fluent-plugin-geoip 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +213 -143
- data/fluent-plugin-geoip.gemspec +1 -1
- data/lib/fluent/plugin/filter_geoip.rb +11 -7
- data/lib/fluent/plugin/geoip.rb +10 -3
- data/lib/fluent/plugin/out_geoip.rb +9 -5
- data/test/plugin/test_filter_geoip.rb +88 -0
- data/test/plugin/test_out_geoip.rb +3 -3
- data/utils/dump.rb +27 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6f265530c6153294e8c0e5c35176a8e51f926708757622feee23177dbf388252
|
4
|
+
data.tar.gz: fd1b525e0e78306a8d87356531ddd5106de541b60e0521cad6e5cbeca15a84ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32c7fb52de7c2a970fffe128e1c86cd327b8615e6e124d3019e50c74e4808674179de9a6761a4929375c8f159866364fe2e93e1042311e310bf52639b24058ca
|
7
|
+
data.tar.gz: d7f3f9f3cb1d7be3bf294bdc1b000c74d379e3454f64b188ab05a2804fc1d3379c775c758e2dab37e9f0477980f9466ba239542b868d7eaaf3b9a92ab50dcee6
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# fluent-plugin-geoip [![Build Status](https://travis-ci.org/y-ken/fluent-plugin-geoip.png?branch=master)](https://travis-ci.org/y-ken/fluent-plugin-geoip)
|
2
2
|
|
3
|
-
Fluentd Output plugin to add information about geographical location of IP addresses with Maxmind GeoIP databases.
|
3
|
+
Fluentd Filter/Output plugin to add information about geographical location of IP addresses with Maxmind GeoIP databases.
|
4
4
|
|
5
|
-
fluent-plugin-geoip has bundled cost-free [GeoLite City database](http://dev.maxmind.com/geoip/legacy/geolite/) by default.<br />
|
5
|
+
fluent-plugin-geoip has bundled cost-free [GeoLite2 Free Downloadable Databases](https://dev.maxmind.com/geoip/geoip2/geolite2/) and [GeoLite City database](http://dev.maxmind.com/geoip/legacy/geolite/) by default.<br />
|
6
6
|
Also you can use purchased [GeoIP City database](http://www.maxmind.com/en/city) ([lang:ja](http://www.maxmind.com/ja/city)) which costs starting from $50.
|
7
7
|
|
8
8
|
The accuracy details for GeoLite City (free) and GeoIP City (purchased) has described at the page below.
|
@@ -22,7 +22,7 @@ If you want to use this plugin with Fluentd v0.12.x or earlier use 0.8.x.
|
|
22
22
|
### Compatibility notice
|
23
23
|
|
24
24
|
We've used Fluentd v1 API in this plugin since 1.0.0.
|
25
|
-
So we have dropped some features.
|
25
|
+
So we have dropped some features from GeoipOutput.
|
26
26
|
|
27
27
|
See also [official document](http://docs.fluentd.org/v1.0/articles/plugin-update-from-v12)
|
28
28
|
|
@@ -107,10 +107,12 @@ $ sudo td-agent-gem install fluent-plugin-geoip
|
|
107
107
|
|
108
108
|
## Usage
|
109
109
|
|
110
|
-
### For
|
110
|
+
### For GeoipFilter
|
111
|
+
|
112
|
+
Note that filter version of geoip plugin does not have handling tag feature.
|
111
113
|
|
112
114
|
```xml
|
113
|
-
<
|
115
|
+
<filter access.apache>
|
114
116
|
@type geoip
|
115
117
|
|
116
118
|
# Specify one or more geoip lookup field which has ip address (default: host)
|
@@ -118,108 +120,89 @@ $ sudo td-agent-gem install fluent-plugin-geoip
|
|
118
120
|
geoip_lookup_key host
|
119
121
|
|
120
122
|
# Specify optional geoip database (using bundled GeoLiteCity databse by default)
|
121
|
-
geoip_database "/path/to/your/GeoIPCity.dat"
|
123
|
+
# geoip_database "/path/to/your/GeoIPCity.dat"
|
122
124
|
# Specify optional geoip2 database
|
123
|
-
# geoip2_database "/path/to/your/GeoLite2-City.mmdb"
|
124
|
-
# Specify backend library (geoip, geoip2_compat
|
125
|
-
backend_library
|
125
|
+
# geoip2_database "/path/to/your/GeoLite2-City.mmdb" (using bundled GeoLite2-City.mmdb by default)
|
126
|
+
# Specify backend library (geoip2_c, geoip, geoip2_compat)
|
127
|
+
backend_library geoip2_c
|
126
128
|
|
127
129
|
# Set adding field with placeholder (more than one settings are required.)
|
128
130
|
<record>
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
country ${
|
133
|
-
country_name ${
|
134
|
-
|
135
|
-
area ${area_code["host"]}
|
136
|
-
region ${region["host"]}
|
137
|
-
city ${city["host"]}
|
131
|
+
city ${city.names.en["host"]}
|
132
|
+
latitude ${location.latitude["host"]}
|
133
|
+
longitude ${location.longitude["host"]}
|
134
|
+
country ${country.iso_code["host"]}
|
135
|
+
country_name ${country.names.en["host"]}
|
136
|
+
postal_code ${postal.code["host"]}
|
138
137
|
</record>
|
139
138
|
|
140
|
-
# Settings for tag
|
141
|
-
tag geoip.${tag[1]}
|
142
|
-
|
143
139
|
# To avoid get stacktrace error with `[null, null]` array for elasticsearch.
|
144
140
|
skip_adding_null_record true
|
145
141
|
|
146
|
-
# Set log_level
|
147
|
-
log_level info
|
148
|
-
|
149
|
-
<buffer tag>
|
150
|
-
# Set buffering time (default: 0s)
|
151
|
-
flush_interval 1s
|
152
|
-
</buffer>
|
153
|
-
</match>
|
142
|
+
# Set @log_level (default: warn)
|
143
|
+
@log_level info
|
144
|
+
</filter>
|
154
145
|
```
|
155
146
|
|
156
147
|
#### Tips: how to geolocate multiple key
|
157
148
|
|
158
149
|
```xml
|
159
|
-
<
|
150
|
+
<filter access.apache>
|
160
151
|
@type geoip
|
161
152
|
geoip_lookup_key user1_host, user2_host
|
162
153
|
<record>
|
163
|
-
user1_city ${city["user1_host"]}
|
164
|
-
user2_city ${city["user2_host"]}
|
154
|
+
user1_city ${city.names.en["user1_host"]}
|
155
|
+
user2_city ${city.names.en["user2_host"]}
|
165
156
|
</record>
|
166
|
-
|
167
|
-
</match>
|
157
|
+
</filter>
|
168
158
|
```
|
169
159
|
|
170
160
|
#### Advanced config samples
|
171
161
|
|
172
162
|
It is a sample to get friendly geo point recdords for elasticsearch with Yajl (JSON) parser.<br />
|
173
163
|
|
174
|
-
**Notice** v0 config will be deprecated in the future.
|
175
|
-
|
176
164
|
```
|
177
|
-
<
|
165
|
+
<filter access.apache>
|
178
166
|
@type geoip
|
179
167
|
geoip_lookup_key host
|
180
168
|
<record>
|
181
169
|
# lat lon as properties
|
182
170
|
# ex. {"lat" => 37.4192008972168, "lon" => -122.05740356445312 }
|
183
|
-
location_properties '{ "lat" : ${latitude["host"]}, "lon" : ${longitude["host"]} }'
|
171
|
+
location_properties '{ "lat" : ${location.latitude["host"]}, "lon" : ${location.longitude["host"]} }'
|
184
172
|
|
185
173
|
# lat lon as string
|
186
174
|
# ex. "37.4192008972168,-122.05740356445312"
|
187
|
-
location_string ${latitude["host"]},${longitude["host"]}
|
175
|
+
location_string ${location.latitude["host"]},${location.longitude["host"]}
|
188
176
|
|
189
177
|
# GeoJSON (lat lon as array) is useful for Kibana's bettermap.
|
190
178
|
# ex. [-122.05740356445312, 37.4192008972168]
|
191
|
-
location_array '[${longitude["host"]},${latitude["host"]}]'
|
179
|
+
location_array '[${location.longitude["host"]},${location.latitude["host"]}]'
|
192
180
|
</record>
|
193
|
-
tag geoip.${tag[1]}
|
194
181
|
|
195
182
|
# To avoid get stacktrace error with `[null, null]` array for elasticsearch.
|
196
183
|
skip_adding_null_record true
|
197
|
-
</
|
184
|
+
</filter>
|
198
185
|
```
|
199
186
|
|
200
187
|
On the case of using td-agent3 (v1-config), it have to quote `{ ... }` or `[ ... ]` block with quotation like below.
|
201
188
|
|
202
189
|
```
|
203
|
-
<
|
190
|
+
<filter access.apache>
|
204
191
|
@type geoip
|
205
192
|
geoip_lookup_key host
|
206
193
|
<record>
|
207
|
-
location_properties '{ "lat" : ${latitude["host"]}, "lon" : ${longitude["host"]} }'
|
208
|
-
location_string ${latitude["host"]},${longitude["host"]}
|
209
|
-
location_array '[${longitude["host"]},${latitude["host"]}]'
|
194
|
+
location_properties '{ "lat" : ${location.latitude["host"]}, "lon" : ${location.longitude["host"]} }'
|
195
|
+
location_string ${location.latitude["host"]},${location.longitude["host"]}
|
196
|
+
location_array '[${location.longitude["host"]},${location.latitude["host"]}]'
|
210
197
|
</record>
|
211
|
-
remove_tag_prefix access.
|
212
|
-
tag geoip.${tag}
|
213
198
|
skip_adding_null_record true
|
214
|
-
</
|
199
|
+
</filter>
|
215
200
|
```
|
216
201
|
|
217
|
-
### For
|
218
|
-
|
219
|
-
Note that filter version of geoip plugin does not have handling tag feature.
|
202
|
+
### For GeoipOutput
|
220
203
|
|
221
204
|
```xml
|
222
|
-
<
|
205
|
+
<match access.apache>
|
223
206
|
@type geoip
|
224
207
|
|
225
208
|
# Specify one or more geoip lookup field which has ip address (default: host)
|
@@ -235,28 +218,35 @@ Note that filter version of geoip plugin does not have handling tag feature.
|
|
235
218
|
|
236
219
|
# Set adding field with placeholder (more than one settings are required.)
|
237
220
|
<record>
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
region ${region["host"]}
|
221
|
+
latitude ${location.latitude["host"]}
|
222
|
+
longitude ${location.longitude["host"]}
|
223
|
+
country ${country.iso_code["host"]}
|
224
|
+
country_name ${country.names.en["host"]}
|
225
|
+
postal_code ${postal.code["host"]}
|
226
|
+
region ${subdivisions.0.iso_code["host"]}
|
227
|
+
region_name ${subdivisions.0.names.en["host"]}
|
228
|
+
city ${city.names.en["host"]}
|
247
229
|
</record>
|
248
230
|
|
231
|
+
# Settings for tag
|
232
|
+
tag geoip.${tag[1]}
|
233
|
+
|
249
234
|
# To avoid get stacktrace error with `[null, null]` array for elasticsearch.
|
250
235
|
skip_adding_null_record true
|
251
236
|
|
252
|
-
# Set log_level
|
253
|
-
log_level info
|
254
|
-
|
237
|
+
# Set @log_level (default: warn)
|
238
|
+
@log_level info
|
239
|
+
|
240
|
+
<buffer tag>
|
241
|
+
# Set buffering time (default: 0s)
|
242
|
+
flush_interval 1s
|
243
|
+
</buffer>
|
244
|
+
</match>
|
255
245
|
```
|
256
246
|
|
257
247
|
## Tutorial
|
258
248
|
|
259
|
-
### For
|
249
|
+
### For GeoipFilter
|
260
250
|
|
261
251
|
#### configuration
|
262
252
|
|
@@ -265,24 +255,17 @@ Note that filter version of geoip plugin does not have handling tag feature.
|
|
265
255
|
@type forward
|
266
256
|
</source>
|
267
257
|
|
268
|
-
<
|
269
|
-
@type
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
lat ${latitude["host"]}
|
278
|
-
lon ${longitude["host"]}
|
279
|
-
country ${country_code["host"]}
|
280
|
-
</record>
|
281
|
-
tag debug.${tag[1]}
|
282
|
-
</store>
|
283
|
-
</match>
|
258
|
+
<filter test.geoip>
|
259
|
+
@type geoip
|
260
|
+
geoip_lookup_key host
|
261
|
+
<record>
|
262
|
+
city ${city.names.en["host"]}
|
263
|
+
lat ${location.latitude["host"]}
|
264
|
+
lon ${location.longitude["host"]}
|
265
|
+
</record>
|
266
|
+
</filter>
|
284
267
|
|
285
|
-
<match
|
268
|
+
<match test.**>
|
286
269
|
@type stdout
|
287
270
|
</match>
|
288
271
|
```
|
@@ -295,14 +278,18 @@ $ echo '{"host":"66.102.9.80","message":"test"}' | fluent-cat test.geoip
|
|
295
278
|
|
296
279
|
# check the result at stdout
|
297
280
|
$ tail /var/log/td-agent/td-agent.log
|
298
|
-
|
299
|
-
2013-08-04 16:21:32 +0900 debug.geoip: {"host":"66.102.9.80","message":"test","lat":37.4192008972168,"lon":-122.05740356445312,"country":"US"}
|
281
|
+
2016-02-01 12:04:37 +0900 test.geoip: {"host":"66.102.9.80","message":"test","city":"Mountain View","lat":37.4192008972168,"lon":-122.05740356445312}
|
300
282
|
```
|
301
283
|
|
302
|
-
|
303
|
-
http://dev.maxmind.com/geoip/legacy/csv/
|
284
|
+
You can check geoip data format using [utils/dump.rb](https://github.com/okkez/fluent-plugin-geoip/utils/dump.rb).
|
304
285
|
|
305
|
-
|
286
|
+
```
|
287
|
+
$ bundle exec ruby urils/dump.rb geoip2 66.102.3.80
|
288
|
+
$ bundle exec ruby urils/dump.rb geoip2_compat 66.102.3.80
|
289
|
+
$ bundle exec ruby urils/dump.rb geoip 66.102.3.80
|
290
|
+
```
|
291
|
+
|
292
|
+
### For GeoipOutput
|
306
293
|
|
307
294
|
#### configuration
|
308
295
|
|
@@ -311,17 +298,24 @@ http://dev.maxmind.com/geoip/legacy/csv/
|
|
311
298
|
@type forward
|
312
299
|
</source>
|
313
300
|
|
314
|
-
<
|
315
|
-
@type
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
301
|
+
<match test.geoip>
|
302
|
+
@type copy
|
303
|
+
<store>
|
304
|
+
@type stdout
|
305
|
+
</store>
|
306
|
+
<store>
|
307
|
+
@type geoip
|
308
|
+
geoip_lookup_key host
|
309
|
+
<record>
|
310
|
+
lat ${location.latitude["host"]}
|
311
|
+
lon ${location.longitude["host"]}
|
312
|
+
country ${country.iso_code["host"]}
|
313
|
+
</record>
|
314
|
+
tag debug.${tag[1]}
|
315
|
+
</store>
|
316
|
+
</match>
|
323
317
|
|
324
|
-
<match
|
318
|
+
<match debug.**>
|
325
319
|
@type stdout
|
326
320
|
</match>
|
327
321
|
```
|
@@ -334,37 +328,19 @@ $ echo '{"host":"66.102.9.80","message":"test"}' | fluent-cat test.geoip
|
|
334
328
|
|
335
329
|
# check the result at stdout
|
336
330
|
$ tail /var/log/td-agent/td-agent.log
|
337
|
-
|
331
|
+
2013-08-04 16:21:32 +0900 test.geoip: {"host":"66.102.9.80","message":"test"}
|
332
|
+
2013-08-04 16:21:32 +0900 debug.geoip: {"host":"66.102.9.80","message":"test","lat":37.4192008972168,"lon":-122.05740356445312,"country":"US"}
|
338
333
|
```
|
339
334
|
|
340
|
-
|
341
|
-
http://dev.maxmind.com/geoip/legacy/csv/
|
342
|
-
|
343
|
-
## Placeholders
|
344
|
-
|
345
|
-
### GeoIP legacy
|
346
|
-
|
347
|
-
Provides these placeholders for adding field of geolocate results.<br />
|
348
|
-
For more example of geolocating, you can try these websites like [Geo IP Address View](http://www.geoipview.com/) or [View my IP information](http://www.geoiptool.com/en/).
|
349
|
-
|
350
|
-
| placeholder attributes | output example | type | note |
|
351
|
-
|--------------------------------|-------------------|--------------|------|
|
352
|
-
| ${city[lookup_field]} | "Ithaca" | varchar(255) | - |
|
353
|
-
| ${latitude[lookup_field]} | 42.4277992248535 | decimal | - |
|
354
|
-
| ${longitude[lookup_field]} | -76.4981994628906 | decimal | - |
|
355
|
-
| ${country_code3[lookup_field]} | "USA" | varchar(3) | - |
|
356
|
-
| ${country_code[lookup_field]} | "US" | varchar(2) | A two-character ISO 3166-1 country code |
|
357
|
-
| ${country_name[lookup_field]} | "United States" | varchar(50) | - |
|
358
|
-
| ${dma_code[lookup_field]} | 555 | unsigned int | **only for US** |
|
359
|
-
| ${area_code[lookup_field]} | 607 | char(3) | **only for US** |
|
360
|
-
| ${region[lookup_field]} | "NY" | char(2) | A two character ISO-3166-2 or FIPS 10-4 code |
|
361
|
-
|
362
|
-
Further more specification available at http://dev.maxmind.com/geoip/legacy/csv/#GeoIP_City_Edition_CSV_Database_Fields
|
335
|
+
You can check geoip data format using [utils/dump.rb](https://github.com/okkez/fluent-plugin-geoip/utils/dump.rb).
|
363
336
|
|
364
|
-
|
337
|
+
```
|
338
|
+
$ bundle exec ruby urils/dump.rb geoip2 66.102.3.80
|
339
|
+
$ bundle exec ruby urils/dump.rb geoip2_compat 66.102.3.80
|
340
|
+
$ bundle exec ruby urils/dump.rb geoip 66.102.3.80
|
341
|
+
```
|
365
342
|
|
366
|
-
|
367
|
-
* `geoip_database`: path to your GeoLiteCity.dat
|
343
|
+
## Placeholders
|
368
344
|
|
369
345
|
### GeoIP2
|
370
346
|
|
@@ -405,43 +381,139 @@ Related configurations:
|
|
405
381
|
* `backend_library`: `geoip2_compat` or `geoip2_c`
|
406
382
|
* `geoip2_database`: path to your GeoLite2-City.mmdb
|
407
383
|
|
384
|
+
### GeoIP legacy
|
385
|
+
|
386
|
+
Provides these placeholders for adding field of geolocate results.<br />
|
387
|
+
For more example of geolocating, you can try these websites like [Geo IP Address View](http://www.geoipview.com/) or [View my IP information](http://www.geoiptool.com/en/).
|
388
|
+
|
389
|
+
| placeholder attributes | output example | type | note |
|
390
|
+
|--------------------------------|-------------------|--------------|------|
|
391
|
+
| ${city[lookup_field]} | "Ithaca" | varchar(255) | - |
|
392
|
+
| ${latitude[lookup_field]} | 42.4277992248535 | decimal | - |
|
393
|
+
| ${longitude[lookup_field]} | -76.4981994628906 | decimal | - |
|
394
|
+
| ${country_code3[lookup_field]} | "USA" | varchar(3) | - |
|
395
|
+
| ${country_code[lookup_field]} | "US" | varchar(2) | A two-character ISO 3166-1 country code |
|
396
|
+
| ${country_name[lookup_field]} | "United States" | varchar(50) | - |
|
397
|
+
| ${dma_code[lookup_field]} | 555 | unsigned int | **only for US** |
|
398
|
+
| ${area_code[lookup_field]} | 607 | char(3) | **only for US** |
|
399
|
+
| ${region[lookup_field]} | "NY" | char(2) | A two character ISO-3166-2 or FIPS 10-4 code |
|
400
|
+
|
401
|
+
Further more specification available at http://dev.maxmind.com/geoip/legacy/csv/#GeoIP_City_Edition_CSV_Database_Fields
|
402
|
+
|
403
|
+
Related configurations:
|
404
|
+
|
405
|
+
* `backend_library`: `geoip` (default)
|
406
|
+
* `geoip_database`: path to your GeoLiteCity.dat
|
407
|
+
|
408
408
|
## Parameters
|
409
409
|
|
410
|
-
###
|
410
|
+
### GeoipFilter
|
411
|
+
|
412
|
+
Note that filter version of `geoip` plugin does not have handling `tag` feature.
|
413
|
+
|
414
|
+
#### Plugin helpers
|
415
|
+
|
416
|
+
* [compat_parameters](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-compat_parameters)
|
417
|
+
* [inject](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-inject)
|
418
|
+
|
419
|
+
See also [Filter Plugin Overview](https://docs.fluentd.org/v1.0/articles/filter-plugin-overview)
|
420
|
+
|
421
|
+
#### Supported sections
|
422
|
+
|
423
|
+
* [Inject section configurations](https://docs.fluentd.org/v1.0/articles/inject-section)
|
424
|
+
|
425
|
+
#### Parameters
|
426
|
+
|
427
|
+
[Plugin Common Paramteters](https://docs.fluentd.org/v1.0/articles/plugin-common-parameters)
|
428
|
+
|
429
|
+
**geoip_database** (string) (optional)
|
430
|
+
|
431
|
+
* Default value: bundled database `GeoLiteCity.dat`
|
432
|
+
|
433
|
+
Path to GeoIP database file.
|
434
|
+
|
435
|
+
**geoip2_database** (string) (optional)
|
436
|
+
|
437
|
+
* Default value: bundled database `GeoLite2-City.mmdb`.
|
438
|
+
|
439
|
+
Path to GeoIP2 database file.
|
440
|
+
|
441
|
+
**geoip_lookup_key** (string) (optional)
|
442
|
+
|
443
|
+
* Default value: `host`.
|
411
444
|
|
412
|
-
|
413
|
-
* `tag_key`
|
445
|
+
Specify one or more geoip lookup field which has IP address.
|
414
446
|
|
415
|
-
|
416
|
-
Further details are written at http://docs.fluentd.org/articles/in_exec
|
447
|
+
**skip_adding_null_record** (bool) (optional)
|
417
448
|
|
418
|
-
*
|
449
|
+
* Default value: `nil`
|
419
450
|
|
420
451
|
Skip adding geoip fields when this valaues to `true`.
|
421
452
|
On the case of getting nothing of GeoIP info (such as local IP), it will output the original record without changing anything.
|
422
453
|
|
423
|
-
|
454
|
+
**backend_library** (enum) (optional)
|
424
455
|
|
425
|
-
|
456
|
+
* Available values: `geoip`, `geoip2_compat`, `geoip2_c`
|
457
|
+
* Default value: `geoip2_c`.
|
426
458
|
|
427
|
-
|
459
|
+
Set backend library.
|
428
460
|
|
429
|
-
|
461
|
+
### GeoipOutput
|
430
462
|
|
431
|
-
|
463
|
+
#### Plugin helpers
|
432
464
|
|
433
|
-
|
465
|
+
* [event_emitter](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-event_emitter)
|
466
|
+
* [compat_parameters](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-compat_parameters)
|
467
|
+
* [inject](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-inject)
|
468
|
+
|
469
|
+
See also [Output Plugin Overview](https://docs.fluentd.org/v1.0/articles/output-plugin-overview)
|
470
|
+
|
471
|
+
#### Sections
|
472
|
+
|
473
|
+
* [Inject section configurations](https://docs.fluentd.org/v1.0/articles/inject-section)
|
474
|
+
* [Buffer section configurations](https://docs.fluentd.org/v1.0/articles/buffer-section)
|
475
|
+
|
476
|
+
#### Parameters
|
477
|
+
|
478
|
+
[Plugin Common Paramteters](https://docs.fluentd.org/v1.0/articles/plugin-common-parameters)
|
479
|
+
|
480
|
+
**geoip_database** (string) (optional)
|
481
|
+
|
482
|
+
* Default value: bundled database `GeoLiteCity.dat`
|
483
|
+
|
484
|
+
Path to GeoIP database file.
|
485
|
+
|
486
|
+
**geoip2_database** (string) (optional)
|
434
487
|
|
435
|
-
*
|
488
|
+
* Default value: bundled database `GeoLite2-City.mmdb`.
|
436
489
|
|
437
|
-
|
438
|
-
Further details are written at http://docs.fluentd.org/articles/in_exec
|
490
|
+
Path to GeoIP2 database file.
|
439
491
|
|
440
|
-
|
492
|
+
**geoip_lookup_key** (string) (optional)
|
493
|
+
|
494
|
+
* Default value: `host`.
|
495
|
+
|
496
|
+
Specify one or more geoip lookup field which has IP address.
|
497
|
+
|
498
|
+
**skip_adding_null_record** (bool) (optional)
|
499
|
+
|
500
|
+
* Default value: `nil`
|
441
501
|
|
442
502
|
Skip adding geoip fields when this valaues to `true`.
|
443
503
|
On the case of getting nothing of GeoIP info (such as local IP), it will output the original record without changing anything.
|
444
504
|
|
505
|
+
**backend_library** (enum) (optional)
|
506
|
+
|
507
|
+
* Available values: `geoip`, `geoip2_compat`, `geoip2_c`
|
508
|
+
* Default value: `geoip2_c`.
|
509
|
+
|
510
|
+
Set backend library.
|
511
|
+
|
512
|
+
**tag** (string) (optional)
|
513
|
+
|
514
|
+
On using this option with tag placeholder like `tag geoip.${tag}` (test code is available at [test_out_geoip.rb](https://github.com/y-ken/fluent-plugin-geoip/blob/master/test/plugin/test_out_geoip.rb)).
|
515
|
+
|
516
|
+
|
445
517
|
## Articles
|
446
518
|
|
447
519
|
* [IPアドレスを元に位置情報をリアルタイムに付与する fluent-plugin-geoip v0.0.1をリリースしました #fluentd - Y-Ken Studio](http://y-ken.hatenablog.com/entry/fluent-plugin-geoip-has-released)<br />
|
@@ -463,8 +535,6 @@ http://developer.smartnews.be/blog/2013/10/03/easy-data-analysis-using-fluentd-r
|
|
463
535
|
|
464
536
|
Pull requests are very welcome!!
|
465
537
|
|
466
|
-
* support [GeoIP2](http://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/)
|
467
|
-
|
468
538
|
## Contributing
|
469
539
|
|
470
540
|
1. Fork it
|
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 = "1.
|
7
|
+
spec.version = "1.1.0"
|
8
8
|
spec.authors = ["Kentaro Yoshida"]
|
9
9
|
spec.email = ["y.ken.studio@gmail.com"]
|
10
10
|
spec.summary = %q{Fluentd Filter plugin to add information about geographical location of IP addresses with Maxmind GeoIP databases.}
|
@@ -5,20 +5,19 @@ module Fluent::Plugin
|
|
5
5
|
class GeoipFilter < Fluent::Plugin::Filter
|
6
6
|
Fluent::Plugin.register_filter('geoip', self)
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
helpers :compat_parameters, :inject
|
9
|
+
|
10
|
+
config_param :geoip_database, :string, default: File.expand_path('../../../data/GeoLiteCity.dat', __dir__)
|
11
|
+
config_param :geoip2_database, :string, default: File.expand_path('../../../data/GeoLite2-City.mmdb', __dir__)
|
10
12
|
config_param :geoip_lookup_key, :string, default: 'host'
|
11
13
|
config_param :skip_adding_null_record, :bool, default: false
|
12
14
|
|
13
|
-
config_set_default
|
14
|
-
|
15
|
-
config_param :hostname_command, :string, default: 'hostname'
|
16
|
-
|
17
|
-
config_param :log_level, :string, default: 'warn'
|
15
|
+
config_set_default :@log_level, "warn"
|
18
16
|
|
19
17
|
config_param :backend_library, :enum, list: Fluent::GeoIP::BACKEND_LIBRARIES, default: :geoip2_c
|
20
18
|
|
21
19
|
def configure(conf)
|
20
|
+
compat_parameters_convert(conf, :inject)
|
22
21
|
super
|
23
22
|
@geoip = Fluent::GeoIP.new(self, conf)
|
24
23
|
end
|
@@ -28,7 +27,12 @@ module Fluent::Plugin
|
|
28
27
|
if filtered_record
|
29
28
|
record = filtered_record
|
30
29
|
end
|
30
|
+
record = inject_values_to_record(tag, time, record)
|
31
31
|
record
|
32
32
|
end
|
33
|
+
|
34
|
+
def multi_workers_ready?
|
35
|
+
true
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
data/lib/fluent/plugin/geoip.rb
CHANGED
@@ -56,7 +56,9 @@ module Fluent
|
|
56
56
|
dummy_text = Yajl::Encoder.encode('dummy_text')
|
57
57
|
Yajl::Parser.parse(v.gsub(REGEXP_PLACEHOLDER_SCAN, dummy_text))
|
58
58
|
rescue Yajl::ParseError => e
|
59
|
-
|
59
|
+
message = "geoip: failed to parse '#{v}' as json."
|
60
|
+
log.error message, error: e
|
61
|
+
raise Fluent::ConfigError, message
|
60
62
|
end
|
61
63
|
}
|
62
64
|
validate_json.call if json?(v.tr('\'"\\', ''))
|
@@ -108,7 +110,6 @@ module Fluent
|
|
108
110
|
|
109
111
|
def quoted_value?(text)
|
110
112
|
# to improbe compatibility with fluentd v1-config
|
111
|
-
trim_quote = text[1..text.size-2]
|
112
113
|
text.match(/(^'.+'$|^".+"$)/)
|
113
114
|
end
|
114
115
|
|
@@ -151,7 +152,13 @@ module Fluent
|
|
151
152
|
position = placeholder_key.match(REGEXP_PLACEHOLDER_SINGLE)
|
152
153
|
next if position.nil? or geodata[position[:record_key]].nil?
|
153
154
|
keys = [position[:record_key]] + position[:geoip_key].split('.').map(&:to_sym)
|
154
|
-
|
155
|
+
value = geodata.dig(*keys)
|
156
|
+
value = if [:latitude, :longitude].include?(keys.last)
|
157
|
+
value || 0.0
|
158
|
+
else
|
159
|
+
value
|
160
|
+
end
|
161
|
+
placeholder[placeholder_key] = value
|
155
162
|
end
|
156
163
|
placeholder
|
157
164
|
end
|
@@ -6,23 +6,23 @@ class Fluent::Plugin::GeoipOutput < Fluent::Plugin::Output
|
|
6
6
|
|
7
7
|
helpers :event_emitter, :inject, :compat_parameters
|
8
8
|
|
9
|
-
config_param :geoip_database, :string, default: File.
|
10
|
-
config_param :geoip2_database, :string, default: File.
|
9
|
+
config_param :geoip_database, :string, default: File.expand_path('../../../data/GeoLiteCity.dat', __dir__)
|
10
|
+
config_param :geoip2_database, :string, default: File.expand_path('../../../data/GeoLite2-City.mmdb', __dir__)
|
11
11
|
config_param :geoip_lookup_key, :string, default: 'host'
|
12
12
|
config_param :tag, :string, default: nil
|
13
13
|
config_param :skip_adding_null_record, :bool, default: false
|
14
14
|
|
15
|
-
|
16
|
-
config_param :log_level, :string, default: 'warn'
|
15
|
+
config_set_default :@log_level, "warn"
|
17
16
|
|
18
17
|
config_param :backend_library, :enum, list: Fluent::GeoIP::BACKEND_LIBRARIES, default: :geoip2_c
|
19
18
|
config_section :buffer do
|
20
19
|
config_set_default :@type, :memory
|
21
20
|
config_set_default :chunk_keys, ['tag']
|
21
|
+
config_set_default :flush_interval, 0
|
22
22
|
end
|
23
23
|
|
24
24
|
def configure(conf)
|
25
|
-
compat_parameters_convert(conf, :buffer, default_chunk_key: 'tag')
|
25
|
+
compat_parameters_convert(conf, :buffer, :inject, default_chunk_key: 'tag')
|
26
26
|
super
|
27
27
|
raise Fluetn::ConfigError, "chunk key must include 'tag'" unless @chunk_key_tag
|
28
28
|
placeholder_validate!(:tag, @tag) if @tag
|
@@ -48,4 +48,8 @@ class Fluent::Plugin::GeoipOutput < Fluent::Plugin::Output
|
|
48
48
|
tag = extract_placeholders(@tag, chunk.metadata) if @tag
|
49
49
|
router.emit_stream(tag, es)
|
50
50
|
end
|
51
|
+
|
52
|
+
def multi_workers_ready?
|
53
|
+
true
|
54
|
+
end
|
51
55
|
end
|
@@ -19,6 +19,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
19
19
|
|
20
20
|
def filter(config, messages, syntax: :v1)
|
21
21
|
d = create_driver(config, syntax: syntax)
|
22
|
+
yield d if block_given?
|
22
23
|
d.run(default_tag: "input.access") {
|
23
24
|
messages.each {|message|
|
24
25
|
d.feed(@time, message)
|
@@ -27,6 +28,15 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
27
28
|
d.filtered_records
|
28
29
|
end
|
29
30
|
|
31
|
+
def setup_geoip_mock(d)
|
32
|
+
geoip = d.instance.instance_variable_get(:@geoip)
|
33
|
+
db = Object.new
|
34
|
+
def db.lookup(ip)
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
geoip.instance_variable_set(:@geoip, db)
|
38
|
+
end
|
39
|
+
|
30
40
|
sub_test_case "configure" do
|
31
41
|
test "empty" do
|
32
42
|
assert_nothing_raised {
|
@@ -392,6 +402,32 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
392
402
|
filtered = filter(config, messages)
|
393
403
|
assert_equal(expected, filtered)
|
394
404
|
end
|
405
|
+
|
406
|
+
def test_filter_when_latitude_longitude_is_nil
|
407
|
+
config = %[
|
408
|
+
backend_library geoip2_c
|
409
|
+
geoip_lookup_key host
|
410
|
+
<record>
|
411
|
+
latitude ${location.latitude['host']}
|
412
|
+
longitude ${location.longitude['host']}
|
413
|
+
</record>
|
414
|
+
]
|
415
|
+
messages = [
|
416
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
417
|
+
]
|
418
|
+
expected = [
|
419
|
+
{
|
420
|
+
"host" => "180.94.85.84",
|
421
|
+
"message" => "nil latitude and longitude",
|
422
|
+
"latitude" => 0.0,
|
423
|
+
"longitude" => 0.0
|
424
|
+
}
|
425
|
+
]
|
426
|
+
filtered = filter(config, messages) do |d|
|
427
|
+
setup_geoip_mock(d)
|
428
|
+
end
|
429
|
+
assert_equal(expected, filtered)
|
430
|
+
end
|
395
431
|
end
|
396
432
|
|
397
433
|
sub_test_case "geoip2_compat" do
|
@@ -661,6 +697,32 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
661
697
|
filtered = filter(config, messages)
|
662
698
|
assert_equal(expected, filtered)
|
663
699
|
end
|
700
|
+
|
701
|
+
def test_filter_when_latitude_longitude_is_nil
|
702
|
+
config = %[
|
703
|
+
backend_library geoip2_compat
|
704
|
+
geoip_lookup_key host
|
705
|
+
<record>
|
706
|
+
latitude ${latitude['host']}
|
707
|
+
longitude ${longitude['host']}
|
708
|
+
</record>
|
709
|
+
]
|
710
|
+
messages = [
|
711
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
712
|
+
]
|
713
|
+
expected = [
|
714
|
+
{
|
715
|
+
"host" => "180.94.85.84",
|
716
|
+
"message" => "nil latitude and longitude",
|
717
|
+
"latitude" => 0.0,
|
718
|
+
"longitude" => 0.0
|
719
|
+
}
|
720
|
+
]
|
721
|
+
filtered = filter(config, messages) do |d|
|
722
|
+
setup_geoip_mock(d)
|
723
|
+
end
|
724
|
+
assert_equal(expected, filtered)
|
725
|
+
end
|
664
726
|
end
|
665
727
|
|
666
728
|
sub_test_case "geoip legacy" do
|
@@ -1025,6 +1087,32 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
1025
1087
|
filtered = filter(config, messages)
|
1026
1088
|
assert_equal(expected, filtered)
|
1027
1089
|
end
|
1090
|
+
|
1091
|
+
def test_filter_when_latitude_longitude_is_nil
|
1092
|
+
config = %[
|
1093
|
+
backend_library geoip
|
1094
|
+
geoip_lookup_key host
|
1095
|
+
<record>
|
1096
|
+
latitude ${latitude['host']}
|
1097
|
+
longitude ${longitude['host']}
|
1098
|
+
</record>
|
1099
|
+
]
|
1100
|
+
messages = [
|
1101
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
1102
|
+
]
|
1103
|
+
expected = [
|
1104
|
+
{
|
1105
|
+
"host" => "180.94.85.84",
|
1106
|
+
"message" => "nil latitude and longitude",
|
1107
|
+
"latitude" => 0.0,
|
1108
|
+
"longitude" => 0.0
|
1109
|
+
}
|
1110
|
+
]
|
1111
|
+
filtered = filter(config, messages) do |d|
|
1112
|
+
setup_geoip_mock(d)
|
1113
|
+
end
|
1114
|
+
assert_equal(expected, filtered)
|
1115
|
+
end
|
1028
1116
|
end
|
1029
1117
|
end
|
1030
1118
|
|
@@ -273,7 +273,7 @@ class GeoipOutputTest < Test::Unit::TestCase
|
|
273
273
|
assert_equal 'Mountain View', events[0][2]['from_city']
|
274
274
|
assert_equal 'United States', events[0][2]['from_country']
|
275
275
|
assert_equal 37.419200000000004, events[0][2]['latitude']
|
276
|
-
assert_equal
|
276
|
+
assert_equal(-122.0574, events[0][2]['longitude'])
|
277
277
|
assert_equal '37.419200000000004,-122.0574', events[0][2]['float_concat']
|
278
278
|
assert_equal [-122.0574, 37.419200000000004], events[0][2]['float_array']
|
279
279
|
float_nest = {"lat" => 37.419200000000004, "lon" => -122.0574 }
|
@@ -559,7 +559,7 @@ class GeoipOutputTest < Test::Unit::TestCase
|
|
559
559
|
assert_equal 'Mountain View', events[0][2]['from_city']
|
560
560
|
assert_equal 'United States', events[0][2]['from_country']
|
561
561
|
assert_equal 37.419200000000004, events[0][2]['latitude']
|
562
|
-
assert_equal
|
562
|
+
assert_equal(-122.0574, events[0][2]['longitude'])
|
563
563
|
assert_equal '37.419200000000004,-122.0574', events[0][2]['float_concat']
|
564
564
|
assert_equal [-122.0574, 37.419200000000004], events[0][2]['float_array']
|
565
565
|
float_nest = {"lat" => 37.419200000000004, "lon" => -122.0574 }
|
@@ -933,7 +933,7 @@ class GeoipOutputTest < Test::Unit::TestCase
|
|
933
933
|
assert_equal 'Mountain View', events[0][2]['from_city']
|
934
934
|
assert_equal 'United States', events[0][2]['from_country']
|
935
935
|
assert_equal 37.4192008972168, events[0][2]['latitude']
|
936
|
-
assert_equal
|
936
|
+
assert_equal(-122.05740356445312, events[0][2]['longitude'])
|
937
937
|
assert_equal '37.4192008972168,-122.05740356445312', events[0][2]['float_concat']
|
938
938
|
assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['float_array']
|
939
939
|
float_nest = {"lat" => 37.4192008972168, "lon" => -122.05740356445312 }
|
data/utils/dump.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require "geoip"
|
4
|
+
require "geoip2_compat"
|
5
|
+
require "geoip2"
|
6
|
+
require "pp"
|
7
|
+
|
8
|
+
backend = ARGV[0]
|
9
|
+
ip = ARGV[1]
|
10
|
+
|
11
|
+
geoip_database = File.expand_path("../data/GeoLiteCity.dat", __dir__)
|
12
|
+
geoip2_database = File.expand_path("../data/GeoLite2-City.mmdb", __dir__)
|
13
|
+
|
14
|
+
geoip = GeoIP::City.new(geoip_database, :memory, false)
|
15
|
+
geoip2_compat = GeoIP2Compat.new(geoip2_database)
|
16
|
+
geoip2 = GeoIP2::Database.new(geoip2_database)
|
17
|
+
|
18
|
+
record = case backend
|
19
|
+
when "geoip"
|
20
|
+
geoip.look_up(ip)
|
21
|
+
when "geoip2_compat"
|
22
|
+
geoip2_compat.lookup(ip)
|
23
|
+
when "geoip2"
|
24
|
+
geoip2.lookup(ip)
|
25
|
+
end
|
26
|
+
|
27
|
+
pp record.to_h
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kentaro Yoshida
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- test/helper.rb
|
176
176
|
- test/plugin/test_filter_geoip.rb
|
177
177
|
- test/plugin/test_out_geoip.rb
|
178
|
+
- utils/dump.rb
|
178
179
|
homepage: https://github.com/y-ken/fluent-plugin-geoip
|
179
180
|
licenses:
|
180
181
|
- Apache-2.0
|
@@ -195,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
196
|
version: '0'
|
196
197
|
requirements: []
|
197
198
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.
|
199
|
+
rubygems_version: 2.7.3
|
199
200
|
signing_key:
|
200
201
|
specification_version: 4
|
201
202
|
summary: Fluentd Filter plugin to add information about geographical location of IP
|