fluent-plugin-geoip 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +42 -22
- data/fluent-plugin-geoip.gemspec +1 -1
- data/lib/fluent/plugin/out_geoip.rb +23 -4
- data/test/plugin/test_out_geoip.rb +32 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -24,7 +24,7 @@ $ sudo apt-get install libgeoip-dev
|
|
24
24
|
|
25
25
|
## Installation
|
26
26
|
|
27
|
-
install with `gem` or
|
27
|
+
install with `gem` or td-agent provided command as:
|
28
28
|
|
29
29
|
```bash
|
30
30
|
# for fluentd
|
@@ -32,6 +32,9 @@ $ gem install fluent-plugin-geoip
|
|
32
32
|
|
33
33
|
# for td-agent
|
34
34
|
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-geoip
|
35
|
+
|
36
|
+
# for td-agent2
|
37
|
+
$ sudo td-agent-gem install fluent-plugin-geoip
|
35
38
|
```
|
36
39
|
|
37
40
|
## Usage
|
@@ -45,20 +48,20 @@ $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-geoip
|
|
45
48
|
geoip_lookup_key host
|
46
49
|
|
47
50
|
# Specify optional geoip database (using bundled GeoLiteCity databse by default)
|
48
|
-
geoip_database
|
51
|
+
geoip_database "/path/to/your/GeoIPCity.dat"
|
49
52
|
|
50
53
|
# Set adding field with placeholder (more than one settings are required.)
|
51
54
|
<record>
|
52
|
-
city ${city[
|
53
|
-
latitude ${latitude[
|
54
|
-
longitude ${longitude[
|
55
|
-
country_code3 ${country_code3[
|
56
|
-
country_code2 ${country_code2[
|
57
|
-
country ${country_code[
|
58
|
-
country_name ${country_name[
|
59
|
-
dma ${dma_code[
|
60
|
-
area ${area_code[
|
61
|
-
region ${region[
|
55
|
+
city ${city["host"]}
|
56
|
+
latitude ${latitude["host"]}
|
57
|
+
longitude ${longitude["host"]}
|
58
|
+
country_code3 ${country_code3["host"]}
|
59
|
+
country_code2 ${country_code2["host"]}
|
60
|
+
country ${country_code["host"]}
|
61
|
+
country_name ${country_name["host"]}
|
62
|
+
dma ${dma_code["host"]}
|
63
|
+
area ${area_code["host"]}
|
64
|
+
region ${region["host"]}
|
62
65
|
</record>
|
63
66
|
|
64
67
|
# Settings for tag
|
@@ -80,8 +83,8 @@ $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-geoip
|
|
80
83
|
type geoip
|
81
84
|
geoip_lookup_key user1_host, user2_host
|
82
85
|
<record>
|
83
|
-
user1_city ${city[
|
84
|
-
user2_city ${city[
|
86
|
+
user1_city ${city["user1_host"]}
|
87
|
+
user2_city ${city["user2_host"]}
|
85
88
|
</record>
|
86
89
|
remove_tag_prefix access.
|
87
90
|
tag geoip.${tag}
|
@@ -90,24 +93,41 @@ $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-geoip
|
|
90
93
|
|
91
94
|
#### Advanced config samples
|
92
95
|
|
93
|
-
It is a sample to get friendly geo point recdords for elasticsearch with Yajl (JSON) parser
|
96
|
+
It is a sample to get friendly geo point recdords for elasticsearch with Yajl (JSON) parser.<br />
|
97
|
+
|
94
98
|
|
95
99
|
```
|
96
|
-
<match
|
100
|
+
<match access.apache>
|
97
101
|
type geoip
|
98
102
|
geoip_lookup_key host
|
99
103
|
<record>
|
100
104
|
# lat lon as properties
|
101
105
|
# ex. {"lat" => 37.4192008972168, "lon" => -122.05740356445312 }
|
102
|
-
location_properties { "lat"
|
106
|
+
location_properties { "lat" : ${latitude["host"]}, "lon" : ${longitude["host"]} }
|
103
107
|
|
104
108
|
# lat lon as string
|
105
109
|
# ex. "37.4192008972168,-122.05740356445312"
|
106
|
-
location_string ${latitude[
|
110
|
+
location_string ${latitude["host"]},${longitude["host"]}
|
107
111
|
|
108
112
|
# lat lon as array (it is useful for Kibana's bettermap.)
|
109
113
|
# ex. [-122.05740356445312, 37.4192008972168]
|
110
|
-
location_array [${longitude[
|
114
|
+
location_array [${longitude["host"]},${latitude["host"]}]
|
115
|
+
</record>
|
116
|
+
remove_tag_prefix access.
|
117
|
+
tag geoip.${tag}
|
118
|
+
</match>
|
119
|
+
```
|
120
|
+
|
121
|
+
On the case of using td-agent2 (v1-config), it have to quote `{ ... }` or `[ ... ]` block with quotation like below.
|
122
|
+
|
123
|
+
```
|
124
|
+
<match access.apache>
|
125
|
+
type geoip
|
126
|
+
geoip_lookup_key host
|
127
|
+
<record>
|
128
|
+
location_properties '{ "lat" : ${latitude["host"]}, "lon" : ${longitude["host"]} }'
|
129
|
+
location_string ${latitude["host"]},${longitude["host"]}
|
130
|
+
location_array '[${longitude["host"]},${latitude["host"]}]'
|
111
131
|
</record>
|
112
132
|
remove_tag_prefix access.
|
113
133
|
tag geoip.${tag}
|
@@ -132,9 +152,9 @@ It is a sample to get friendly geo point recdords for elasticsearch with Yajl (J
|
|
132
152
|
type geoip
|
133
153
|
geoip_lookup_key host
|
134
154
|
<record>
|
135
|
-
city ${city[
|
136
|
-
lat ${latitude[
|
137
|
-
lon ${longitude[
|
155
|
+
city ${city["host"]}
|
156
|
+
lat ${latitude["host"]}
|
157
|
+
lon ${longitude["host"]}
|
138
158
|
</record>
|
139
159
|
remove_tag_prefix test.
|
140
160
|
tag debug.${tag}
|
data/fluent-plugin-geoip.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-geoip"
|
7
|
-
spec.version = "0.3.
|
7
|
+
spec.version = "0.3.1"
|
8
8
|
spec.authors = ["Kentaro Yoshida"]
|
9
9
|
spec.email = ["y.ken.studio@gmail.com"]
|
10
10
|
spec.summary = %q{Fluentd Output plugin to add information about geographical location of IP addresses with Maxmind GeoIP databases.}
|
@@ -3,8 +3,7 @@ require 'fluent/mixin/rewrite_tag_name'
|
|
3
3
|
class Fluent::GeoipOutput < Fluent::BufferedOutput
|
4
4
|
Fluent::Plugin.register_output('geoip', self)
|
5
5
|
|
6
|
-
|
7
|
-
REGEXP_PLACEHOLDER_SINGLE = /^\$\{(?<geoip_key>-?[^\[]+)\['(?<record_key>-?[^']+)'\]\}$/
|
6
|
+
REGEXP_PLACEHOLDER_SINGLE = /^\$\{(?<geoip_key>-?[^\[]+)\[['"](?<record_key>-?[^'"]+)['"]\]\}$/
|
8
7
|
REGEXP_PLACEHOLDER_SCAN = /(\$\{[^\}]+?\})/
|
9
8
|
GEOIP_KEYS = %w(city latitude longitude country_code3 country_code2 country_code country_name dma_code area_code region)
|
10
9
|
|
@@ -60,6 +59,7 @@ class Fluent::GeoipOutput < Fluent::BufferedOutput
|
|
60
59
|
conf.elements.select { |element| element.name == 'record' }.each { |element|
|
61
60
|
element.each_pair { |k, v|
|
62
61
|
element.has_key?(k) # to suppress unread configuration warning
|
62
|
+
v = v[1..v.size-2] if quoted_json?(v)
|
63
63
|
@map[k] = v
|
64
64
|
validate_json = Proc.new {
|
65
65
|
begin
|
@@ -69,7 +69,7 @@ class Fluent::GeoipOutput < Fluent::BufferedOutput
|
|
69
69
|
raise Fluent::ConfigError, "geoip: failed to parse '#{v}' as json."
|
70
70
|
end
|
71
71
|
}
|
72
|
-
validate_json.call if v.
|
72
|
+
validate_json.call if json?(v.tr('\'"\\', ''))
|
73
73
|
}
|
74
74
|
}
|
75
75
|
@placeholder_keys = @map.values.join.scan(REGEXP_PLACEHOLDER_SCAN).map{ |placeholder| placeholder[0] }.uniq
|
@@ -105,12 +105,31 @@ class Fluent::GeoipOutput < Fluent::BufferedOutput
|
|
105
105
|
end
|
106
106
|
|
107
107
|
private
|
108
|
+
|
109
|
+
def json?(text)
|
110
|
+
text.match(/^\[.+\]$/) || text.match(/^\{.+\}$/) || text.match(/^[\d\.\-]+$/)
|
111
|
+
end
|
112
|
+
|
113
|
+
def quoted_json?(text)
|
114
|
+
# to improbe compatibility with fluentd v1-config
|
115
|
+
trim_quote = text[1..text.size-2]
|
116
|
+
text.match(/(^'.+'$|^".+"$)/) && (json_array_block?(trim_quote) || json_hash_block?(trim_quote))
|
117
|
+
end
|
118
|
+
|
119
|
+
def json_array_block?(text)
|
120
|
+
text.match(/^\[[^\{]*?\{.+\}[^\}]*?\]$/)
|
121
|
+
end
|
122
|
+
|
123
|
+
def json_hash_block?(text)
|
124
|
+
text.match(/^\{[^\{]*?\{.+\}[^\}]*?\}$/)
|
125
|
+
end
|
126
|
+
|
108
127
|
def add_geoip_field(record)
|
109
128
|
placeholder = create_placeholder(geolocate(get_address(record)))
|
110
129
|
@map.each do |record_key, value|
|
111
130
|
if value.match(REGEXP_PLACEHOLDER_SINGLE)
|
112
131
|
rewrited = placeholder[value]
|
113
|
-
elsif value
|
132
|
+
elsif json?(value)
|
114
133
|
rewrited = value.gsub(REGEXP_PLACEHOLDER_SCAN) {|match|
|
115
134
|
Yajl::Encoder.encode(placeholder[match])
|
116
135
|
}
|
@@ -326,4 +326,36 @@ class GeoipOutputTest < Test::Unit::TestCase
|
|
326
326
|
assert_equal nil, emits[1][2]['to_country']
|
327
327
|
assert_equal [nil, nil], emits[1][2]['string_array']
|
328
328
|
end
|
329
|
+
|
330
|
+
|
331
|
+
|
332
|
+
def test_emit_v1_parser
|
333
|
+
d1 = create_driver(%[
|
334
|
+
geoip_lookup_key host
|
335
|
+
<record>
|
336
|
+
location_properties '{ "lat": ${latitude["host"]}, "lon": ${longitude["host"]} }'
|
337
|
+
location_string ${latitude['host']},${longitude['host']}
|
338
|
+
location_string2 ${latitude["host"]},${longitude["host"]}
|
339
|
+
location_array "[${longitude['host']},${latitude['host']}]"
|
340
|
+
location_array2 '[${longitude["host"]},${latitude["host"]}]'
|
341
|
+
peculiar_pattern [GEOIP] message => {"lat":${latitude['host']}, "lon":${longitude['host']}}
|
342
|
+
</record>
|
343
|
+
remove_tag_prefix input.
|
344
|
+
tag geoip.${tag}
|
345
|
+
], 'input.access')
|
346
|
+
d1.run do
|
347
|
+
d1.emit({'host' => '66.102.3.80', 'message' => 'valid ip'})
|
348
|
+
end
|
349
|
+
emits = d1.emits
|
350
|
+
assert_equal 1, emits.length
|
351
|
+
assert_equal 'geoip.access', emits[0][0] # tag
|
352
|
+
location_properties = { "lat" => 37.4192008972168, "lon"=> -122.05740356445312 }
|
353
|
+
assert_equal location_properties, emits[0][2]['location_properties']
|
354
|
+
assert_equal '37.4192008972168,-122.05740356445312', emits[0][2]['location_string']
|
355
|
+
assert_equal '37.4192008972168,-122.05740356445312', emits[0][2]['location_string2']
|
356
|
+
assert_equal [-122.05740356445312, 37.4192008972168], emits[0][2]['location_array']
|
357
|
+
assert_equal [-122.05740356445312, 37.4192008972168], emits[0][2]['location_array2']
|
358
|
+
assert_equal '[GEOIP] message => {"lat":37.4192008972168, "lon":-122.05740356445312}', emits[0][2]['peculiar_pattern']
|
359
|
+
end
|
329
360
|
end
|
361
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-11-
|
12
|
+
date: 2014-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|