fluent-plugin-geoip-kk 1.0.2 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3343f0a6464f46969141b4c6dbc731bf58ff1bddabeecd0f55bfad2a4c21b842
4
- data.tar.gz: 7c90087650a115cd023d3cde331d7504ee0540432747554e2150abd6d0ea780d
3
+ metadata.gz: a09c35276c49497e5ce32dfdb4be3ceb9281a4c74061c057ef63e3f2429c597e
4
+ data.tar.gz: d61d017ac27cd4ec7d7d3b448df7e34713dde36b36792cc7f43ee71dc88dc583
5
5
  SHA512:
6
- metadata.gz: dfd08a491d65964d1ed9ec4927ed1041f07f5a376b91b36cabf4a18c430854a7e1241fb3cbc73c65d9eb1d912f9f509659939dae5223cc4e0a63ca9cfafa6855
7
- data.tar.gz: 4f534578358e07d02a193f9019c143304e8c3ef4997a22bf14f52ce8ec384884b804a12d9130ab84c281c4d34ec873dc270f63c216a5a6c6c8246613913f36df
6
+ metadata.gz: '06163815ea4dcd37e4e42bad34d00991f7b38d21a1b05fb9b99f73821c45f570fa1706986b495d9e9225342ec0ea4cba73f4c5d26c92b161a1df19a5fdf77e1d'
7
+ data.tar.gz: fc25e0ab574149dcf1cc1bcd92e8d2ea6924b9ad2c9e955caca1b871a29aa002f5e802b4920e139b07b407c9587ca36a6ff8cc3b250e27823ac0e97460dd9fcc
data/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  | fluent-plugin-geoip-kk | fluentd | ruby |
11
11
  |----------------------------|------------|--------|
12
- | >= 1.0.1 | >= v0.14.0 | >= 2.1 |
12
+ | >= 1.0.2 | >= v0.14.0 | >= 2.1 |
13
13
  | < 1.0.0 | >= v0.12.0 | >= 1.9 |
14
14
 
15
15
 
@@ -23,66 +23,149 @@ $ gem install fluent-plugin-geoip-kk
23
23
  $ sudo td-agent-gem install fluent-plugin-geoip-kk
24
24
  ```
25
25
 
26
+ ## Configuration Parameters
26
27
 
27
- ## Usage
28
+ | Parameter | Type | Default | Description |
29
+ |-----------|------|---------|-------------|
30
+ | key_name | string | client_ip | Field name that contains the IP address |
31
+ | out_key | string | geo | Output field name to store GeoIP data |
32
+ | database_path | string | data/GeoLite2-City.mmdb | Path to the GeoIP database file |
33
+ | flatten | bool | false | Flatten the GeoIP data structure |
34
+ | cache_size | integer | 8192 | Size of the LRU cache |
35
+ | cache_ttl | integer | 3600 | TTL for cached items in seconds |
36
+ | skip_private_ip | bool | true | Skip adding GeoIP data for private IP addresses |
28
37
 
29
- ### Example 1:
38
+ ## Usage Examples
39
+
40
+ ### Basic Configuration
41
+
42
+ ```xml
43
+ <filter access.nginx.**>
44
+ @type geoip
45
+ key_name client_ip
46
+ out_key geo
47
+ </filter>
48
+ ```
49
+
50
+ ### Advanced Configuration
30
51
 
31
52
  ```xml
32
53
  <filter access.nginx.**>
33
54
  @type geoip
34
- # key_name client_ip
35
- # database_path /data/geoip/GeoLite2-City.mmdb
36
- # out_key geo
55
+
56
+ # IP address field configuration
57
+ key_name client_ip
58
+ out_key geo
59
+
60
+ # Database configuration
61
+ database_path /path/to/GeoLite2-City.mmdb
62
+
63
+ # Cache configuration
64
+ cache_size 10000 # Cache up to 10000 IP addresses
65
+ cache_ttl 3600 # Cache TTL: 1 hour
66
+
67
+ # Output configuration
68
+ flatten false # Keep nested structure
69
+
70
+ # IP processing configuration
71
+ skip_private_ip true # Skip private IP addresses
37
72
  </filter>
38
73
  ```
39
74
 
40
- Assuming following inputs are coming:
75
+ ### Input Example
41
76
 
42
77
  ```json
43
- access.nginx: {
44
- "client_ip":"93.184.216.34",
45
- "scheme":"http", "method":"GET", "host":"example.com",
46
- "path":"/", "query":"-", "req_bytes":200, "referer":"-",
47
- "status":200, "res_bytes":800, "res_body_bytes":600, "taken_time":0.001, "user_agent":"Mozilla/5.0"
78
+ {
79
+ "client_ip": "93.184.216.34",
80
+ "scheme": "http",
81
+ "method": "GET",
82
+ "host": "example.com",
83
+ "path": "/",
84
+ "query": "-",
85
+ "req_bytes": 200,
86
+ "referer": "-",
87
+ "status": 200,
88
+ "res_bytes": 800,
89
+ "res_body_bytes": 600,
90
+ "taken_time": 0.001,
91
+ "user_agent": "Mozilla/5.0"
48
92
  }
49
93
  ```
50
94
 
51
- then output bocomes as belows:
95
+ ### Output Example (Default Structure)
52
96
 
53
97
  ```json
54
- access.nginx: {
55
- "client_ip":"93.184.216.34",
56
- "scheme":"http", "method":"GET", "host":"example.com",
57
- "path":"/", "query":"-", "req_bytes":200, "referer":"-",
58
- "status":200, "res_bytes":800, "res_body_bytes":600, "taken_time":0.001, "user_agent":"Mozilla/5.0",
98
+ {
99
+ "client_ip": "93.184.216.34",
100
+ "scheme": "http",
101
+ "method": "GET",
102
+ // ... other original fields ...
59
103
  "geo": {
60
- "coordinates": [-70.8228, 42.150800000000004],
61
- "country_code": "US",
62
- "city": "Norwell",
63
- "region_code": "MA",
104
+ "coordinates": {
105
+ "latitude": 42.150800000000004,
106
+ "longitude": -70.8228,
107
+ "accuracy_radius": 100
108
+ },
109
+ "country": {
110
+ "code": "US",
111
+ "name": "United States"
112
+ },
113
+ "city": {
114
+ "name": "Norwell",
115
+ "confidence": 90
116
+ },
117
+ "region": {
118
+ "code": "MA",
119
+ "name": "Massachusetts"
120
+ },
121
+ "postal": {
122
+ "code": "02061",
123
+ "confidence": 95
124
+ },
125
+ "timezone": "America/New_York"
64
126
  }
65
127
  }
66
128
  ```
67
129
 
130
+ ### Output Example (Flattened Structure)
68
131
 
69
- ## Parameters
70
- - key_name *field_key*
132
+ When `flatten true` is specified:
71
133
 
72
- Target key name. default client_ip.
73
-
74
- - out_key *string*
134
+ ```json
135
+ {
136
+ "client_ip": "93.184.216.34",
137
+ // ... other original fields ...
138
+ "geo_coordinates_latitude": 42.150800000000004,
139
+ "geo_coordinates_longitude": -70.8228,
140
+ "geo_coordinates_accuracy_radius": 100,
141
+ "geo_country_code": "US",
142
+ "geo_country_name": "United States",
143
+ "geo_city_name": "Norwell",
144
+ "geo_city_confidence": 90,
145
+ "geo_region_code": "MA",
146
+ "geo_region_name": "Massachusetts",
147
+ "geo_postal_code": "02061",
148
+ "geo_postal_confidence": 95,
149
+ "geo_timezone": "America/New_York"
150
+ }
151
+ ```
75
152
 
76
- Output prefix key name. default geo.
153
+ ## Performance Optimization
77
154
 
78
- - database_path *file_path*
155
+ The plugin includes several performance optimizations:
79
156
 
80
- Database file(GeoIPCity.dat) path.
81
- Get from [MaxMind](http://dev.maxmind.com/geoip/legacy/geolite/)
157
+ 1. LRU Cache with TTL
158
+ - Caches GeoIP lookups to reduce database access
159
+ - Configurable cache size and TTL
160
+ - Automatic cache cleanup for expired entries
82
161
 
83
- - flatten *bool*
84
- join hashed data by '_'. default false.
162
+ 2. Skip Private IPs
163
+ - Optionally skip processing private IP addresses
164
+ - Reduces unnecessary database lookups
85
165
 
166
+ 3. Efficient Record Access
167
+ - Uses Fluentd's record accessor for optimized field access
168
+ - Reduces memory allocations
86
169
 
87
170
  ## VS.
88
171
  [fluent-plugin-geoip](https://github.com/y-ken/fluent-plugin-geoip)
@@ -95,7 +178,6 @@ It is able to customize fields with placeholder.
95
178
  * 5-10 times faster by the LRU cache.
96
179
  * See [benchmark](test/bench_geoip_filter.rb).
97
180
 
98
-
99
181
  ## Development
100
182
 
101
183
  After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
@@ -127,12 +209,10 @@ This gem uses GitHub Actions for automated publishing. To publish a new version:
127
209
  4. Push to the branch (`git push origin my-new-feature`)
128
210
  5. Create a new Pull Request
129
211
 
130
-
131
212
  ## Copyright
132
213
 
133
214
  Copyright (c) 2015 Yuri Umezaki
134
215
 
135
-
136
216
  ## License
137
217
 
138
218
  [Apache License, Version 2.0.](http://www.apache.org/licenses/LICENSE-2.0)
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'fluent-plugin-geoip-kk'
8
- spec.version = '1.0.2'
8
+ spec.version = '1.0.3'
9
9
  spec.authors = ['kevin197011']
10
10
  spec.email = ['kevin197011@outlook.com']
11
11
  spec.homepage = 'https://github.com/kevin197011/fluent-plugin-geoip-kk'
@@ -63,7 +63,7 @@ module Fluent
63
63
  # Initialize cache with TTL support
64
64
  @geoip_cache = LruRedux::TTL::Cache.new(@cache_size, @cache_ttl)
65
65
 
66
- log.info "Initialized GeoIP filter", database: @database_path, cache_size: @cache_size, cache_ttl: @cache_ttl
66
+ log.info 'Initialized GeoIP filter', database: @database_path, cache_size: @cache_size, cache_ttl: @cache_ttl
67
67
  end
68
68
 
69
69
  def filter(tag, time, record)
@@ -74,7 +74,7 @@ module Fluent
74
74
  ip = IPAddr.new(ip_addr)
75
75
  return record if @skip_private_ip && ip.private?
76
76
  rescue IPAddr::InvalidAddressError => e
77
- log.debug "Invalid IP address", ip: ip_addr, error: e.message
77
+ log.debug 'Invalid IP address', ip: ip_addr, error: e.message
78
78
  return record
79
79
  end
80
80
 
@@ -89,7 +89,7 @@ module Fluent
89
89
 
90
90
  record
91
91
  rescue StandardError => e
92
- log.error "Failed to process GeoIP lookup", error_class: e.class, error: e.message, tag: tag, time: time
92
+ log.error 'Failed to process GeoIP lookup', error_class: e.class, error: e.message, tag: tag, time: time
93
93
  record
94
94
  end
95
95
 
@@ -99,61 +99,93 @@ module Fluent
99
99
  geo_ip = @geoip.lookup(ip_addr)
100
100
  return {} if geo_ip.nil?
101
101
 
102
- {
103
- 'coordinates' => get_coordinates(geo_ip),
104
- 'country' => get_country_info(geo_ip),
105
- 'city' => get_city_info(geo_ip),
106
- 'region' => get_region_info(geo_ip),
107
- 'postal' => get_postal_info(geo_ip),
108
- 'timezone' => geo_ip.location&.time_zone
109
- }.compact
102
+ result = {}
103
+
104
+ if coordinates = get_coordinates(geo_ip)
105
+ result['coordinates'] = coordinates
106
+ end
107
+
108
+ if country = get_country_info(geo_ip)
109
+ result['country'] = country
110
+ end
111
+
112
+ if city = get_city_info(geo_ip)
113
+ result['city'] = city
114
+ end
115
+
116
+ if region = get_region_info(geo_ip)
117
+ result['region'] = region
118
+ end
119
+
120
+ if postal = get_postal_info(geo_ip)
121
+ result['postal'] = postal
122
+ end
123
+
124
+ result['timezone'] = geo_ip.location.time_zone if geo_ip.location && geo_ip.location.time_zone
125
+
126
+ result
110
127
  end
111
128
 
112
129
  def get_coordinates(geo_ip)
113
130
  return nil unless geo_ip.location
114
131
 
115
- {
116
- 'latitude' => geo_ip.location.latitude,
117
- 'longitude' => geo_ip.location.longitude,
118
- 'accuracy_radius' => geo_ip.location.accuracy_radius
119
- }.compact
132
+ result = {}
133
+ location = geo_ip.location
134
+
135
+ result['latitude'] = location.latitude if location.latitude
136
+ result['longitude'] = location.longitude if location.longitude
137
+ result['accuracy_radius'] = location.accuracy_radius if location.accuracy_radius
138
+
139
+ result.empty? ? nil : result
120
140
  end
121
141
 
122
142
  def get_country_info(geo_ip)
123
143
  return nil unless geo_ip.country
124
144
 
125
- {
126
- 'code' => geo_ip.country.iso_code,
127
- 'name' => geo_ip.country.name
128
- }.compact
145
+ result = {}
146
+ country = geo_ip.country
147
+
148
+ result['code'] = country.iso_code if country.iso_code
149
+ result['name'] = country.name if country.name
150
+
151
+ result.empty? ? nil : result
129
152
  end
130
153
 
131
154
  def get_city_info(geo_ip)
132
155
  return nil unless geo_ip.city
133
156
 
134
- {
135
- 'name' => geo_ip.city.name,
136
- 'confidence' => geo_ip.city.confidence
137
- }.compact
157
+ result = {}
158
+ city = geo_ip.city
159
+
160
+ result['name'] = city.name if city.name
161
+ result['confidence'] = city.confidence if city.confidence
162
+
163
+ result.empty? ? nil : result
138
164
  end
139
165
 
140
166
  def get_region_info(geo_ip)
141
- return nil unless geo_ip.subdivisions&.any?
167
+ return nil unless geo_ip.subdivisions && !geo_ip.subdivisions.empty?
142
168
 
143
169
  subdivision = geo_ip.subdivisions.first
144
- {
145
- 'code' => subdivision.iso_code,
146
- 'name' => subdivision.name
147
- }.compact
170
+ return nil unless subdivision
171
+
172
+ result = {}
173
+ result['code'] = subdivision.iso_code if subdivision.iso_code
174
+ result['name'] = subdivision.name if subdivision.name
175
+
176
+ result.empty? ? nil : result
148
177
  end
149
178
 
150
179
  def get_postal_info(geo_ip)
151
180
  return nil unless geo_ip.postal
152
181
 
153
- {
154
- 'code' => geo_ip.postal.code,
155
- 'confidence' => geo_ip.postal.confidence
156
- }.compact
182
+ result = {}
183
+ postal = geo_ip.postal
184
+
185
+ result['code'] = postal.code if postal.code
186
+ result['confidence'] = postal.confidence if postal.confidence
187
+
188
+ result.empty? ? nil : result
157
189
  end
158
190
 
159
191
  def hash_flatten(hash, keys = [])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-geoip-kk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - kevin197011