logstash-filter-useragent 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -4
- data/README.md +3 -0
- data/lib/logstash/filters/useragent.rb +41 -32
- data/logstash-filter-useragent.gemspec +1 -1
- data/spec/filters/useragent_spec.rb +26 -6
- metadata +21 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b15dbfc5639b8beaf8ab72610de93b6f4639175f
|
4
|
+
data.tar.gz: c9966b10c9b5a543a48c35e8e6bb7d54d4f156db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83f573235d4e17df240c22281705b5755d429e6dc868d943418848f70d087b40723969800d6ac91f5c59b538931f8e930924171a572e9f7b54584580ec1338dd
|
7
|
+
data.tar.gz: 626a212f02ab445506b2caa8a6006bd0098ab493f347e85d3e23b17358ed5ee8bec43b76d77e95e441a1a570e1dbddfa69dcc4dbae3abf47ae5c9d5c2ccabe3d
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
## 2.0.4
|
2
|
+
- Fefactored field references, fixed specs and some cleanups
|
3
|
+
|
1
4
|
## 2.0.0
|
2
|
-
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
5
|
+
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
3
6
|
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
4
7
|
- Dependency on logstash-core update to 2.0
|
5
8
|
|
6
|
-
|
9
|
+
## 2.0.1
|
7
10
|
- Add ability to replace source with target
|
8
|
-
|
9
|
-
|
11
|
+
|
12
|
+
## 1.1.0
|
13
|
+
- Add LRU cache
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
+
[](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Filters/job/logstash-plugin-filter-useragent-unit/)
|
5
|
+
|
3
6
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
4
7
|
|
5
8
|
It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
|
@@ -54,18 +54,18 @@ class LogStash::Filters::UserAgent < LogStash::Filters::Base
|
|
54
54
|
# number of cache misses and waste memory.
|
55
55
|
config :lru_cache_size, :validate => :number, :default => 1000
|
56
56
|
|
57
|
-
public
|
58
57
|
def register
|
59
58
|
require 'user_agent_parser'
|
59
|
+
|
60
60
|
if @regexes.nil?
|
61
61
|
begin
|
62
|
-
@parser = UserAgentParser::Parser.new
|
62
|
+
@parser = UserAgentParser::Parser.new
|
63
63
|
rescue Exception => e
|
64
64
|
begin
|
65
65
|
path = ::File.expand_path('../../../vendor/regexes.yaml', ::File.dirname(__FILE__))
|
66
66
|
@parser = UserAgentParser::Parser.new(:patterns_path => path)
|
67
67
|
rescue => ex
|
68
|
-
raise
|
68
|
+
raise("Failed to cache, due to: #{ex}\n")
|
69
69
|
end
|
70
70
|
end
|
71
71
|
else
|
@@ -74,14 +74,28 @@ class LogStash::Filters::UserAgent < LogStash::Filters::Base
|
|
74
74
|
end
|
75
75
|
|
76
76
|
LOOKUP_CACHE.max_size = @lru_cache_size
|
77
|
-
end #def register
|
78
77
|
|
79
|
-
|
80
|
-
|
81
|
-
|
78
|
+
# make @target in the format [field name] if defined, i.e. surrounded by brakets
|
79
|
+
normalized_target = (@target && @target !~ /^\[[^\[\]]+\]$/) ? "[#{@target}]" : ""
|
80
|
+
|
81
|
+
# predefine prefixed field names
|
82
|
+
@prefixed_name = "#{normalized_target}[#{@prefix}name]"
|
83
|
+
@prefixed_os = "#{normalized_target}[#{@prefix}os]"
|
84
|
+
@prefixed_os_name = "#{normalized_target}[#{@prefix}os_name]"
|
85
|
+
@prefixed_os_major = "#{normalized_target}[#{@prefix}os_major]"
|
86
|
+
@prefixed_os_minor = "#{normalized_target}[#{@prefix}os_minor]"
|
87
|
+
@prefixed_device = "#{normalized_target}[#{@prefix}device]"
|
88
|
+
@prefixed_major = "#{normalized_target}[#{@prefix}major]"
|
89
|
+
@prefixed_minor = "#{normalized_target}[#{@prefix}minor]"
|
90
|
+
@prefixed_patch = "#{normalized_target}[#{@prefix}patch]"
|
91
|
+
@prefixed_build = "#{normalized_target}[#{@prefix}build]"
|
92
|
+
end
|
82
93
|
|
94
|
+
def filter(event)
|
83
95
|
useragent = event[@source]
|
84
|
-
useragent = useragent.first if useragent.is_a?
|
96
|
+
useragent = useragent.first if useragent.is_a?(Array)
|
97
|
+
|
98
|
+
return if useragent.nil? || useragent.empty?
|
85
99
|
|
86
100
|
begin
|
87
101
|
ua_data = lookup_useragent(useragent)
|
@@ -92,19 +106,14 @@ class LogStash::Filters::UserAgent < LogStash::Filters::Base
|
|
92
106
|
|
93
107
|
return unless ua_data
|
94
108
|
|
95
|
-
if @target
|
96
|
-
|
97
|
-
elsif @target == @source
|
98
|
-
target = event[@source] = {}
|
99
|
-
else
|
100
|
-
target = event[@target] ||= {}
|
101
|
-
end
|
102
|
-
|
103
|
-
write_to_target(target, ua_data)
|
109
|
+
event.remove(@source) if @target == @source
|
110
|
+
set_fields(event, ua_data)
|
104
111
|
|
105
112
|
filter_matched(event)
|
106
|
-
end
|
113
|
+
end
|
107
114
|
|
115
|
+
# should be private but need to stay public for specs
|
116
|
+
# TODO: (colin) the related specs should be refactored to not rely on private methods.
|
108
117
|
def lookup_useragent(useragent)
|
109
118
|
return unless useragent
|
110
119
|
|
@@ -117,10 +126,12 @@ class LogStash::Filters::UserAgent < LogStash::Filters::Base
|
|
117
126
|
ua_data
|
118
127
|
end
|
119
128
|
|
120
|
-
|
129
|
+
private
|
130
|
+
|
131
|
+
def set_fields(event, ua_data)
|
121
132
|
# UserAgentParser outputs as US-ASCII.
|
122
133
|
|
123
|
-
|
134
|
+
event[@prefixed_name] = ua_data.name.dup.force_encoding(Encoding::UTF_8)
|
124
135
|
|
125
136
|
#OSX, Andriod and maybe iOS parse correctly, ua-agent parsing for Windows does not provide this level of detail
|
126
137
|
|
@@ -128,25 +139,23 @@ class LogStash::Filters::UserAgent < LogStash::Filters::Base
|
|
128
139
|
# and corrupt the cache. See uap source here for details https://github.com/ua-parser/uap-ruby/tree/master/lib/user_agent_parser
|
129
140
|
if (os = ua_data.os)
|
130
141
|
# The OS is a rich object
|
131
|
-
|
132
|
-
|
142
|
+
event[@prefixed_os] = ua_data.os.to_s.dup.force_encoding(Encoding::UTF_8)
|
143
|
+
event[@prefixed_os_name] = os.name.dup.force_encoding(Encoding::UTF_8) if os.name
|
133
144
|
|
134
145
|
# These are all strings
|
135
146
|
if (os_version = os.version)
|
136
|
-
|
137
|
-
|
147
|
+
event[@prefixed_os_major] = os_version.major.dup.force_encoding(Encoding::UTF_8) if os_version.major
|
148
|
+
event[@prefixed_os_minor] = os_version.minor.dup.force_encoding(Encoding::UTF_8) if os_version.minor
|
138
149
|
end
|
139
150
|
end
|
140
151
|
|
141
|
-
|
152
|
+
event[@prefixed_device] = ua_data.device.to_s.dup.force_encoding(Encoding::UTF_8) if ua_data.device
|
142
153
|
|
143
154
|
if (ua_version = ua_data.version)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
155
|
+
event[@prefixed_major] = ua_version.major.dup.force_encoding(Encoding::UTF_8) if ua_version.major
|
156
|
+
event[@prefixed_minor] = ua_version.minor.dup.force_encoding(Encoding::UTF_8) if ua_version.minor
|
157
|
+
event[@prefixed_patch] = ua_version.patch.dup.force_encoding(Encoding::UTF_8) if ua_version.patch
|
158
|
+
event[@prefixed_build] = ua_version.patch_minor.dup.force_encoding(Encoding::UTF_8) if ua_version.patch_minor
|
148
159
|
end
|
149
160
|
end
|
150
|
-
|
151
|
-
end # class LogStash::Filters::UserAgent
|
152
|
-
|
161
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-filter-useragent'
|
4
|
-
s.version = '2.0.
|
4
|
+
s.version = '2.0.4'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Parse user agent strings into structured data based on BrowserScope data"
|
7
7
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
@@ -41,12 +41,31 @@ describe LogStash::Filters::UserAgent do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
describe "Without user agent" do
|
45
|
+
config <<-CONFIG
|
46
|
+
filter {
|
47
|
+
useragent {
|
48
|
+
source => "message"
|
49
|
+
target => "ua"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
CONFIG
|
53
|
+
|
54
|
+
sample "foo" => "bar" do
|
55
|
+
reject { subject }.include?("ua")
|
56
|
+
end
|
57
|
+
|
58
|
+
sample "" do
|
59
|
+
reject { subject }.include?("ua")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
44
63
|
describe "LRU object identity" do
|
64
|
+
let(:ua_string) { "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" }
|
45
65
|
let(:uafilter) { LogStash::Filters::UserAgent.new("source" => "foo") }
|
46
|
-
let(:ua_data) {
|
47
|
-
|
48
|
-
}
|
49
|
-
subject(:target) { {} }
|
66
|
+
let(:ua_data) { uafilter.lookup_useragent(ua_string) }
|
67
|
+
|
68
|
+
subject(:target) { LogStash::Event.new("foo" => ua_string) }
|
50
69
|
|
51
70
|
before do
|
52
71
|
uafilter.register
|
@@ -54,7 +73,8 @@ describe LogStash::Filters::UserAgent do
|
|
54
73
|
# Stub this out because this UA doesn't have this field
|
55
74
|
allow(ua_data.version).to receive(:patch_minor).and_return("foo")
|
56
75
|
|
57
|
-
|
76
|
+
# expect(event).receive(:lookup_useragent)
|
77
|
+
uafilter.filter(target)
|
58
78
|
end
|
59
79
|
|
60
80
|
{
|
@@ -99,7 +119,7 @@ describe LogStash::Filters::UserAgent do
|
|
99
119
|
CONFIG
|
100
120
|
|
101
121
|
sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
|
102
|
-
insist { subject }.include?("message")
|
122
|
+
insist { subject.to_hash }.include?("message")
|
103
123
|
insist { subject["message"]["name"] } == "Chrome"
|
104
124
|
insist { subject["message"]["os"] } == "Linux"
|
105
125
|
insist { subject["message"]["major"] } == "26"
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-filter-useragent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
|
14
|
+
name: logstash-core
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
15
16
|
requirements:
|
16
17
|
- - '>='
|
17
18
|
- !ruby/object:Gem::Version
|
@@ -19,10 +20,7 @@ dependencies:
|
|
19
20
|
- - <
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 3.0.0
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
type: :runtime
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
26
24
|
requirements:
|
27
25
|
- - '>='
|
28
26
|
- !ruby/object:Gem::Version
|
@@ -30,48 +28,50 @@ dependencies:
|
|
30
28
|
- - <
|
31
29
|
- !ruby/object:Gem::Version
|
32
30
|
version: 3.0.0
|
31
|
+
prerelease: false
|
32
|
+
type: :runtime
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
+
name: user_agent_parser
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.0.0
|
34
40
|
requirement: !ruby/object:Gem::Requirement
|
35
41
|
requirements:
|
36
42
|
- - '>='
|
37
43
|
- !ruby/object:Gem::Version
|
38
44
|
version: 2.0.0
|
39
|
-
name: user_agent_parser
|
40
45
|
prerelease: false
|
41
46
|
type: :runtime
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: lru_redux
|
42
49
|
version_requirements: !ruby/object:Gem::Requirement
|
43
50
|
requirements:
|
44
|
-
- -
|
51
|
+
- - ~>
|
45
52
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
47
|
-
- !ruby/object:Gem::Dependency
|
53
|
+
version: 1.1.0
|
48
54
|
requirement: !ruby/object:Gem::Requirement
|
49
55
|
requirements:
|
50
56
|
- - ~>
|
51
57
|
- !ruby/object:Gem::Version
|
52
58
|
version: 1.1.0
|
53
|
-
name: lru_redux
|
54
59
|
prerelease: false
|
55
60
|
type: :runtime
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: logstash-devutils
|
56
63
|
version_requirements: !ruby/object:Gem::Requirement
|
57
64
|
requirements:
|
58
|
-
- -
|
65
|
+
- - '>='
|
59
66
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
61
|
-
- !ruby/object:Gem::Dependency
|
67
|
+
version: '0'
|
62
68
|
requirement: !ruby/object:Gem::Requirement
|
63
69
|
requirements:
|
64
70
|
- - '>='
|
65
71
|
- !ruby/object:Gem::Version
|
66
72
|
version: '0'
|
67
|
-
name: logstash-devutils
|
68
73
|
prerelease: false
|
69
74
|
type: :development
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - '>='
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '0'
|
75
75
|
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
76
76
|
email: info@elastic.co
|
77
77
|
executables: []
|