fluent-plugin-filter-geoip 0.2.2 → 0.2.3
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/README.md +118 -5
- data/fluent-plugin-filter-geoip.gemspec +1 -1
- data/lib/fluent/plugin/filter_geoip.rb +96 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 592c7a6c492a234c331d225cf58de2d35c669a03
|
4
|
+
data.tar.gz: b59b98a1889229052058739831f17ce4516df099
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d723fa0a431a2eb320b59d5012e72153ab6e59786422411c965dbfc7e43a5f566663b437eaf660caa9d30f5ad5798888aa545c04538a7d4054fbf96d0c616292
|
7
|
+
data.tar.gz: 72919a44209008f6fb1d5ca9bf7bf58fadb5f1ce5827dd87f73a89082f318096bde0da9b0409748d9ba42f9167e4cdc271f257b78ad83a1a72d9dc71eb697cf3
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ This is a [Fluentd](http://fluentd.org/) filter plugin for adding [GeoIP data](h
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
9
|
```
|
10
|
-
gem 'fluent-plugin-output-
|
10
|
+
gem 'fluent-plugin-output-geoip'
|
11
11
|
```
|
12
12
|
|
13
13
|
And then execute:
|
@@ -16,14 +16,32 @@ And then execute:
|
|
16
16
|
|
17
17
|
Or install it yourself as:
|
18
18
|
|
19
|
-
$ gem install fluent-plugin-output-
|
19
|
+
$ gem install fluent-plugin-output-geoip
|
20
20
|
|
21
21
|
## Config parameters
|
22
22
|
|
23
|
-
###
|
23
|
+
### download_url
|
24
24
|
|
25
25
|
```
|
26
|
-
|
26
|
+
download_url http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
|
27
|
+
```
|
28
|
+
|
29
|
+
### md5_url
|
30
|
+
|
31
|
+
```
|
32
|
+
md5_url http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
|
33
|
+
```
|
34
|
+
|
35
|
+
### database_path
|
36
|
+
|
37
|
+
```
|
38
|
+
database_path ./geoip/database/GeoLite2-City.mmdb
|
39
|
+
```
|
40
|
+
|
41
|
+
### md5_path
|
42
|
+
|
43
|
+
```
|
44
|
+
md5_path ./geoip/database/GeoLite2-City.md5
|
27
45
|
```
|
28
46
|
|
29
47
|
### lookup_field
|
@@ -116,7 +134,11 @@ connection_type true
|
|
116
134
|
<filter tail.log>
|
117
135
|
@type geoip
|
118
136
|
|
119
|
-
|
137
|
+
download_url http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
|
138
|
+
md5_url http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5
|
139
|
+
database_path ./geoip/database/GeoLite2-City.mmdb
|
140
|
+
md5_path ./geoip/database/GeoLite2-City.md5
|
141
|
+
|
120
142
|
lookup_field host
|
121
143
|
field_prefix geoip
|
122
144
|
field_delimiter _
|
@@ -135,6 +157,97 @@ connection_type true
|
|
135
157
|
</filter>
|
136
158
|
```
|
137
159
|
|
160
|
+
Assuming following inputs are coming:
|
161
|
+
|
162
|
+
```javascript
|
163
|
+
{
|
164
|
+
"host":"212.99.123.25",
|
165
|
+
"user":"-",
|
166
|
+
"method":"GET",
|
167
|
+
"path":"/item/sports/4981",
|
168
|
+
"code":"200",
|
169
|
+
"size":"94",
|
170
|
+
"referer":"/category/electronics",
|
171
|
+
"agent":"Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/20100101 Firefox/10.0.1"
|
172
|
+
}
|
173
|
+
```
|
174
|
+
|
175
|
+
then output bocomes as belows:
|
176
|
+
|
177
|
+
```javascript
|
178
|
+
{
|
179
|
+
"host":"212.99.123.25",
|
180
|
+
"user":"-",
|
181
|
+
"method":"GET",
|
182
|
+
"path":"/item/sports/4981",
|
183
|
+
"code":"200",
|
184
|
+
"size":"94",
|
185
|
+
"referer":"/category/electronics",
|
186
|
+
"agent":"Mozilla/5.0 (Windows NT 6.0; rv:10.0.1) Gecko/20100101 Firefox/10.0.1",
|
187
|
+
"geoip_continent_code":"EU",
|
188
|
+
"geoip_continent_geoname_id":6255148,
|
189
|
+
"geoip_continent_names_de":"Europa",
|
190
|
+
"geoip_continent_names_en":"Europe",
|
191
|
+
"geoip_continent_names_es":"Europa",
|
192
|
+
"geoip_continent_names_fr":"Europe",
|
193
|
+
"geoip_continent_names_ja":"ヨーロッパ",
|
194
|
+
"geoip_continent_names_pt-BR":"Europa",
|
195
|
+
"geoip_continent_names_ru":"Европа",
|
196
|
+
"geoip_continent_names_zh-CN":"欧洲",
|
197
|
+
"geoip_country_geoname_id":3017382,
|
198
|
+
"geoip_country_iso_code":"FR",
|
199
|
+
"geoip_country_names_de":"Frankreich",
|
200
|
+
"geoip_country_names_en":"France",
|
201
|
+
"geoip_country_names_es":"Francia",
|
202
|
+
"geoip_country_names_fr":"France",
|
203
|
+
"geoip_country_names_ja":"フランス共和国",
|
204
|
+
"geoip_country_names_pt-BR":"França",
|
205
|
+
"geoip_country_names_ru":"Франция",
|
206
|
+
"geoip_country_names_zh-CN":"法国",
|
207
|
+
"geoip_city_geoname_id":3038354,
|
208
|
+
"geoip_city_names_de":"Aix-en-Provence",
|
209
|
+
"geoip_city_names_en":"Aix-en-Provence",
|
210
|
+
"geoip_city_names_es":"Aix-en-Provence",
|
211
|
+
"geoip_city_names_fr":"Aix-en-Provence",
|
212
|
+
"geoip_city_names_ja":"エクス=アン=プロヴァンス",
|
213
|
+
"geoip_city_names_pt-BR":"Aix-en-Provence",
|
214
|
+
"geoip_city_names_ru":"Экс-ан-Прованс",
|
215
|
+
"geoip_city_names_zh-CN":"普罗旺斯地区艾克斯",
|
216
|
+
"geoip_location_latitude":43.5283,
|
217
|
+
"geoip_location_longitude":5.4497,
|
218
|
+
"geoip_location_time_zone":"Europe/Paris",
|
219
|
+
"geoip_postal_code":"13090",
|
220
|
+
"geoip_registered_country_geoname_id":3017382,
|
221
|
+
"geoip_registered_country_iso_code":"FR",
|
222
|
+
"geoip_registered_country_names_de":"Frankreich",
|
223
|
+
"geoip_registered_country_names_en":"France",
|
224
|
+
"geoip_registered_country_names_es":"Francia",
|
225
|
+
"geoip_registered_country_names_fr":"France",
|
226
|
+
"geoip_registered_country_names_ja":"フランス共和国",
|
227
|
+
"geoip_registered_country_names_pt-BR":"França",
|
228
|
+
"geoip_registered_country_names_ru":"Франция",
|
229
|
+
"geoip_registered_country_names_zh-CN":"法国",
|
230
|
+
"geoip_subdivisions_0_geoname_id":2985244,
|
231
|
+
"geoip_subdivisions_0_iso_code":"U",
|
232
|
+
"geoip_subdivisions_0_names_de":"Provence-Alpes-Côte d’Azur",
|
233
|
+
"geoip_subdivisions_0_names_en":"Provence-Alpes-Côte d'Azur",
|
234
|
+
"geoip_subdivisions_0_names_es":"Provenza-Alpes-Costa Azul",
|
235
|
+
"geoip_subdivisions_0_names_fr":"Provence-Alpes-Côte d'Azur",
|
236
|
+
"geoip_subdivisions_0_names_ja":"プロヴァンス=アルプ=コート・ダジュール地域圏",
|
237
|
+
"geoip_subdivisions_0_names_pt-BR":"Provença-Alpes-Costa Azul",
|
238
|
+
"geoip_subdivisions_0_names_ru":"Прованс — Альпы — Лазурный Берег",
|
239
|
+
"geoip_subdivisions_0_names_zh-CN":"普罗旺斯-阿尔卑斯-蓝色海岸",
|
240
|
+
"geoip_subdivisions_1_geoname_id":3031359,
|
241
|
+
"geoip_subdivisions_1_iso_code":"13",
|
242
|
+
"geoip_subdivisions_1_names_de":"Bouches-du-Rhône",
|
243
|
+
"geoip_subdivisions_1_names_en":"Bouches-du-Rhône",
|
244
|
+
"geoip_subdivisions_1_names_es":"Bocas del Ródano",
|
245
|
+
"geoip_subdivisions_1_names_fr":"Bouches-du-Rhône",
|
246
|
+
"geoip_subdivisions_1_names_pt-BR":"Bocas do Ródano",
|
247
|
+
"geoip_localtion_latlon":"43.5283,5.4497"
|
248
|
+
}
|
249
|
+
```
|
250
|
+
|
138
251
|
## Development
|
139
252
|
|
140
253
|
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
|
@@ -1,10 +1,17 @@
|
|
1
1
|
require 'maxminddb'
|
2
2
|
require 'json'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'open-uri'
|
3
5
|
|
4
6
|
module Fluent
|
5
7
|
class GeoIPFilter < Filter
|
6
8
|
Fluent::Plugin.register_filter('geoip', self)
|
7
9
|
|
10
|
+
DEFAULT_DOWNLOAD_URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz'
|
11
|
+
DEFAULT_MD5_URL = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.md5'
|
12
|
+
DEFAULT_DATABASE_PATH = './geoip/database/GeoLite2-City.mmdb'
|
13
|
+
DEFAULT_MD5_PATH = './geoip/database/GeoLite2-City.md5'
|
14
|
+
|
8
15
|
DEFAULT_LOOKUP_FIELD = 'ip'
|
9
16
|
DEFAULT_FIELD_PREFIX = 'geoip'
|
10
17
|
DEFAULT_FIELD_DELIMITER = '_'
|
@@ -21,7 +28,16 @@ module Fluent
|
|
21
28
|
DEFAULT_TRAITS = true
|
22
29
|
DEFAULT_CONNECTION_TYPE = true
|
23
30
|
|
24
|
-
config_param :
|
31
|
+
config_param :download_url, :string, :default => DEFAULT_DOWNLOAD_URL,
|
32
|
+
:desc => ''
|
33
|
+
|
34
|
+
config_param :md5_url, :string, :default => DEFAULT_MD5_URL,
|
35
|
+
:desc => ''
|
36
|
+
|
37
|
+
config_param :database_path, :string, :default => DEFAULT_DATABASE_PATH,
|
38
|
+
:desc => ''
|
39
|
+
|
40
|
+
config_param :md5_path, :string, :default => DEFAULT_MD5_PATH,
|
25
41
|
:desc => ''
|
26
42
|
|
27
43
|
config_param :lookup_field, :string, :default => DEFAULT_LOOKUP_FIELD,
|
@@ -73,7 +89,13 @@ module Fluent
|
|
73
89
|
def configure(conf)
|
74
90
|
super
|
75
91
|
|
76
|
-
@
|
92
|
+
@download_url = conf.has_key?('download_url') ? conf['download_url'] : DEFAULT_DOWNLOAD_URL
|
93
|
+
|
94
|
+
@md5_url = conf.has_key?('md5_url') ? conf['md5_url'] : DEFAULT_MD5_URL
|
95
|
+
|
96
|
+
@database_path = conf.has_key?('database_path') ? conf['database_path'] : DEFAULT_DATABASE_PATH
|
97
|
+
|
98
|
+
@md5_path = conf.has_key?('md5_path') ? conf['md5_path'] : DEFAULT_MD5_PATH
|
77
99
|
|
78
100
|
@lookup_field = conf.has_key?('lookup_field') ? conf['lookup_field'] : DEFAULT_LOOKUP_FIELD
|
79
101
|
|
@@ -103,6 +125,8 @@ module Fluent
|
|
103
125
|
|
104
126
|
@connection_type = conf.has_key?('connection_type') ? to_boolean(conf['connection_type']) : DEFAULT_CONNECTION_TYPE
|
105
127
|
|
128
|
+
download_database @download_url, @md5_url, @database_path, @md5_path
|
129
|
+
|
106
130
|
@database = MaxMindDB.new(@database_path)
|
107
131
|
end
|
108
132
|
|
@@ -234,6 +258,75 @@ module Fluent
|
|
234
258
|
else
|
235
259
|
return false
|
236
260
|
end
|
237
|
-
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def download_database(download_url, md5_url, database_path, md5_path)
|
264
|
+
# database directory
|
265
|
+
database_dir = File.expand_path(File.dirname(database_path))
|
266
|
+
md5_dir = File.expand_path(File.dirname(md5_path))
|
267
|
+
|
268
|
+
# create database directory if directory does not exist.
|
269
|
+
FileUtils.mkdir_p(database_dir) unless File.exist?(database_dir)
|
270
|
+
FileUtils.mkdir_p(md5_dir) unless File.exist?(md5_dir)
|
271
|
+
|
272
|
+
# create empty md5 file if file does not exist.
|
273
|
+
File.open(md5_path, 'wb').close() unless File.exist?(md5_path)
|
274
|
+
|
275
|
+
# read saved md5
|
276
|
+
saved_md5 = nil
|
277
|
+
begin
|
278
|
+
open(md5_path, 'rb') do |data|
|
279
|
+
saved_md5 = data.read
|
280
|
+
end
|
281
|
+
rescue => e
|
282
|
+
log.warn e.message
|
283
|
+
end
|
284
|
+
|
285
|
+
# fetch md5
|
286
|
+
fetched_md5 = nil
|
287
|
+
begin
|
288
|
+
open(md5_url, 'rb') do |data|
|
289
|
+
fetched_md5 = data.read
|
290
|
+
end
|
291
|
+
rescue => e
|
292
|
+
log.warn e.message
|
293
|
+
end
|
294
|
+
|
295
|
+
# check md5
|
296
|
+
unless saved_md5 == fetched_md5 then
|
297
|
+
# download new database
|
298
|
+
download_path = database_dir + '/' + File.basename(download_url)
|
299
|
+
begin
|
300
|
+
open(download_path, 'wb') do |output|
|
301
|
+
open(download_url, 'rb') do |data|
|
302
|
+
output.write(data.read)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
rescue => e
|
306
|
+
log.warn e.message
|
307
|
+
end
|
308
|
+
|
309
|
+
# unzip new database temporaly
|
310
|
+
tmp_database_path = database_dir + '/tmp_' + File.basename(database_path)
|
311
|
+
begin
|
312
|
+
open(tmp_database_path, 'wb') do |output|
|
313
|
+
Zlib::GzipReader.open(download_path) do |gz|
|
314
|
+
output.write(gz.read)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
rescue => e
|
318
|
+
puts e.message
|
319
|
+
end
|
320
|
+
|
321
|
+
# check mkd5
|
322
|
+
temp_md5 = Digest::MD5.hexdigest(File.open(tmp_database_path, 'rb').read)
|
323
|
+
if fetched_md5 == temp_md5 then
|
324
|
+
FileUtils.mv(tmp_database_path, database_path)
|
325
|
+
|
326
|
+
# record new md5
|
327
|
+
File.write(md5_path, fetched_md5)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
238
331
|
end
|
239
332
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-filter-geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Minoru Osuka
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|