fluent-plugin-geoip 1.0.0 → 1.3.2

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.
@@ -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.0.0
4
+ version: 1.3.2
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-19 00:00:00.000000000 Z
11
+ date: 2020-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit-rr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: geoip2_compat
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +163,7 @@ executables: []
149
163
  extensions: []
150
164
  extra_rdoc_files: []
151
165
  files:
166
+ - ".github/ISSUE_TEMPLATE.md"
152
167
  - ".gitignore"
153
168
  - ".travis.yml"
154
169
  - Appraisals
@@ -166,15 +181,14 @@ files:
166
181
  - dockerfiles/Dockerfile-ruby2.2
167
182
  - dockerfiles/Dockerfile-ruby2.3
168
183
  - dockerfiles/Dockerfile-ruby2.4
184
+ - dockerfiles/Dockerfile-ruby2.5
169
185
  - fluent-plugin-geoip.gemspec
170
186
  - gemfiles/fluentd_v1.0_with_backport_dig.gemfile
171
187
  - gemfiles/fluentd_v1.0_without_backport_dig.gemfile
172
188
  - lib/fluent/plugin/filter_geoip.rb
173
- - lib/fluent/plugin/geoip.rb
174
- - lib/fluent/plugin/out_geoip.rb
175
189
  - test/helper.rb
176
190
  - test/plugin/test_filter_geoip.rb
177
- - test/plugin/test_out_geoip.rb
191
+ - utils/dump.rb
178
192
  homepage: https://github.com/y-ken/fluent-plugin-geoip
179
193
  licenses:
180
194
  - Apache-2.0
@@ -194,8 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
208
  - !ruby/object:Gem::Version
195
209
  version: '0'
196
210
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.6.13
211
+ rubygems_version: 3.0.3
199
212
  signing_key:
200
213
  specification_version: 4
201
214
  summary: Fluentd Filter plugin to add information about geographical location of IP
@@ -203,4 +216,3 @@ summary: Fluentd Filter plugin to add information about geographical location of
203
216
  test_files:
204
217
  - test/helper.rb
205
218
  - test/plugin/test_filter_geoip.rb
206
- - test/plugin/test_out_geoip.rb
@@ -1,174 +0,0 @@
1
- require 'geoip'
2
- require 'yajl'
3
- unless {}.respond_to?(:dig)
4
- begin
5
- # backport_dig is faster than dig_rb so prefer backport_dig.
6
- # And Fluentd v1.0.1 uses backport_dig
7
- require 'backport_dig'
8
- rescue LoadError
9
- require 'dig_rb'
10
- end
11
- end
12
-
13
- module Fluent
14
- class GeoIP
15
- BACKEND_LIBRARIES = [:geoip, :geoip2_compat, :geoip2_c]
16
-
17
- REGEXP_PLACEHOLDER_SINGLE = /^\$\{(?<geoip_key>-?[^\[]+)\[['"](?<record_key>-?[^'"]+)['"]\]\}$/
18
- REGEXP_PLACEHOLDER_SCAN = /['"]?(\$\{[^\}]+?\})['"]?/
19
-
20
- GEOIP_KEYS = %w(city latitude longitude country_code3 country_code country_name dma_code area_code region)
21
- GEOIP2_COMPAT_KEYS = %w(city country_code country_name latitude longitude postal_code region region_name)
22
-
23
- attr_reader :log
24
-
25
- def initialize(plugin, conf)
26
- @map = {}
27
- plugin.geoip_lookup_key = plugin.geoip_lookup_key.split(/\s*,\s*/)
28
- @geoip_lookup_key = plugin.geoip_lookup_key
29
- @skip_adding_null_record = plugin.skip_adding_null_record
30
- @log = plugin.log
31
-
32
- # enable_key_* format (legacy format)
33
- conf.keys.select{|k| k =~ /^enable_key_/}.each do |key|
34
- geoip_key = key.sub('enable_key_','')
35
- raise Fluent::ConfigError, "geoip: unsupported key #{geoip_key}" unless GEOIP_KEYS.include?(geoip_key)
36
- @geoip_lookup_key.zip(conf[key].split(/\s*,\s*/)).each do |lookup_field,record_key|
37
- if record_key.nil?
38
- raise Fluent::ConfigError, "geoip: missing value found at '#{key} #{lookup_field}'"
39
- end
40
- @map[record_key] = "${#{geoip_key}['#{lookup_field}']}"
41
- end
42
- end
43
- if conf.keys.select{|k| k =~ /^enable_key_/}.size > 0
44
- log.warn "geoip: 'enable_key_*' config format is obsoleted. use <record></record> directive for now."
45
- log.warn "geoip: for further details referable to https://github.com/y-ken/fluent-plugin-geoip"
46
- end
47
-
48
- # <record></record> directive
49
- conf.elements.select { |element| element.name == 'record' }.each { |element|
50
- element.each_pair { |k, v|
51
- element.has_key?(k) # to suppress unread configuration warning
52
- v = v[1..v.size-2] if quoted_value?(v)
53
- @map[k] = v
54
- validate_json = Proc.new {
55
- begin
56
- dummy_text = Yajl::Encoder.encode('dummy_text')
57
- Yajl::Parser.parse(v.gsub(REGEXP_PLACEHOLDER_SCAN, dummy_text))
58
- rescue Yajl::ParseError => e
59
- raise Fluent::ConfigError, "geoip: failed to parse '#{v}' as json."
60
- end
61
- }
62
- validate_json.call if json?(v.tr('\'"\\', ''))
63
- }
64
- }
65
- @placeholder_keys = @map.values.join.scan(REGEXP_PLACEHOLDER_SCAN).map{ |placeholder| placeholder[0] }.uniq
66
- @placeholder_keys.each do |key|
67
- geoip_key = key.match(REGEXP_PLACEHOLDER_SINGLE)[:geoip_key]
68
- case plugin.backend_library
69
- when :geoip
70
- raise Fluent::ConfigError, "#{plugin.backend_library}: unsupported key #{geoip_key}" unless GEOIP_KEYS.include?(geoip_key)
71
- when :geoip2_compat
72
- raise Fluent::ConfigError, "#{plugin.backend_library}: unsupported key #{geoip_key}" unless GEOIP2_COMPAT_KEYS.include?(geoip_key)
73
- when :geoip2_c
74
- # Nothing to do.
75
- # We cannot define supported key(s) before we fetch values from GeoIP2 database
76
- # because geoip2_c can fetch any fields in GeoIP2 database.
77
- end
78
- end
79
-
80
- @geoip = load_database(plugin)
81
- end
82
-
83
- def add_geoip_field(record)
84
- placeholder = create_placeholder(geolocate(get_address(record)))
85
- return record if @skip_adding_null_record && placeholder.values.first.nil?
86
- @map.each do |record_key, value|
87
- if value.match(REGEXP_PLACEHOLDER_SINGLE)
88
- rewrited = placeholder[value]
89
- elsif json?(value)
90
- rewrited = value.gsub(REGEXP_PLACEHOLDER_SCAN) {|match|
91
- match = match[1..match.size-2] if quoted_value?(match)
92
- Yajl::Encoder.encode(placeholder[match])
93
- }
94
- rewrited = parse_json(rewrited)
95
- else
96
- rewrited = value.gsub(REGEXP_PLACEHOLDER_SCAN, placeholder)
97
- end
98
- record[record_key] = rewrited
99
- end
100
- return record
101
- end
102
-
103
- private
104
-
105
- def json?(text)
106
- text.match(/^\[.+\]$/) || text.match(/^\{.+\}$/)
107
- end
108
-
109
- def quoted_value?(text)
110
- # to improbe compatibility with fluentd v1-config
111
- trim_quote = text[1..text.size-2]
112
- text.match(/(^'.+'$|^".+"$)/)
113
- end
114
-
115
- def parse_json(message)
116
- begin
117
- return Yajl::Parser.parse(message)
118
- rescue Yajl::ParseError => e
119
- log.info "geoip: failed to parse '#{message}' as json.", error_class: e.class, error: e.message
120
- return nil
121
- end
122
- end
123
-
124
- def get_address(record)
125
- address = {}
126
- @geoip_lookup_key.each do |field|
127
- address[field] = record[field] || record.dig(*field.split('.'))
128
- end
129
- address
130
- end
131
-
132
- def geolocate(addresses)
133
- geodata = {}
134
- addresses.each do |field, ip|
135
- geo = nil
136
- if ip
137
- geo = if @geoip.respond_to?(:look_up)
138
- @geoip.look_up(ip)
139
- else
140
- @geoip.lookup(ip)
141
- end
142
- end
143
- geodata[field] = geo
144
- end
145
- geodata
146
- end
147
-
148
- def create_placeholder(geodata)
149
- placeholder = {}
150
- @placeholder_keys.each do |placeholder_key|
151
- position = placeholder_key.match(REGEXP_PLACEHOLDER_SINGLE)
152
- next if position.nil? or geodata[position[:record_key]].nil?
153
- keys = [position[:record_key]] + position[:geoip_key].split('.').map(&:to_sym)
154
- placeholder[placeholder_key] = geodata.dig(*keys)
155
- end
156
- placeholder
157
- end
158
-
159
- def load_database(plugin)
160
- case plugin.backend_library
161
- when :geoip
162
- ::GeoIP::City.new(plugin.geoip_database, :memory, false)
163
- when :geoip2_compat
164
- require 'geoip2_compat'
165
- GeoIP2Compat.new(plugin.geoip2_database)
166
- when :geoip2_c
167
- require 'geoip2'
168
- GeoIP2::Database.new(plugin.geoip2_database)
169
- end
170
- rescue LoadError
171
- raise Fluent::ConfigError, "You must install #{plugin.backend_library} gem."
172
- end
173
- end
174
- end
@@ -1,51 +0,0 @@
1
- require 'fluent/plugin/output'
2
- require 'fluent/plugin/geoip'
3
-
4
- class Fluent::Plugin::GeoipOutput < Fluent::Plugin::Output
5
- Fluent::Plugin.register_output('geoip', self)
6
-
7
- helpers :event_emitter, :inject, :compat_parameters
8
-
9
- config_param :geoip_database, :string, default: File.dirname(__FILE__) + '/../../../data/GeoLiteCity.dat'
10
- config_param :geoip2_database, :string, default: File.dirname(__FILE__) + '/../../../data/GeoLite2-City.mmdb'
11
- config_param :geoip_lookup_key, :string, default: 'host'
12
- config_param :tag, :string, default: nil
13
- config_param :skip_adding_null_record, :bool, default: false
14
-
15
- config_param :flush_interval, :time, default: 0
16
- config_param :log_level, :string, default: 'warn'
17
-
18
- config_param :backend_library, :enum, list: Fluent::GeoIP::BACKEND_LIBRARIES, default: :geoip2_c
19
- config_section :buffer do
20
- config_set_default :@type, :memory
21
- config_set_default :chunk_keys, ['tag']
22
- end
23
-
24
- def configure(conf)
25
- compat_parameters_convert(conf, :buffer, default_chunk_key: 'tag')
26
- super
27
- raise Fluetn::ConfigError, "chunk key must include 'tag'" unless @chunk_key_tag
28
- placeholder_validate!(:tag, @tag) if @tag
29
- @geoip = Fluent::GeoIP.new(self, conf)
30
- end
31
-
32
- def format(tag, time, record)
33
- record = inject_values_to_record(tag, time, record)
34
- [tag, time, record].to_msgpack
35
- end
36
-
37
- def formatted_to_msgpack_binary
38
- true
39
- end
40
-
41
- def write(chunk)
42
- es = Fluent::MultiEventStream.new
43
- tag = ""
44
- chunk.each do |_tag, time, record|
45
- tag = _tag
46
- es.add(time, @geoip.add_geoip_field(record))
47
- end
48
- tag = extract_placeholders(@tag, chunk.metadata) if @tag
49
- router.emit_stream(tag, es)
50
- end
51
- end
@@ -1,1076 +0,0 @@
1
- require 'helper'
2
- require 'fluent/plugin/out_geoip'
3
- require 'fluent/test/driver/output'
4
-
5
- class GeoipOutputTest < Test::Unit::TestCase
6
- def setup
7
- Fluent::Test.setup
8
- end
9
-
10
- CONFIG = %[
11
- geoip_lookup_key host
12
- enable_key_city geoip_city
13
- tag geoip.${tag[1]}
14
- ]
15
-
16
- def create_driver(conf = CONFIG, syntax: :v1)
17
- Fluent::Test::Driver::Output.new(Fluent::Plugin::GeoipOutput).configure(conf, syntax: syntax)
18
- end
19
-
20
- sub_test_case "configure" do
21
- test "empty" do
22
- assert_nothing_raised do
23
- create_driver('')
24
- end
25
- end
26
-
27
- test "missing required parameters" do
28
- assert_raise(Fluent::ConfigError) {
29
- create_driver('enable_key_cities')
30
- }
31
- end
32
-
33
- test "minimum" do
34
- d = create_driver %[
35
- enable_key_city geoip_city
36
- tag geoip.${tag[1]}
37
- ]
38
- assert_equal 'geoip_city', d.instance.config['enable_key_city']
39
- end
40
-
41
- test "invalid key name" do
42
- assert_raise(Fluent::ConfigError.new("geoip: unsupported key cities")) do
43
- create_driver('enable_key_cities')
44
- end
45
- end
46
-
47
- test "multiple key config" do
48
- d = create_driver %[
49
- geoip_lookup_key from.ip, to.ip
50
- enable_key_city from_city, to_city
51
- tag geoip.${tag[1]}
52
- ]
53
- assert_equal 'from_city, to_city', d.instance.config['enable_key_city']
54
- end
55
-
56
- test "multiple key config (bad configure)" do
57
- assert_raise(Fluent::ConfigError) do
58
- create_driver %[
59
- geoip_lookup_key from.ip, to.ip
60
- enable_key_city from_city
61
- enable_key_region from_region
62
- tag geoip.${tag[1]}
63
- ]
64
- end
65
- end
66
-
67
- test "invalid json structure w/ Ruby hash like" do
68
- assert_raise(Fluent::ConfigParseError) do
69
- create_driver %[
70
- geoip_lookup_key host
71
- <record>
72
- invalid_json {"foo" => 123}
73
- </record>
74
- tag geoip.${tag[1]}
75
- ]
76
- end
77
- end
78
-
79
- test "invalid json structure w/ unquoted string literal" do
80
- assert_raise(Fluent::ConfigParseError) do
81
- create_driver %[
82
- geoip_lookup_key host
83
- <record>
84
- invalid_json {"foo" : string, "bar" : 123}
85
- </record>
86
- tag geoip.${tag[1]}
87
- ]
88
- end
89
- end
90
-
91
- data(geoip: "geoip",
92
- geoip2_compat: "geoip2_compat")
93
- test "unsupported key" do |backend|
94
- assert_raise(Fluent::ConfigError.new("#{backend}: unsupported key unknown")) do
95
- create_driver %[
96
- backend_library #{backend}
97
- <record>
98
- city ${unknown["host"]}
99
- </record>
100
- tag geoip.${tag[1]}
101
- ]
102
- end
103
- end
104
-
105
- data(geoip: ["geoip", '${city["host"]}'],
106
- geoip2_compat: ["geoip2_compat", '${city["host"]}'],
107
- geoip2_c: ["geoip2_c", '${city.names.en["host"]}'])
108
- test "supported backend" do |(backend, placeholder)|
109
- create_driver %[
110
- backend_library #{backend}
111
- <record>
112
- city #{placeholder}
113
- </record>
114
- tag geoip.${tag[1]}
115
- ]
116
- end
117
-
118
- test "unsupported backend" do
119
- assert_raise(Fluent::ConfigError) do
120
- create_driver %[
121
- backend_library hive_geoip2
122
- <record>
123
- city ${city["host"]}
124
- </record>
125
- tag geoip.${tag[1]}
126
- ]
127
- end
128
- end
129
- end
130
-
131
- sub_test_case "geoip2_c" do
132
- def test_emit_tag_option
133
- d1 = create_driver(%[
134
- backend_library geoip2_c
135
- geoip_lookup_key host
136
- <record>
137
- geoip_city ${city.names.en['host']}
138
- </record>
139
- tag geoip.${tag[1]}
140
- ])
141
- d1.run(default_tag: 'input.access') do
142
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
143
- d1.feed({'message' => 'missing field'})
144
- end
145
- events = d1.events
146
- assert_equal 2, events.length
147
- assert_equal 'geoip.access', events[0][0] # tag
148
- assert_equal 'Mountain View', events[0][2]['geoip_city']
149
- assert_equal nil, events[1][2]['geoip_city']
150
- end
151
-
152
- def test_emit_tag_parts
153
- d1 = create_driver(%[
154
- backend_library geoip2_c
155
- geoip_lookup_key host
156
- <record>
157
- geoip_city ${city.names.en['host']}
158
- </record>
159
- tag geoip.${tag[1]}.${tag[2]}.${tag[3]}
160
- ])
161
- d1.run(default_tag: '0.1.2.3') do
162
- d1.feed({'host' => '66.102.3.80'})
163
- end
164
- events = d1.events
165
- assert_equal 1, events.length
166
- assert_equal 'geoip.1.2.3', events[0][0] # tag
167
- assert_equal 'Mountain View', events[0][2]['geoip_city']
168
- end
169
-
170
- def test_emit_with_dot_key
171
- d1 = create_driver(%[
172
- backend_library geoip2_c
173
- geoip_lookup_key ip.origin, ip.dest
174
- <record>
175
- origin_country ${country.iso_code['ip.origin']}
176
- dest_country ${country.iso_code['ip.dest']}
177
- </record>
178
- tag geoip.${tag[1]}
179
- ])
180
- d1.run(default_tag: 'input.access') do
181
- d1.feed({'ip.origin' => '66.102.3.80', 'ip.dest' => '8.8.8.8'})
182
- end
183
- events = d1.events
184
- assert_equal 1, events.length
185
- assert_equal 'geoip.access', events[0][0] # tag
186
- assert_equal 'US', events[0][2]['origin_country']
187
- assert_equal 'US', events[0][2]['dest_country']
188
- end
189
-
190
- def test_emit_with_unknown_address
191
- d1 = create_driver(%[
192
- backend_library geoip2_c
193
- geoip_lookup_key host
194
- <record>
195
- geoip_city ${city.names.en['host']}
196
- geopoint [${location.longitude['host']}, ${location.latitude['host']}]
197
- </record>
198
- skip_adding_null_record false
199
- tag geoip.${tag[1]}
200
- ], syntax: :v0)
201
- d1.run(default_tag: 'input.access') do
202
- # 203.0.113.1 is a test address described in RFC5737
203
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
204
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
205
- end
206
- events = d1.events
207
- assert_equal 2, events.length
208
- assert_equal 'geoip.access', events[0][0] # tag
209
- assert_equal nil, events[0][2]['geoip_city']
210
- assert_equal 'geoip.access', events[1][0] # tag
211
- assert_equal nil, events[1][2]['geoip_city']
212
- end
213
-
214
- def test_emit_with_skip_unknown_address
215
- d1 = create_driver(%[
216
- backend_library geoip2_c
217
- geoip_lookup_key host
218
- <record>
219
- geoip_city ${city.names.en['host']}
220
- geopoint [${location.longitude['host']}, ${location.latitude['host']}]
221
- </record>
222
- skip_adding_null_record true
223
- tag geoip.${tag[1]}
224
- ], syntax: :v0)
225
- d1.run(default_tag: 'input.access') do
226
- # 203.0.113.1 is a test address described in RFC5737
227
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
228
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
229
- d1.feed({'host' => '66.102.3.80', 'message' => 'google bot'})
230
- end
231
- events = d1.events
232
- assert_equal 3, events.length
233
- assert_equal 'geoip.access', events[0][0] # tag
234
- assert_equal nil, events[0][2]['geoip_city']
235
- assert_equal nil, events[0][2]['geopoint']
236
- assert_equal 'geoip.access', events[1][0] # tag
237
- assert_equal nil, events[1][2]['geoip_city']
238
- assert_equal nil, events[1][2]['geopoint']
239
- assert_equal 'Mountain View', events[2][2]['geoip_city']
240
- assert_equal [-122.0574, 37.419200000000004], events[2][2]['geopoint']
241
- end
242
-
243
- def test_emit_record_directive
244
- d1 = create_driver(%[
245
- backend_library geoip2_c
246
- geoip_lookup_key from.ip
247
- <record>
248
- from_city ${city.names.en['from.ip']}
249
- from_country ${country.names.en['from.ip']}
250
- latitude ${location.latitude['from.ip']}
251
- longitude ${location.longitude['from.ip']}
252
- float_concat ${location.latitude['from.ip']},${location.longitude['from.ip']}
253
- float_array [${location.longitude['from.ip']}, ${location.latitude['from.ip']}]
254
- float_nest { "lat" : ${location.latitude['from.ip']}, "lon" : ${location.longitude['from.ip']}}
255
- string_concat ${location.latitude['from.ip']},${location.longitude['from.ip']}
256
- string_array [${city.names.en['from.ip']}, ${country.names.en['from.ip']}]
257
- string_nest { "city" : ${city.names.en['from.ip']}, "country_name" : ${country.names.en['from.ip']}}
258
- unknown_city ${city.names.en['unknown_key']}
259
- undefined ${city.names.en['undefined']}
260
- broken_array1 [${location.longitude['from.ip']}, ${location.latitude['undefined']}]
261
- broken_array2 [${location.longitude['undefined']}, ${location.latitude['undefined']}]
262
- </record>
263
- tag geoip.${tag[1]}
264
- ], syntax: :v0)
265
- d1.run(default_tag: 'input.access') do
266
- d1.feed({'from' => {'ip' => '66.102.3.80'}})
267
- d1.feed({'message' => 'missing field'})
268
- end
269
- events = d1.events
270
- assert_equal 2, events.length
271
-
272
- assert_equal 'geoip.access', events[0][0] # tag
273
- assert_equal 'Mountain View', events[0][2]['from_city']
274
- assert_equal 'United States', events[0][2]['from_country']
275
- assert_equal 37.419200000000004, events[0][2]['latitude']
276
- assert_equal -122.0574, events[0][2]['longitude']
277
- assert_equal '37.419200000000004,-122.0574', events[0][2]['float_concat']
278
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['float_array']
279
- float_nest = {"lat" => 37.419200000000004, "lon" => -122.0574 }
280
- assert_equal float_nest, events[0][2]['float_nest']
281
- assert_equal '37.419200000000004,-122.0574', events[0][2]['string_concat']
282
- assert_equal ["Mountain View", "United States"], events[0][2]['string_array']
283
- string_nest = {"city" => "Mountain View", "country_name" => "United States"}
284
- assert_equal string_nest, events[0][2]['string_nest']
285
- assert_equal nil, events[0][2]['unknown_city']
286
- assert_equal nil, events[0][2]['undefined']
287
- assert_equal [-122.0574, nil], events[0][2]['broken_array1']
288
- assert_equal [nil, nil], events[0][2]['broken_array2']
289
-
290
- assert_equal nil, events[1][2]['from_city']
291
- assert_equal nil, events[1][2]['from_country']
292
- assert_equal nil, events[1][2]['latitude']
293
- assert_equal nil, events[1][2]['longitude']
294
- assert_equal ',', events[1][2]['float_concat']
295
- assert_equal [nil, nil], events[1][2]['float_array']
296
- float_nest = {"lat" => nil, "lon" => nil}
297
- assert_equal float_nest, events[1][2]['float_nest']
298
- assert_equal ',', events[1][2]['string_concat']
299
- assert_equal [nil, nil], events[1][2]['string_array']
300
- string_nest = {"city" => nil, "country_name" => nil}
301
- assert_equal string_nest, events[1][2]['string_nest']
302
- assert_equal nil, events[1][2]['unknown_city']
303
- assert_equal nil, events[1][2]['undefined']
304
- assert_equal [nil, nil], events[1][2]['broken_array1']
305
- assert_equal [nil, nil], events[1][2]['broken_array2']
306
- end
307
-
308
- def test_emit_record_directive_multiple_record
309
- d1 = create_driver(%[
310
- backend_library geoip2_c
311
- geoip_lookup_key from.ip, to.ip
312
- <record>
313
- from_city ${city.names.en['from.ip']}
314
- to_city ${city.names.en['to.ip']}
315
- from_country ${country.names.en['from.ip']}
316
- to_country ${country.names.en['to.ip']}
317
- string_array [${country.names.en['from.ip']}, ${country.names.en['to.ip']}]
318
- </record>
319
- tag geoip.${tag[1]}
320
- ], syntax: :v0)
321
- d1.run(default_tag: 'input.access') do
322
- d1.feed({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}})
323
- d1.feed({'message' => 'missing field'})
324
- end
325
- events = d1.events
326
- assert_equal 2, events.length
327
-
328
- assert_equal 'geoip.access', events[0][0] # tag
329
- assert_equal 'Mountain View', events[0][2]['from_city']
330
- assert_equal 'United States', events[0][2]['from_country']
331
- assert_equal 'Tokorozawa', events[0][2]['to_city']
332
- assert_equal 'Japan', events[0][2]['to_country']
333
- assert_equal ['United States','Japan'], events[0][2]['string_array']
334
-
335
- assert_equal nil, events[1][2]['from_city']
336
- assert_equal nil, events[1][2]['to_city']
337
- assert_equal nil, events[1][2]['from_country']
338
- assert_equal nil, events[1][2]['to_country']
339
- assert_equal [nil, nil], events[1][2]['string_array']
340
- end
341
-
342
- def config_quoted_record
343
- %[
344
- backend_library geoip2_c
345
- geoip_lookup_key host
346
- <record>
347
- location_properties '{ "country_code" : "${country.iso_code["host"]}", "lat": ${location.latitude["host"]}, "lon": ${location.longitude["host"]} }'
348
- location_string ${location.latitude['host']},${location.longitude['host']}
349
- location_string2 ${country.iso_code["host"]}
350
- location_array "[${location.longitude['host']},${location.latitude['host']}]"
351
- location_array2 '[${location.longitude["host"]},${location.latitude["host"]}]'
352
- peculiar_pattern '[GEOIP] message => {"lat":${location.latitude["host"]}, "lon":${location.longitude["host"]}}'
353
- </record>
354
- tag geoip.${tag[1]}
355
- ]
356
- end
357
-
358
- def test_emit_quoted_record
359
- d1 = create_driver(config_quoted_record)
360
- d1.run(default_tag: 'input.access') do
361
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
362
- end
363
- events = d1.events
364
- assert_equal 1, events.length
365
- assert_equal 'geoip.access', events[0][0] # tag
366
- location_properties = { "country_code" => "US", "lat" => 37.419200000000004, "lon"=> -122.0574 }
367
- assert_equal location_properties, events[0][2]['location_properties']
368
- assert_equal '37.419200000000004,-122.0574', events[0][2]['location_string']
369
- assert_equal 'US', events[0][2]['location_string2']
370
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array']
371
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array2']
372
- assert_equal '[GEOIP] message => {"lat":37.419200000000004, "lon":-122.0574}', events[0][2]['peculiar_pattern']
373
- end
374
-
375
- def test_emit_v1_config_compatibility
376
- d1 = create_driver(config_quoted_record)
377
- d1.run(default_tag: 'input.access') do
378
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
379
- end
380
- events = d1.events
381
- assert_equal 1, events.length
382
- assert_equal 'geoip.access', events[0][0] # tag
383
- location_properties = { "country_code" => "US", "lat" => 37.419200000000004, "lon"=> -122.0574 }
384
- assert_equal location_properties, events[0][2]['location_properties']
385
- assert_equal '37.419200000000004,-122.0574', events[0][2]['location_string']
386
- assert_equal 'US', events[0][2]['location_string2']
387
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array']
388
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array2']
389
- assert_equal '[GEOIP] message => {"lat":37.419200000000004, "lon":-122.0574}', events[0][2]['peculiar_pattern']
390
- end
391
-
392
- def test_emit_multiline_v1_config
393
- d1 = create_driver(%[
394
- backend_library geoip2_c
395
- geoip_lookup_key host
396
- <record>
397
- location_properties {
398
- "city": "${city.names.en['host']}",
399
- "country_code": "${country.iso_code['host']}",
400
- "latitude": "${location.latitude['host']}",
401
- "longitude": "${location.longitude['host']}"
402
- }
403
- </record>
404
- tag geoip.${tag[1]}
405
- ])
406
- d1.run(default_tag: 'input.access') do
407
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
408
- end
409
- events = d1.events
410
- assert_equal 1, events.length
411
- assert_equal 'geoip.access', events[0][0] # tag
412
- location_properties = { "city"=>"Mountain View", "country_code"=>"US", "latitude"=>37.419200000000004, "longitude"=>-122.0574 }
413
- assert_equal location_properties, events[0][2]['location_properties']
414
- end
415
- end
416
-
417
- sub_test_case "geoip2_compat" do
418
- def test_emit_tag_option
419
- d1 = create_driver(%[
420
- backend_library geoip2_compat
421
- geoip_lookup_key host
422
- <record>
423
- geoip_city ${city['host']}
424
- </record>
425
- tag geoip.${tag[1]}
426
- ])
427
- d1.run(default_tag: 'input.access') do
428
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
429
- d1.feed({'message' => 'missing field'})
430
- end
431
- events = d1.events
432
- assert_equal 2, events.length
433
- assert_equal 'geoip.access', events[0][0] # tag
434
- assert_equal 'Mountain View', events[0][2]['geoip_city']
435
- assert_equal nil, events[1][2]['geoip_city']
436
- end
437
-
438
- def test_emit_tag_parts
439
- d1 = create_driver(%[
440
- backend_library geoip2_compat
441
- geoip_lookup_key host
442
- <record>
443
- geoip_city ${city['host']}
444
- </record>
445
- tag geoip.${tag[1]}.${tag[2]}.${tag[3]}
446
- ])
447
- d1.run(default_tag: '0.1.2.3') do
448
- d1.feed({'host' => '66.102.3.80'})
449
- end
450
- events = d1.events
451
- assert_equal 1, events.length
452
- assert_equal 'geoip.1.2.3', events[0][0] # tag
453
- assert_equal 'Mountain View', events[0][2]['geoip_city']
454
- end
455
-
456
- def test_emit_with_dot_key
457
- d1 = create_driver(%[
458
- backend_library geoip2_compat
459
- geoip_lookup_key ip.origin, ip.dest
460
- <record>
461
- origin_country ${country_code['ip.origin']}
462
- dest_country ${country_code['ip.dest']}
463
- </record>
464
- tag geoip.${tag[1]}
465
- ])
466
- d1.run(default_tag: 'input.access') do
467
- d1.feed({'ip.origin' => '66.102.3.80', 'ip.dest' => '8.8.8.8'})
468
- end
469
- events = d1.events
470
- assert_equal 1, events.length
471
- assert_equal 'geoip.access', events[0][0] # tag
472
- assert_equal 'US', events[0][2]['origin_country']
473
- assert_equal 'US', events[0][2]['dest_country']
474
- end
475
-
476
- def test_emit_with_unknown_address
477
- d1 = create_driver(%[
478
- backend_library geoip2_compat
479
- geoip_lookup_key host
480
- <record>
481
- geoip_city ${city['host']}
482
- geopoint [${longitude['host']}, ${latitude['host']}]
483
- </record>
484
- skip_adding_null_record false
485
- tag geoip.${tag[1]}
486
- ], syntax: :v0)
487
- d1.run(default_tag: 'input.access') do
488
- # 203.0.113.1 is a test address described in RFC5737
489
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
490
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
491
- end
492
- events = d1.events
493
- assert_equal 2, events.length
494
- assert_equal 'geoip.access', events[0][0] # tag
495
- assert_equal nil, events[0][2]['geoip_city']
496
- assert_equal 'geoip.access', events[1][0] # tag
497
- assert_equal nil, events[1][2]['geoip_city']
498
- end
499
-
500
- def test_emit_with_skip_unknown_address
501
- d1 = create_driver(%[
502
- backend_library geoip2_compat
503
- geoip_lookup_key host
504
- <record>
505
- geoip_city ${city['host']}
506
- geopoint [${longitude['host']}, ${latitude['host']}]
507
- </record>
508
- skip_adding_null_record true
509
- tag geoip.${tag[1]}
510
- ], syntax: :v0)
511
- d1.run(default_tag: 'input.access') do
512
- # 203.0.113.1 is a test address described in RFC5737
513
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
514
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
515
- d1.feed({'host' => '66.102.3.80', 'message' => 'google bot'})
516
- end
517
- events = d1.events
518
- assert_equal 3, events.length
519
- assert_equal 'geoip.access', events[0][0] # tag
520
- assert_equal nil, events[0][2]['geoip_city']
521
- assert_equal nil, events[0][2]['geopoint']
522
- assert_equal 'geoip.access', events[1][0] # tag
523
- assert_equal nil, events[1][2]['geoip_city']
524
- assert_equal nil, events[1][2]['geopoint']
525
- assert_equal 'Mountain View', events[2][2]['geoip_city']
526
- assert_equal [-122.0574, 37.419200000000004], events[2][2]['geopoint']
527
- end
528
-
529
- def test_emit_record_directive
530
- d1 = create_driver(%[
531
- backend_library geoip2_compat
532
- geoip_lookup_key from.ip
533
- <record>
534
- from_city ${city['from.ip']}
535
- from_country ${country_name['from.ip']}
536
- latitude ${latitude['from.ip']}
537
- longitude ${longitude['from.ip']}
538
- float_concat ${latitude['from.ip']},${longitude['from.ip']}
539
- float_array [${longitude['from.ip']}, ${latitude['from.ip']}]
540
- float_nest { "lat" : ${latitude['from.ip']}, "lon" : ${longitude['from.ip']}}
541
- string_concat ${latitude['from.ip']},${longitude['from.ip']}
542
- string_array [${city['from.ip']}, ${country_name['from.ip']}]
543
- string_nest { "city" : ${city['from.ip']}, "country_name" : ${country_name['from.ip']}}
544
- unknown_city ${city['unknown_key']}
545
- undefined ${city['undefined']}
546
- broken_array1 [${longitude['from.ip']}, ${latitude['undefined']}]
547
- broken_array2 [${longitude['undefined']}, ${latitude['undefined']}]
548
- </record>
549
- tag geoip.${tag[1]}
550
- ], syntax: :v0)
551
- d1.run(default_tag: 'input.access') do
552
- d1.feed({'from' => {'ip' => '66.102.3.80'}})
553
- d1.feed({'message' => 'missing field'})
554
- end
555
- events = d1.events
556
- assert_equal 2, events.length
557
-
558
- assert_equal 'geoip.access', events[0][0] # tag
559
- assert_equal 'Mountain View', events[0][2]['from_city']
560
- assert_equal 'United States', events[0][2]['from_country']
561
- assert_equal 37.419200000000004, events[0][2]['latitude']
562
- assert_equal -122.0574, events[0][2]['longitude']
563
- assert_equal '37.419200000000004,-122.0574', events[0][2]['float_concat']
564
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['float_array']
565
- float_nest = {"lat" => 37.419200000000004, "lon" => -122.0574 }
566
- assert_equal float_nest, events[0][2]['float_nest']
567
- assert_equal '37.419200000000004,-122.0574', events[0][2]['string_concat']
568
- assert_equal ["Mountain View", "United States"], events[0][2]['string_array']
569
- string_nest = {"city" => "Mountain View", "country_name" => "United States"}
570
- assert_equal string_nest, events[0][2]['string_nest']
571
- assert_equal nil, events[0][2]['unknown_city']
572
- assert_equal nil, events[0][2]['undefined']
573
- assert_equal [-122.0574, nil], events[0][2]['broken_array1']
574
- assert_equal [nil, nil], events[0][2]['broken_array2']
575
-
576
- assert_equal nil, events[1][2]['from_city']
577
- assert_equal nil, events[1][2]['from_country']
578
- assert_equal nil, events[1][2]['latitude']
579
- assert_equal nil, events[1][2]['longitude']
580
- assert_equal ',', events[1][2]['float_concat']
581
- assert_equal [nil, nil], events[1][2]['float_array']
582
- float_nest = {"lat" => nil, "lon" => nil}
583
- assert_equal float_nest, events[1][2]['float_nest']
584
- assert_equal ',', events[1][2]['string_concat']
585
- assert_equal [nil, nil], events[1][2]['string_array']
586
- string_nest = {"city" => nil, "country_name" => nil}
587
- assert_equal string_nest, events[1][2]['string_nest']
588
- assert_equal nil, events[1][2]['unknown_city']
589
- assert_equal nil, events[1][2]['undefined']
590
- assert_equal [nil, nil], events[1][2]['broken_array1']
591
- assert_equal [nil, nil], events[1][2]['broken_array2']
592
- end
593
-
594
- def test_emit_record_directive_multiple_record
595
- d1 = create_driver(%[
596
- backend_library geoip2_compat
597
- geoip_lookup_key from.ip, to.ip
598
- <record>
599
- from_city ${city['from.ip']}
600
- to_city ${city['to.ip']}
601
- from_country ${country_name['from.ip']}
602
- to_country ${country_name['to.ip']}
603
- string_array [${country_name['from.ip']}, ${country_name['to.ip']}]
604
- </record>
605
- tag geoip.${tag[1]}
606
- ], syntax: :v0)
607
- d1.run(default_tag: 'input.access') do
608
- d1.feed({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}})
609
- d1.feed({'message' => 'missing field'})
610
- end
611
- events = d1.events
612
- assert_equal 2, events.length
613
-
614
- assert_equal 'geoip.access', events[0][0] # tag
615
- assert_equal 'Mountain View', events[0][2]['from_city']
616
- assert_equal 'United States', events[0][2]['from_country']
617
- assert_equal 'Tokorozawa', events[0][2]['to_city']
618
- assert_equal 'Japan', events[0][2]['to_country']
619
- assert_equal ['United States','Japan'], events[0][2]['string_array']
620
-
621
- assert_equal nil, events[1][2]['from_city']
622
- assert_equal nil, events[1][2]['to_city']
623
- assert_equal nil, events[1][2]['from_country']
624
- assert_equal nil, events[1][2]['to_country']
625
- assert_equal [nil, nil], events[1][2]['string_array']
626
- end
627
-
628
- def config_quoted_record
629
- %[
630
- backend_library geoip2_compat
631
- geoip_lookup_key host
632
- <record>
633
- location_properties '{ "country_code" : "${country_code["host"]}", "lat": ${latitude["host"]}, "lon": ${longitude["host"]} }'
634
- location_string ${latitude['host']},${longitude['host']}
635
- location_string2 ${country_code["host"]}
636
- location_array "[${longitude['host']},${latitude['host']}]"
637
- location_array2 '[${longitude["host"]},${latitude["host"]}]'
638
- peculiar_pattern '[GEOIP] message => {"lat":${latitude["host"]}, "lon":${longitude["host"]}}'
639
- </record>
640
- tag geoip.${tag[1]}
641
- ]
642
- end
643
-
644
- def test_emit_quoted_record
645
- d1 = create_driver(config_quoted_record)
646
- d1.run(default_tag: 'input.access') do
647
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
648
- end
649
- events = d1.events
650
- assert_equal 1, events.length
651
- assert_equal 'geoip.access', events[0][0] # tag
652
- location_properties = { "country_code" => "US", "lat" => 37.419200000000004, "lon"=> -122.0574 }
653
- assert_equal location_properties, events[0][2]['location_properties']
654
- assert_equal '37.419200000000004,-122.0574', events[0][2]['location_string']
655
- assert_equal 'US', events[0][2]['location_string2']
656
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array']
657
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array2']
658
- assert_equal '[GEOIP] message => {"lat":37.419200000000004, "lon":-122.0574}', events[0][2]['peculiar_pattern']
659
- end
660
-
661
- def test_emit_v1_config_compatibility
662
- d1 = create_driver(config_quoted_record)
663
- d1.run(default_tag: 'input.access') do
664
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
665
- end
666
- events = d1.events
667
- assert_equal 1, events.length
668
- assert_equal 'geoip.access', events[0][0] # tag
669
- location_properties = { "country_code" => "US", "lat" => 37.419200000000004, "lon"=> -122.0574 }
670
- assert_equal location_properties, events[0][2]['location_properties']
671
- assert_equal '37.419200000000004,-122.0574', events[0][2]['location_string']
672
- assert_equal 'US', events[0][2]['location_string2']
673
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array']
674
- assert_equal [-122.0574, 37.419200000000004], events[0][2]['location_array2']
675
- assert_equal '[GEOIP] message => {"lat":37.419200000000004, "lon":-122.0574}', events[0][2]['peculiar_pattern']
676
- end
677
-
678
- def test_emit_multiline_v1_config
679
- d1 = create_driver(%[
680
- backend_library geoip2_compat
681
- geoip_lookup_key host
682
- <record>
683
- location_properties {
684
- "city": "${city['host']}",
685
- "country_code": "${country_code['host']}",
686
- "latitude": "${latitude['host']}",
687
- "longitude": "${longitude['host']}"
688
- }
689
- </record>
690
- tag geoip.${tag[1]}
691
- ])
692
- d1.run(default_tag: 'input.access') do
693
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
694
- end
695
- events = d1.events
696
- assert_equal 1, events.length
697
- assert_equal 'geoip.access', events[0][0] # tag
698
- location_properties = { "city"=>"Mountain View", "country_code"=>"US", "latitude"=>37.419200000000004, "longitude"=>-122.0574 }
699
- assert_equal location_properties, events[0][2]['location_properties']
700
- end
701
- end
702
-
703
- sub_test_case "geoip legacy" do
704
- def test_emit
705
- d1 = create_driver(%[
706
- backend_library geoip
707
- geoip_lookup_key host
708
- enable_key_city geoip_city
709
- tag geoip.${tag[1]}
710
- ])
711
- d1.run(default_tag: 'input.access') do
712
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
713
- d1.feed({'message' => 'missing field'})
714
- end
715
- events = d1.events
716
- assert_equal 2, events.length
717
- assert_equal 'geoip.access', events[0][0] # tag
718
- assert_equal 'Mountain View', events[0][2]['geoip_city']
719
- assert_equal nil, events[1][2]['geoip_city']
720
- end
721
-
722
- def test_emit_tag_option
723
- d1 = create_driver(%[
724
- backend_library geoip
725
- geoip_lookup_key host
726
- <record>
727
- geoip_city ${city['host']}
728
- </record>
729
- tag geoip.${tag[1]}
730
- ])
731
- d1.run(default_tag: 'input.access') do
732
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
733
- d1.feed({'message' => 'missing field'})
734
- end
735
- events = d1.events
736
- assert_equal 2, events.length
737
- assert_equal 'geoip.access', events[0][0] # tag
738
- assert_equal 'Mountain View', events[0][2]['geoip_city']
739
- assert_equal nil, events[1][2]['geoip_city']
740
- end
741
-
742
- def test_emit_tag_parts
743
- d1 = create_driver(%[
744
- backend_library geoip
745
- geoip_lookup_key host
746
- <record>
747
- geoip_city ${city['host']}
748
- </record>
749
- tag geoip.${tag[1]}.${tag[2]}.${tag[3]}
750
- ])
751
- d1.run(default_tag: '0.1.2.3') do
752
- d1.feed({'host' => '66.102.3.80'})
753
- end
754
- events = d1.events
755
- assert_equal 1, events.length
756
- assert_equal 'geoip.1.2.3', events[0][0] # tag
757
- assert_equal 'Mountain View', events[0][2]['geoip_city']
758
- end
759
-
760
- def test_emit_with_dot_key
761
- d1 = create_driver(%[
762
- backend_library geoip
763
- geoip_lookup_key ip.origin, ip.dest
764
- <record>
765
- origin_country ${country_code['ip.origin']}
766
- dest_country ${country_code['ip.dest']}
767
- </record>
768
- tag geoip.${tag[1]}
769
- ])
770
- d1.run(default_tag: 'input.access') do
771
- d1.feed({'ip.origin' => '66.102.3.80', 'ip.dest' => '8.8.8.8'})
772
- end
773
- events = d1.events
774
- assert_equal 1, events.length
775
- assert_equal 'geoip.access', events[0][0] # tag
776
- assert_equal 'US', events[0][2]['origin_country']
777
- assert_equal 'US', events[0][2]['dest_country']
778
- end
779
-
780
- def test_emit_nested_attr
781
- d1 = create_driver(%[
782
- backend_library geoip
783
- geoip_lookup_key host.ip
784
- enable_key_city geoip_city
785
- tag geoip.${tag[1]}
786
- ])
787
- d1.run(default_tag: 'input.access') do
788
- d1.feed({'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip'})
789
- d1.feed({'message' => 'missing field'})
790
- end
791
- events = d1.events
792
- assert_equal 2, events.length
793
- assert_equal 'geoip.access', events[0][0] # tag
794
- assert_equal 'Mountain View', events[0][2]['geoip_city']
795
- assert_equal nil, events[1][2]['geoip_city']
796
- end
797
-
798
- def test_emit_with_unknown_address
799
- d1 = create_driver(%[
800
- backend_library geoip
801
- geoip_lookup_key host
802
- <record>
803
- geoip_city ${city['host']}
804
- geopoint [${longitude['host']}, ${latitude['host']}]
805
- </record>
806
- skip_adding_null_record false
807
- tag geoip.${tag[1]}
808
- ], syntax: :v0)
809
- d1.run(default_tag: 'input.access') do
810
- # 203.0.113.1 is a test address described in RFC5737
811
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
812
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
813
- end
814
- events = d1.events
815
- assert_equal 2, events.length
816
- assert_equal 'geoip.access', events[0][0] # tag
817
- assert_equal nil, events[0][2]['geoip_city']
818
- assert_equal 'geoip.access', events[1][0] # tag
819
- assert_equal nil, events[1][2]['geoip_city']
820
- end
821
-
822
- def test_emit_with_skip_unknown_address
823
- d1 = create_driver(%[
824
- backend_library geoip
825
- geoip_lookup_key host
826
- <record>
827
- geoip_city ${city['host']}
828
- geopoint [${longitude['host']}, ${latitude['host']}]
829
- </record>
830
- skip_adding_null_record true
831
- tag geoip.${tag[1]}
832
- ], syntax: :v0)
833
- d1.run(default_tag: 'input.access') do
834
- # 203.0.113.1 is a test address described in RFC5737
835
- d1.feed({'host' => '203.0.113.1', 'message' => 'invalid ip'})
836
- d1.feed({'host' => '0', 'message' => 'invalid ip'})
837
- d1.feed({'host' => '66.102.3.80', 'message' => 'google bot'})
838
- end
839
- events = d1.events
840
- assert_equal 3, events.length
841
- assert_equal 'geoip.access', events[0][0] # tag
842
- assert_equal nil, events[0][2]['geoip_city']
843
- assert_equal nil, events[0][2]['geopoint']
844
- assert_equal 'geoip.access', events[1][0] # tag
845
- assert_equal nil, events[1][2]['geoip_city']
846
- assert_equal nil, events[1][2]['geopoint']
847
- assert_equal 'Mountain View', events[2][2]['geoip_city']
848
- assert_equal [-122.05740356445312, 37.4192008972168], events[2][2]['geopoint']
849
- end
850
-
851
- def test_emit_multiple_key
852
- d1 = create_driver(%[
853
- backend_library geoip
854
- geoip_lookup_key from.ip, to.ip
855
- enable_key_city from_city, to_city
856
- tag geoip.${tag[1]}
857
- ])
858
- d1.run(default_tag: 'input.access') do
859
- d1.feed({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}})
860
- d1.feed({'message' => 'missing field'})
861
- end
862
- events = d1.events
863
- assert_equal 2, events.length
864
- assert_equal 'geoip.access', events[0][0] # tag
865
- assert_equal 'Mountain View', events[0][2]['from_city']
866
- assert_equal 'Tokorozawa', events[0][2]['to_city']
867
- assert_equal nil, events[1][2]['from_city']
868
- assert_equal nil, events[1][2]['to_city']
869
- end
870
-
871
- def test_emit_multiple_key_multiple_record
872
- d1 = create_driver(%[
873
- backend_library geoip
874
- geoip_lookup_key from.ip, to.ip
875
- enable_key_city from_city, to_city
876
- enable_key_country_name from_country, to_country
877
- tag geoip.${tag[1]}
878
- ])
879
- d1.run(default_tag: 'input.access') do
880
- d1.feed({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}})
881
- d1.feed({'from' => {'ip' => '66.102.3.80'}})
882
- d1.feed({'message' => 'missing field'})
883
- end
884
- events = d1.events
885
- assert_equal 3, events.length
886
- assert_equal 'geoip.access', events[0][0] # tag
887
- assert_equal 'Mountain View', events[0][2]['from_city']
888
- assert_equal 'United States', events[0][2]['from_country']
889
- assert_equal 'Tokorozawa', events[0][2]['to_city']
890
- assert_equal 'Japan', events[0][2]['to_country']
891
-
892
- assert_equal 'Mountain View', events[1][2]['from_city']
893
- assert_equal 'United States', events[1][2]['from_country']
894
- assert_equal nil, events[1][2]['to_city']
895
- assert_equal nil, events[1][2]['to_country']
896
-
897
- assert_equal nil, events[2][2]['from_city']
898
- assert_equal nil, events[2][2]['from_country']
899
- assert_equal nil, events[2][2]['to_city']
900
- assert_equal nil, events[2][2]['to_country']
901
- end
902
-
903
- def test_emit_record_directive
904
- d1 = create_driver(%[
905
- backend_library geoip
906
- geoip_lookup_key from.ip
907
- <record>
908
- from_city ${city['from.ip']}
909
- from_country ${country_name['from.ip']}
910
- latitude ${latitude['from.ip']}
911
- longitude ${longitude['from.ip']}
912
- float_concat ${latitude['from.ip']},${longitude['from.ip']}
913
- float_array [${longitude['from.ip']}, ${latitude['from.ip']}]
914
- float_nest { "lat" : ${latitude['from.ip']}, "lon" : ${longitude['from.ip']}}
915
- string_concat ${latitude['from.ip']},${longitude['from.ip']}
916
- string_array [${city['from.ip']}, ${country_name['from.ip']}]
917
- string_nest { "city" : ${city['from.ip']}, "country_name" : ${country_name['from.ip']}}
918
- unknown_city ${city['unknown_key']}
919
- undefined ${city['undefined']}
920
- broken_array1 [${longitude['from.ip']}, ${latitude['undefined']}]
921
- broken_array2 [${longitude['undefined']}, ${latitude['undefined']}]
922
- </record>
923
- tag geoip.${tag[1]}
924
- ], syntax: :v0)
925
- d1.run(default_tag: 'input.access') do
926
- d1.feed({'from' => {'ip' => '66.102.3.80'}})
927
- d1.feed({'message' => 'missing field'})
928
- end
929
- events = d1.events
930
- assert_equal 2, events.length
931
-
932
- assert_equal 'geoip.access', events[0][0] # tag
933
- assert_equal 'Mountain View', events[0][2]['from_city']
934
- assert_equal 'United States', events[0][2]['from_country']
935
- assert_equal 37.4192008972168, events[0][2]['latitude']
936
- assert_equal -122.05740356445312, events[0][2]['longitude']
937
- assert_equal '37.4192008972168,-122.05740356445312', events[0][2]['float_concat']
938
- assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['float_array']
939
- float_nest = {"lat" => 37.4192008972168, "lon" => -122.05740356445312 }
940
- assert_equal float_nest, events[0][2]['float_nest']
941
- assert_equal '37.4192008972168,-122.05740356445312', events[0][2]['string_concat']
942
- assert_equal ["Mountain View", "United States"], events[0][2]['string_array']
943
- string_nest = {"city" => "Mountain View", "country_name" => "United States"}
944
- assert_equal string_nest, events[0][2]['string_nest']
945
- assert_equal nil, events[0][2]['unknown_city']
946
- assert_equal nil, events[0][2]['undefined']
947
- assert_equal [-122.05740356445312, nil], events[0][2]['broken_array1']
948
- assert_equal [nil, nil], events[0][2]['broken_array2']
949
-
950
- assert_equal nil, events[1][2]['from_city']
951
- assert_equal nil, events[1][2]['from_country']
952
- assert_equal nil, events[1][2]['latitude']
953
- assert_equal nil, events[1][2]['longitude']
954
- assert_equal ',', events[1][2]['float_concat']
955
- assert_equal [nil, nil], events[1][2]['float_array']
956
- float_nest = {"lat" => nil, "lon" => nil}
957
- assert_equal float_nest, events[1][2]['float_nest']
958
- assert_equal ',', events[1][2]['string_concat']
959
- assert_equal [nil, nil], events[1][2]['string_array']
960
- string_nest = {"city" => nil, "country_name" => nil}
961
- assert_equal string_nest, events[1][2]['string_nest']
962
- assert_equal nil, events[1][2]['unknown_city']
963
- assert_equal nil, events[1][2]['undefined']
964
- assert_equal [nil, nil], events[1][2]['broken_array1']
965
- assert_equal [nil, nil], events[1][2]['broken_array2']
966
- end
967
-
968
- def test_emit_record_directive_multiple_record
969
- d1 = create_driver(%[
970
- backend_library geoip
971
- geoip_lookup_key from.ip, to.ip
972
- <record>
973
- from_city ${city['from.ip']}
974
- to_city ${city['to.ip']}
975
- from_country ${country_name['from.ip']}
976
- to_country ${country_name['to.ip']}
977
- string_array [${country_name['from.ip']}, ${country_name['to.ip']}]
978
- </record>
979
- tag geoip.${tag[1]}
980
- ], syntax: :v0)
981
- d1.run(default_tag: 'input.access') do
982
- d1.feed({'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}})
983
- d1.feed({'message' => 'missing field'})
984
- end
985
- events = d1.events
986
- assert_equal 2, events.length
987
-
988
- assert_equal 'geoip.access', events[0][0] # tag
989
- assert_equal 'Mountain View', events[0][2]['from_city']
990
- assert_equal 'United States', events[0][2]['from_country']
991
- assert_equal 'Tokorozawa', events[0][2]['to_city']
992
- assert_equal 'Japan', events[0][2]['to_country']
993
- assert_equal ['United States','Japan'], events[0][2]['string_array']
994
-
995
- assert_equal nil, events[1][2]['from_city']
996
- assert_equal nil, events[1][2]['to_city']
997
- assert_equal nil, events[1][2]['from_country']
998
- assert_equal nil, events[1][2]['to_country']
999
- assert_equal [nil, nil], events[1][2]['string_array']
1000
- end
1001
-
1002
- def config_quoted_record
1003
- %[
1004
- backend_library geoip
1005
- geoip_lookup_key host
1006
- <record>
1007
- location_properties '{ "country_code" : "${country_code["host"]}", "lat": ${latitude["host"]}, "lon": ${longitude["host"]} }'
1008
- location_string ${latitude['host']},${longitude['host']}
1009
- location_string2 ${country_code["host"]}
1010
- location_array "[${longitude['host']},${latitude['host']}]"
1011
- location_array2 '[${longitude["host"]},${latitude["host"]}]'
1012
- peculiar_pattern '[GEOIP] message => {"lat":${latitude["host"]}, "lon":${longitude["host"]}}'
1013
- </record>
1014
- tag geoip.${tag[1]}
1015
- ]
1016
- end
1017
-
1018
- def test_emit_quoted_record
1019
- d1 = create_driver(config_quoted_record)
1020
- d1.run(default_tag: 'input.access') do
1021
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
1022
- end
1023
- events = d1.events
1024
- assert_equal 1, events.length
1025
- assert_equal 'geoip.access', events[0][0] # tag
1026
- location_properties = { "country_code" => "US", "lat" => 37.4192008972168, "lon"=> -122.05740356445312 }
1027
- assert_equal location_properties, events[0][2]['location_properties']
1028
- assert_equal '37.4192008972168,-122.05740356445312', events[0][2]['location_string']
1029
- assert_equal 'US', events[0][2]['location_string2']
1030
- assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['location_array']
1031
- assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['location_array2']
1032
- assert_equal '[GEOIP] message => {"lat":37.4192008972168, "lon":-122.05740356445312}', events[0][2]['peculiar_pattern']
1033
- end
1034
-
1035
- def test_emit_v1_config_compatibility
1036
- d1 = create_driver(config_quoted_record)
1037
- d1.run(default_tag: 'input.access') do
1038
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
1039
- end
1040
- events = d1.events
1041
- assert_equal 1, events.length
1042
- assert_equal 'geoip.access', events[0][0] # tag
1043
- location_properties = { "country_code" => "US", "lat" => 37.4192008972168, "lon"=> -122.05740356445312 }
1044
- assert_equal location_properties, events[0][2]['location_properties']
1045
- assert_equal '37.4192008972168,-122.05740356445312', events[0][2]['location_string']
1046
- assert_equal 'US', events[0][2]['location_string2']
1047
- assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['location_array']
1048
- assert_equal [-122.05740356445312, 37.4192008972168], events[0][2]['location_array2']
1049
- assert_equal '[GEOIP] message => {"lat":37.4192008972168, "lon":-122.05740356445312}', events[0][2]['peculiar_pattern']
1050
- end
1051
-
1052
- def test_emit_multiline_v1_config
1053
- d1 = create_driver(%[
1054
- backend_library geoip
1055
- geoip_lookup_key host
1056
- <record>
1057
- location_properties {
1058
- "city": "${city['host']}",
1059
- "country_code": "${country_code['host']}",
1060
- "latitude": "${latitude['host']}",
1061
- "longitude": "${longitude['host']}"
1062
- }
1063
- </record>
1064
- tag geoip.${tag[1]}
1065
- ])
1066
- d1.run(default_tag: 'input.access') do
1067
- d1.feed({'host' => '66.102.3.80', 'message' => 'valid ip'})
1068
- end
1069
- events = d1.events
1070
- assert_equal 1, events.length
1071
- assert_equal 'geoip.access', events[0][0] # tag
1072
- location_properties = { "city"=>"Mountain View", "country_code"=>"US", "latitude"=>37.4192008972168, "longitude"=>-122.05740356445312 }
1073
- assert_equal location_properties, events[0][2]['location_properties']
1074
- end
1075
- end
1076
- end