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.
- checksums.yaml +5 -5
- data/.github/ISSUE_TEMPLATE.md +19 -0
- data/.travis.yml +1 -1
- data/README.md +203 -239
- data/docker-compose.yml +12 -5
- data/dockerfiles/Dockerfile-ruby2.1 +1 -1
- data/dockerfiles/Dockerfile-ruby2.2 +1 -1
- data/dockerfiles/Dockerfile-ruby2.3 +1 -1
- data/dockerfiles/Dockerfile-ruby2.4 +1 -1
- data/dockerfiles/Dockerfile-ruby2.5 +8 -0
- data/fluent-plugin-geoip.gemspec +2 -1
- data/lib/fluent/plugin/filter_geoip.rb +196 -11
- data/test/helper.rb +1 -0
- data/test/plugin/test_filter_geoip.rb +296 -107
- data/utils/dump.rb +27 -0
- metadata +20 -8
- data/lib/fluent/plugin/geoip.rb +0 -174
- data/lib/fluent/plugin/out_geoip.rb +0 -51
- data/test/plugin/test_out_geoip.rb +0 -1076
data/docker-compose.yml
CHANGED
@@ -1,31 +1,38 @@
|
|
1
|
-
version: "
|
1
|
+
version: "3"
|
2
2
|
services:
|
3
|
+
test-ruby2.5:
|
4
|
+
build:
|
5
|
+
context: .
|
6
|
+
dockerfile: dockerfiles/Dockerfile-ruby2.5
|
7
|
+
env_file:
|
8
|
+
- env
|
9
|
+
command: tail -f /dev/null
|
3
10
|
test-ruby2.4:
|
4
11
|
build:
|
5
12
|
context: .
|
6
13
|
dockerfile: dockerfiles/Dockerfile-ruby2.4
|
7
14
|
env_file:
|
8
15
|
- env
|
9
|
-
command:
|
16
|
+
command: tail -f /dev/null
|
10
17
|
test-ruby2.3:
|
11
18
|
build:
|
12
19
|
context: .
|
13
20
|
dockerfile: dockerfiles/Dockerfile-ruby2.3
|
14
21
|
env_file:
|
15
22
|
- env
|
16
|
-
command:
|
23
|
+
command: tail -f /dev/null
|
17
24
|
test-ruby2.2:
|
18
25
|
build:
|
19
26
|
context: .
|
20
27
|
dockerfile: dockerfiles/Dockerfile-ruby2.2
|
21
28
|
env_file:
|
22
29
|
- env
|
23
|
-
command:
|
30
|
+
command: tail -f /dev/null
|
24
31
|
test-ruby2.1:
|
25
32
|
build:
|
26
33
|
context: .
|
27
34
|
dockerfile: dockerfiles/Dockerfile-ruby2.1
|
28
35
|
env_file:
|
29
36
|
- env
|
30
|
-
command:
|
37
|
+
command: tail -f /dev/null
|
31
38
|
|
@@ -2,7 +2,7 @@ FROM ruby:2.1-alpine
|
|
2
2
|
|
3
3
|
ENV BUNDLE_GEMFILE=$BUNDLE_GEMFILE
|
4
4
|
|
5
|
-
RUN apk --no-cache --update add build-base ruby-dev libc6-compat
|
5
|
+
RUN apk --no-cache --update add build-base automake autoconf libtool ruby-dev libc6-compat geoip-dev git
|
6
6
|
|
7
7
|
WORKDIR /app
|
8
8
|
COPY . .
|
@@ -2,7 +2,7 @@ FROM ruby:2.2-alpine
|
|
2
2
|
|
3
3
|
ENV BUNDLE_GEMFILE=$BUNDLE_GEMFILE
|
4
4
|
|
5
|
-
RUN apk --no-cache --update add build-base ruby-dev libc6-compat
|
5
|
+
RUN apk --no-cache --update add build-base automake autoconf libtool ruby-dev libc6-compat geoip-dev git
|
6
6
|
|
7
7
|
WORKDIR /app
|
8
8
|
COPY . .
|
@@ -2,7 +2,7 @@ FROM ruby:2.3-alpine
|
|
2
2
|
|
3
3
|
ENV BUNDLE_GEMFILE=$BUNDLE_GEMFILE
|
4
4
|
|
5
|
-
RUN apk --no-cache --update add build-base ruby-dev libc6-compat
|
5
|
+
RUN apk --no-cache --update add build-base automake autoconf libtool ruby-dev libc6-compat geoip-dev git
|
6
6
|
|
7
7
|
WORKDIR /app
|
8
8
|
COPY . .
|
@@ -2,7 +2,7 @@ FROM ruby:2.4-alpine
|
|
2
2
|
|
3
3
|
ENV BUNDLE_GEMFILE=$BUNDLE_GEMFILE
|
4
4
|
|
5
|
-
RUN apk --no-cache --update add build-base ruby-dev libc6-compat
|
5
|
+
RUN apk --no-cache --update add build-base automake autoconf libtool ruby-dev libc6-compat geoip-dev git
|
6
6
|
|
7
7
|
WORKDIR /app
|
8
8
|
COPY . .
|
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.3.2"
|
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.}
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_development_dependency "rake"
|
21
21
|
spec.add_development_dependency "appraisal"
|
22
22
|
spec.add_development_dependency "test-unit", ">= 3.1.0"
|
23
|
+
spec.add_development_dependency "test-unit-rr"
|
23
24
|
spec.add_development_dependency "geoip2_compat"
|
24
25
|
|
25
26
|
spec.add_runtime_dependency "fluentd", [">= 0.14.8", "< 2"]
|
@@ -1,34 +1,219 @@
|
|
1
1
|
require 'fluent/plugin/filter'
|
2
|
-
|
2
|
+
|
3
|
+
require 'geoip'
|
4
|
+
require 'yajl'
|
5
|
+
unless {}.respond_to?(:dig)
|
6
|
+
begin
|
7
|
+
# backport_dig is faster than dig_rb so prefer backport_dig.
|
8
|
+
# And Fluentd v1.0.1 uses backport_dig
|
9
|
+
require 'backport_dig'
|
10
|
+
rescue LoadError
|
11
|
+
require 'dig_rb'
|
12
|
+
end
|
13
|
+
end
|
3
14
|
|
4
15
|
module Fluent::Plugin
|
5
16
|
class GeoipFilter < Fluent::Plugin::Filter
|
6
17
|
Fluent::Plugin.register_filter('geoip', self)
|
7
18
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
19
|
+
BACKEND_LIBRARIES = [:geoip, :geoip2_compat, :geoip2_c]
|
20
|
+
|
21
|
+
REGEXP_PLACEHOLDER_SINGLE = /^\$\{
|
22
|
+
(?<geoip_key>-?[^\[\]]+)
|
23
|
+
\[
|
24
|
+
(?:(?<dq>")|(?<sq>'))
|
25
|
+
(?<record_key>-?(?(<dq>)[^"{}]+|[^'{}]+))
|
26
|
+
(?(<dq>)"|')
|
27
|
+
\]
|
28
|
+
\}$/x
|
29
|
+
REGEXP_PLACEHOLDER_SCAN = /['"]?(\$\{[^\}]+?\})['"]?/
|
12
30
|
|
13
|
-
|
31
|
+
GEOIP_KEYS = %w(city latitude longitude country_code3 country_code country_name dma_code area_code region)
|
32
|
+
GEOIP2_COMPAT_KEYS = %w(city country_code country_name latitude longitude postal_code region region_name)
|
14
33
|
|
15
|
-
|
34
|
+
helpers :compat_parameters, :inject, :record_accessor
|
16
35
|
|
17
|
-
config_param :
|
36
|
+
config_param :geoip_database, :string, default: File.expand_path('../../../data/GeoLiteCity.dat', __dir__)
|
37
|
+
config_param :geoip2_database, :string, default: File.expand_path('../../../data/GeoLite2-City.mmdb', __dir__)
|
38
|
+
config_param :geoip_lookup_keys, :array, value_type: :string, default: ["host"]
|
39
|
+
config_param :geoip_lookup_key, :string, default: nil, deprecated: "Use geoip_lookup_keys instead"
|
40
|
+
config_param :skip_adding_null_record, :bool, default: false
|
18
41
|
|
19
|
-
|
42
|
+
config_set_default :@log_level, "warn"
|
43
|
+
|
44
|
+
config_param :backend_library, :enum, list: BACKEND_LIBRARIES, default: :geoip2_c
|
20
45
|
|
21
46
|
def configure(conf)
|
47
|
+
compat_parameters_convert(conf, :inject)
|
22
48
|
super
|
23
|
-
|
49
|
+
|
50
|
+
@map = {}
|
51
|
+
if @geoip_lookup_key
|
52
|
+
@geoip_lookup_keys = @geoip_lookup_key.split(/\s*,\s*/)
|
53
|
+
end
|
54
|
+
|
55
|
+
@geoip_lookup_keys.each do |key|
|
56
|
+
if key.include?(".") && !key.start_with?("$")
|
57
|
+
$log.warn("#{key} is not treated as nested attributes")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@geoip_lookup_accessors = @geoip_lookup_keys.map {|key| [key, record_accessor_create(key)] }.to_h
|
61
|
+
|
62
|
+
if conf.keys.any? {|k| k =~ /^enable_key_/ }
|
63
|
+
raise Fluent::ConfigError, "geoip: 'enable_key_*' config format is obsoleted. use <record></record> directive instead."
|
64
|
+
end
|
65
|
+
|
66
|
+
# <record></record> directive
|
67
|
+
conf.elements.select { |element| element.name == 'record' }.each { |element|
|
68
|
+
element.each_pair { |k, v|
|
69
|
+
element.has_key?(k) # to suppress unread configuration warning
|
70
|
+
v = v[1..v.size-2] if quoted_value?(v)
|
71
|
+
@map[k] = v
|
72
|
+
validate_json = Proc.new {
|
73
|
+
begin
|
74
|
+
dummy_text = Yajl::Encoder.encode('dummy_text')
|
75
|
+
Yajl::Parser.parse(v.gsub(REGEXP_PLACEHOLDER_SCAN, dummy_text))
|
76
|
+
rescue Yajl::ParseError => e
|
77
|
+
message = "geoip: failed to parse '#{v}' as json."
|
78
|
+
log.error message, error: e
|
79
|
+
raise Fluent::ConfigError, message
|
80
|
+
end
|
81
|
+
}
|
82
|
+
validate_json.call if json?(v.tr('\'"\\', ''))
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
@placeholder_keys = @map.values.join.scan(REGEXP_PLACEHOLDER_SCAN).map{|placeholder| placeholder[0] }.uniq
|
87
|
+
@placeholder_keys.each do |key|
|
88
|
+
m = key.match(REGEXP_PLACEHOLDER_SINGLE)
|
89
|
+
raise Fluent::ConfigError, "Invalid placeholder attributes: #{key}" unless m
|
90
|
+
geoip_key = m[:geoip_key]
|
91
|
+
case @backend_library
|
92
|
+
when :geoip
|
93
|
+
raise Fluent::ConfigError, "#{@backend_library}: unsupported key #{geoip_key}" unless GEOIP_KEYS.include?(geoip_key)
|
94
|
+
when :geoip2_compat
|
95
|
+
raise Fluent::ConfigError, "#{@backend_library}: unsupported key #{geoip_key}" unless GEOIP2_COMPAT_KEYS.include?(geoip_key)
|
96
|
+
when :geoip2_c
|
97
|
+
# Nothing to do.
|
98
|
+
# We cannot define supported key(s) before we fetch values from GeoIP2 database
|
99
|
+
# because geoip2_c can fetch any fields in GeoIP2 database.
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
@geoip = load_database
|
24
104
|
end
|
25
105
|
|
26
106
|
def filter(tag, time, record)
|
27
|
-
filtered_record =
|
107
|
+
filtered_record = add_geoip_field(record)
|
28
108
|
if filtered_record
|
29
109
|
record = filtered_record
|
30
110
|
end
|
111
|
+
record = inject_values_to_record(tag, time, record)
|
31
112
|
record
|
32
113
|
end
|
114
|
+
|
115
|
+
def multi_workers_ready?
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def add_geoip_field(record)
|
122
|
+
placeholder = create_placeholder(geolocate(get_address(record)))
|
123
|
+
return record if @skip_adding_null_record && placeholder.values.first.nil?
|
124
|
+
@map.each do |record_key, value|
|
125
|
+
if value.match(REGEXP_PLACEHOLDER_SINGLE) #|| value.match(REGEXP_PLACEHOLDER_BRACKET_SINGLE)
|
126
|
+
rewrited = placeholder[value]
|
127
|
+
elsif json?(value)
|
128
|
+
rewrited = value.gsub(REGEXP_PLACEHOLDER_SCAN) {|match|
|
129
|
+
match = match[1..match.size-2] if quoted_value?(match)
|
130
|
+
Yajl::Encoder.encode(placeholder[match])
|
131
|
+
}
|
132
|
+
rewrited = parse_json(rewrited)
|
133
|
+
else
|
134
|
+
rewrited = value.gsub(REGEXP_PLACEHOLDER_SCAN, placeholder)
|
135
|
+
end
|
136
|
+
record[record_key] = rewrited
|
137
|
+
end
|
138
|
+
record
|
139
|
+
end
|
140
|
+
|
141
|
+
def json?(text)
|
142
|
+
text.match(/^\[.+\]$/) || text.match(/^\{.+\}$/)
|
143
|
+
end
|
144
|
+
|
145
|
+
def quoted_value?(text)
|
146
|
+
# to improbe compatibility with fluentd v1-config
|
147
|
+
text.match(/(^'.+'$|^".+"$)/)
|
148
|
+
end
|
149
|
+
|
150
|
+
def parse_json(message)
|
151
|
+
begin
|
152
|
+
return Yajl::Parser.parse(message)
|
153
|
+
rescue Yajl::ParseError => e
|
154
|
+
log.info "geoip: failed to parse '#{message}' as json.", error_class: e.class, error: e.message
|
155
|
+
return nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def get_address(record)
|
160
|
+
address = {}
|
161
|
+
@geoip_lookup_accessors.each do |field, accessor|
|
162
|
+
address[field] = accessor.call(record)
|
163
|
+
end
|
164
|
+
address
|
165
|
+
end
|
166
|
+
|
167
|
+
def geolocate(addresses)
|
168
|
+
geodata = {}
|
169
|
+
addresses.each do |field, ip|
|
170
|
+
geo = nil
|
171
|
+
if ip
|
172
|
+
if ip.empty?
|
173
|
+
log.warn "#{field} is empty string"
|
174
|
+
else
|
175
|
+
geo = if @geoip.respond_to?(:look_up)
|
176
|
+
@geoip.look_up(ip)
|
177
|
+
else
|
178
|
+
@geoip.lookup(ip)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
geodata[field] = geo
|
183
|
+
end
|
184
|
+
geodata
|
185
|
+
end
|
186
|
+
|
187
|
+
def create_placeholder(geodata)
|
188
|
+
placeholder = {}
|
189
|
+
@placeholder_keys.each do |placeholder_key|
|
190
|
+
position = placeholder_key.match(REGEXP_PLACEHOLDER_SINGLE)
|
191
|
+
next if position.nil? or geodata[position[:record_key]].nil?
|
192
|
+
keys = [position[:record_key]] + position[:geoip_key].split('.').map(&:to_sym)
|
193
|
+
value = geodata.dig(*keys)
|
194
|
+
value = if [:latitude, :longitude].include?(keys.last)
|
195
|
+
value || 0.0
|
196
|
+
else
|
197
|
+
value
|
198
|
+
end
|
199
|
+
placeholder[placeholder_key] = value
|
200
|
+
end
|
201
|
+
placeholder
|
202
|
+
end
|
203
|
+
|
204
|
+
def load_database
|
205
|
+
case @backend_library
|
206
|
+
when :geoip
|
207
|
+
::GeoIP::City.new(@geoip_database, :memory, false)
|
208
|
+
when :geoip2_compat
|
209
|
+
require 'geoip2_compat'
|
210
|
+
GeoIP2Compat.new(@geoip2_database)
|
211
|
+
when :geoip2_c
|
212
|
+
require 'geoip2'
|
213
|
+
GeoIP2::Database.new(@geoip2_database)
|
214
|
+
end
|
215
|
+
rescue LoadError
|
216
|
+
raise Fluent::ConfigError, "You must install #{@backend_library} gem."
|
217
|
+
end
|
33
218
|
end
|
34
219
|
end
|
data/test/helper.rb
CHANGED
@@ -9,8 +9,10 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
CONFIG = %[
|
12
|
-
|
13
|
-
|
12
|
+
geoip_lookup_keys host
|
13
|
+
<record>
|
14
|
+
geoip_city ${city.names.en['host']}
|
15
|
+
</record>
|
14
16
|
]
|
15
17
|
|
16
18
|
def create_driver(conf = CONFIG, syntax: :v1)
|
@@ -19,6 +21,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
19
21
|
|
20
22
|
def filter(config, messages, syntax: :v1)
|
21
23
|
d = create_driver(config, syntax: syntax)
|
24
|
+
yield d if block_given?
|
22
25
|
d.run(default_tag: "input.access") {
|
23
26
|
messages.each {|message|
|
24
27
|
d.feed(@time, message)
|
@@ -27,6 +30,15 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
27
30
|
d.filtered_records
|
28
31
|
end
|
29
32
|
|
33
|
+
def setup_geoip_mock(d)
|
34
|
+
plugin = d.instance
|
35
|
+
db = Object.new
|
36
|
+
def db.lookup(ip)
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
plugin.instance_variable_set(:@geoip, db)
|
40
|
+
end
|
41
|
+
|
30
42
|
sub_test_case "configure" do
|
31
43
|
test "empty" do
|
32
44
|
assert_nothing_raised {
|
@@ -34,42 +46,27 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
34
46
|
}
|
35
47
|
end
|
36
48
|
|
37
|
-
test "
|
49
|
+
test "obsoleted configuration" do
|
38
50
|
assert_raise(Fluent::ConfigError) {
|
39
|
-
create_driver('
|
51
|
+
create_driver('enable_key_city geoip_city')
|
40
52
|
}
|
41
53
|
end
|
42
54
|
|
43
|
-
test "
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
test "multiple key config" do
|
51
|
-
d = create_driver %[
|
52
|
-
geoip_lookup_key from.ip, to.ip
|
53
|
-
enable_key_city from_city, to_city
|
55
|
+
test "deprecated configuration geoip_lookup_key" do
|
56
|
+
conf = %[
|
57
|
+
geoip_lookup_key host,ip
|
58
|
+
<record>
|
59
|
+
geoip_city ${city['host']}
|
60
|
+
</record>
|
54
61
|
]
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
test "multiple key config (bad configure)" do
|
59
|
-
assert_raise(Fluent::ConfigError) {
|
60
|
-
create_driver %[
|
61
|
-
geoip_lookup_key from.ip, to.ip
|
62
|
-
enable_key_city from_city
|
63
|
-
enable_key_region from_region
|
64
|
-
]
|
65
|
-
}
|
62
|
+
d = create_driver(conf)
|
63
|
+
assert_equal(["host", "ip"], d.instance.geoip_lookup_keys)
|
66
64
|
end
|
67
65
|
|
68
66
|
test "invalid json structure w/ Ruby hash like" do
|
69
|
-
|
70
67
|
assert_raise(Fluent::ConfigParseError) {
|
71
68
|
create_driver %[
|
72
|
-
|
69
|
+
geoip_lookup_keys host
|
73
70
|
<record>
|
74
71
|
invalid_json {"foo" => 123}
|
75
72
|
</record>
|
@@ -80,7 +77,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
80
77
|
test "invalid json structure w/ unquoted string literal" do
|
81
78
|
assert_raise(Fluent::ConfigParseError) {
|
82
79
|
create_driver %[
|
83
|
-
|
80
|
+
geoip_lookup_keys host
|
84
81
|
<record>
|
85
82
|
invalid_json {"foo" : string, "bar" : 123}
|
86
83
|
</record>
|
@@ -88,6 +85,49 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
88
85
|
}
|
89
86
|
end
|
90
87
|
|
88
|
+
test "dotted key is not treated as nested attributes" do
|
89
|
+
mock($log).warn("host.ip is not treated as nested attributes")
|
90
|
+
create_driver %[
|
91
|
+
geoip_lookup_keys host.ip
|
92
|
+
<record>
|
93
|
+
city ${city.names.en['host.ip']}
|
94
|
+
</record>
|
95
|
+
]
|
96
|
+
end
|
97
|
+
|
98
|
+
test "nested attributes bracket style" do
|
99
|
+
mock($log).warn(anything).times(0)
|
100
|
+
create_driver %[
|
101
|
+
geoip_lookup_keys $["host"]["ip"]
|
102
|
+
<record>
|
103
|
+
geoip_city ${city.names.en['$["host"]["ip"]']}
|
104
|
+
</record>
|
105
|
+
]
|
106
|
+
end
|
107
|
+
|
108
|
+
test "nested attributes dot style" do
|
109
|
+
mock($log).warn(anything).times(0)
|
110
|
+
create_driver %[
|
111
|
+
geoip_lookup_keys $.host.ip
|
112
|
+
<record>
|
113
|
+
geoip_city ${city['$.host.ip']}
|
114
|
+
</record>
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
test "invalid placeholder attributes" do
|
119
|
+
assert_raise(Fluent::ConfigError) do
|
120
|
+
create_driver %[
|
121
|
+
geoip_lookup_keys host
|
122
|
+
backend_library geoip2_c
|
123
|
+
|
124
|
+
<record>
|
125
|
+
geoip.city_name ${city.names.en["host]}
|
126
|
+
</record>
|
127
|
+
]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
91
131
|
data(geoip: "geoip",
|
92
132
|
geoip2_compat: "geoip2_compat")
|
93
133
|
test "unsupported key" do |backend|
|
@@ -129,7 +169,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
129
169
|
def test_filter_with_dot_key
|
130
170
|
config = %[
|
131
171
|
backend_library geoip2_c
|
132
|
-
|
172
|
+
geoip_lookup_keys ip.origin, ip.dest
|
133
173
|
<record>
|
134
174
|
origin_country ${country.iso_code['ip.origin']}
|
135
175
|
dest_country ${country.iso_code['ip.dest']}
|
@@ -149,7 +189,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
149
189
|
def test_filter_with_unknown_address
|
150
190
|
config = %[
|
151
191
|
backend_library geoip2_c
|
152
|
-
|
192
|
+
geoip_lookup_keys host
|
153
193
|
<record>
|
154
194
|
geoip_city ${city.names.en['host']}
|
155
195
|
geopoint [${location.longitude['host']}, ${location.latitude['host']}]
|
@@ -169,10 +209,30 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
169
209
|
assert_equal(expected, filtered)
|
170
210
|
end
|
171
211
|
|
212
|
+
def test_filter_with_empty_string
|
213
|
+
config = %[
|
214
|
+
backend_library geoip2_c
|
215
|
+
geoip_lookup_keys host
|
216
|
+
<record>
|
217
|
+
geoip_city '${city.names.en["host"]}'
|
218
|
+
geopoint '[${location.longitude["host"]}, ${location.latitude["host"]}]'
|
219
|
+
</record>
|
220
|
+
skip_adding_null_record false
|
221
|
+
]
|
222
|
+
messages = [
|
223
|
+
{'host' => '', 'message' => 'empty string ip'},
|
224
|
+
]
|
225
|
+
expected = [
|
226
|
+
{'host' => '', 'message' => 'empty string ip', 'geoip_city' => nil, 'geopoint' => [nil, nil]},
|
227
|
+
]
|
228
|
+
filtered = filter(config, messages)
|
229
|
+
assert_equal(expected, filtered)
|
230
|
+
end
|
231
|
+
|
172
232
|
def test_filter_with_skip_unknown_address
|
173
233
|
config = %[
|
174
234
|
backend_library geoip2_c
|
175
|
-
|
235
|
+
geoip_lookup_keys host
|
176
236
|
<record>
|
177
237
|
geoip_city ${city.names.en['host']}
|
178
238
|
geopoint [${location.longitude['host']}, ${location.latitude['host']}]
|
@@ -198,21 +258,21 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
198
258
|
def test_filter_record_directive
|
199
259
|
config = %[
|
200
260
|
backend_library geoip2_c
|
201
|
-
|
261
|
+
geoip_lookup_keys $.from.ip
|
202
262
|
<record>
|
203
|
-
from_city ${city.names.en['from.ip']}
|
204
|
-
from_country ${country.names.en['from.ip']}
|
205
|
-
latitude ${location.latitude['from.ip']}
|
206
|
-
longitude ${location.longitude['from.ip']}
|
207
|
-
float_concat ${location.latitude['from.ip']},${location.longitude['from.ip']}
|
208
|
-
float_array [${location.longitude['from.ip']}, ${location.latitude['from.ip']}]
|
209
|
-
float_nest { "lat" : ${location.latitude['from.ip']}, "lon" : ${location.longitude['from.ip']}}
|
210
|
-
string_concat ${city.names.en['from.ip']},${country.names.en['from.ip']}
|
211
|
-
string_array [${city.names.en['from.ip']}, ${country.names.en['from.ip']}]
|
212
|
-
string_nest { "city" : ${city.names.en['from.ip']}, "country_name" : ${country.names.en['from.ip']}}
|
263
|
+
from_city ${city.names.en['$.from.ip']}
|
264
|
+
from_country ${country.names.en['$.from.ip']}
|
265
|
+
latitude ${location.latitude['$.from.ip']}
|
266
|
+
longitude ${location.longitude['$.from.ip']}
|
267
|
+
float_concat ${location.latitude['$.from.ip']},${location.longitude['$.from.ip']}
|
268
|
+
float_array [${location.longitude['$.from.ip']}, ${location.latitude['$.from.ip']}]
|
269
|
+
float_nest { "lat" : ${location.latitude['$.from.ip']}, "lon" : ${location.longitude['$.from.ip']}}
|
270
|
+
string_concat ${city.names.en['$.from.ip']},${country.names.en['$.from.ip']}
|
271
|
+
string_array [${city.names.en['$.from.ip']}, ${country.names.en['$.from.ip']}]
|
272
|
+
string_nest { "city" : ${city.names.en['$.from.ip']}, "country_name" : ${country.names.en['$.from.ip']}}
|
213
273
|
unknown_city ${city.names.en['unknown_key']}
|
214
274
|
undefined ${city.names.en['undefined']}
|
215
|
-
broken_array1 [${location.longitude['from.ip']}, ${location.latitude['undefined']}]
|
275
|
+
broken_array1 [${location.longitude['$.from.ip']}, ${location.latitude['undefined']}]
|
216
276
|
broken_array2 [${location.longitude['undefined']}, ${location.latitude['undefined']}]
|
217
277
|
</record>
|
218
278
|
]
|
@@ -265,13 +325,13 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
265
325
|
def test_filter_record_directive_multiple_record
|
266
326
|
config = %[
|
267
327
|
backend_library geoip2_c
|
268
|
-
|
328
|
+
geoip_lookup_keys $.from.ip, $.to.ip
|
269
329
|
<record>
|
270
|
-
from_city ${city.names.en['from.ip']}
|
271
|
-
to_city ${city.names.en['to.ip']}
|
272
|
-
from_country ${country.names.en['from.ip']}
|
273
|
-
to_country ${country.names.en['to.ip']}
|
274
|
-
string_array [${country.names.en['from.ip']}, ${country.names.en['to.ip']}]
|
330
|
+
from_city ${city.names.en['$.from.ip']}
|
331
|
+
to_city ${city.names.en['$.to.ip']}
|
332
|
+
from_country ${country.names.en['$.from.ip']}
|
333
|
+
to_country ${country.names.en['$.to.ip']}
|
334
|
+
string_array [${country.names.en['$.from.ip']}, ${country.names.en['$.to.ip']}]
|
275
335
|
</record>
|
276
336
|
]
|
277
337
|
messages = [
|
@@ -304,7 +364,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
304
364
|
def config_quoted_record
|
305
365
|
%[
|
306
366
|
backend_library geoip2_c
|
307
|
-
|
367
|
+
geoip_lookup_keys host
|
308
368
|
<record>
|
309
369
|
location_properties '{ "country_code" : "${country.iso_code["host"]}", "lat": ${location.latitude["host"]}, "lon": ${location.longitude["host"]} }'
|
310
370
|
location_string ${location.latitude['host']},${location.longitude['host']}
|
@@ -365,7 +425,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
365
425
|
def test_filter_multiline_v1_config
|
366
426
|
config = %[
|
367
427
|
backend_library geoip2_c
|
368
|
-
|
428
|
+
geoip_lookup_keys host
|
369
429
|
<record>
|
370
430
|
location_properties {
|
371
431
|
"city": "${city.names.en['host']}",
|
@@ -392,13 +452,79 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
392
452
|
filtered = filter(config, messages)
|
393
453
|
assert_equal(expected, filtered)
|
394
454
|
end
|
455
|
+
|
456
|
+
def test_filter_when_latitude_longitude_is_nil
|
457
|
+
config = %[
|
458
|
+
backend_library geoip2_c
|
459
|
+
geoip_lookup_keys host
|
460
|
+
<record>
|
461
|
+
latitude ${location.latitude['host']}
|
462
|
+
longitude ${location.longitude['host']}
|
463
|
+
</record>
|
464
|
+
]
|
465
|
+
messages = [
|
466
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
467
|
+
]
|
468
|
+
expected = [
|
469
|
+
{
|
470
|
+
"host" => "180.94.85.84",
|
471
|
+
"message" => "nil latitude and longitude",
|
472
|
+
"latitude" => 0.0,
|
473
|
+
"longitude" => 0.0
|
474
|
+
}
|
475
|
+
]
|
476
|
+
filtered = filter(config, messages) do |d|
|
477
|
+
setup_geoip_mock(d)
|
478
|
+
end
|
479
|
+
assert_equal(expected, filtered)
|
480
|
+
end
|
481
|
+
|
482
|
+
def test_filter_nested_attr_bracket_style_double_quote
|
483
|
+
config = %[
|
484
|
+
backend_library geoip2_c
|
485
|
+
geoip_lookup_keys $["host"]["ip"]
|
486
|
+
<record>
|
487
|
+
geoip_city ${city.names.en['$["host"]["ip"]']}
|
488
|
+
</record>
|
489
|
+
]
|
490
|
+
messages = [
|
491
|
+
{'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip'},
|
492
|
+
{'message' => 'missing field'}
|
493
|
+
]
|
494
|
+
expected = [
|
495
|
+
{'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip', 'geoip_city' => 'Mountain View'},
|
496
|
+
{'message' => 'missing field', 'geoip_city' => nil}
|
497
|
+
]
|
498
|
+
filtered = filter(config, messages)
|
499
|
+
assert_equal(expected, filtered)
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_filter_nested_attr_bracket_style_single_quote
|
503
|
+
config = %[
|
504
|
+
backend_library geoip2_c
|
505
|
+
geoip_lookup_keys $['host']['ip']
|
506
|
+
<record>
|
507
|
+
geoip_city ${city.names.en["$['host']['ip']"]}
|
508
|
+
</record>
|
509
|
+
]
|
510
|
+
messages = [
|
511
|
+
{'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip'},
|
512
|
+
{'message' => 'missing field'}
|
513
|
+
]
|
514
|
+
expected = [
|
515
|
+
{'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip', 'geoip_city' => 'Mountain View'},
|
516
|
+
{'message' => 'missing field', 'geoip_city' => nil}
|
517
|
+
]
|
518
|
+
filtered = filter(config, messages)
|
519
|
+
assert_equal(expected, filtered)
|
520
|
+
end
|
395
521
|
end
|
396
522
|
|
397
523
|
sub_test_case "geoip2_compat" do
|
398
524
|
def test_filter_with_dot_key
|
399
525
|
config = %[
|
400
526
|
backend_library geoip2_compat
|
401
|
-
|
527
|
+
geoip_lookup_keys ip.origin, ip.dest
|
402
528
|
<record>
|
403
529
|
origin_country ${country_code['ip.origin']}
|
404
530
|
dest_country ${country_code['ip.dest']}
|
@@ -418,7 +544,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
418
544
|
def test_filter_with_unknown_address
|
419
545
|
config = %[
|
420
546
|
backend_library geoip2_compat
|
421
|
-
|
547
|
+
geoip_lookup_keys host
|
422
548
|
<record>
|
423
549
|
geoip_city ${city['host']}
|
424
550
|
geopoint [${longitude['host']}, ${latitude['host']}]
|
@@ -441,7 +567,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
441
567
|
def test_filter_with_skip_unknown_address
|
442
568
|
config = %[
|
443
569
|
backend_library geoip2_compat
|
444
|
-
|
570
|
+
geoip_lookup_keys host
|
445
571
|
<record>
|
446
572
|
geoip_city ${city['host']}
|
447
573
|
geopoint [${longitude['host']}, ${latitude['host']}]
|
@@ -467,21 +593,21 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
467
593
|
def test_filter_record_directive
|
468
594
|
config = %[
|
469
595
|
backend_library geoip2_compat
|
470
|
-
|
596
|
+
geoip_lookup_keys $.from.ip
|
471
597
|
<record>
|
472
|
-
from_city ${city['from.ip']}
|
473
|
-
from_country ${country_name['from.ip']}
|
474
|
-
latitude ${latitude['from.ip']}
|
475
|
-
longitude ${longitude['from.ip']}
|
476
|
-
float_concat ${latitude['from.ip']},${longitude['from.ip']}
|
477
|
-
float_array [${longitude['from.ip']}, ${latitude['from.ip']}]
|
478
|
-
float_nest { "lat" : ${latitude['from.ip']}, "lon" : ${longitude['from.ip']}}
|
479
|
-
string_concat ${city['from.ip']},${country_name['from.ip']}
|
480
|
-
string_array [${city['from.ip']}, ${country_name['from.ip']}]
|
481
|
-
string_nest { "city" : ${city['from.ip']}, "country_name" : ${country_name['from.ip']}}
|
598
|
+
from_city ${city['$.from.ip']}
|
599
|
+
from_country ${country_name['$.from.ip']}
|
600
|
+
latitude ${latitude['$.from.ip']}
|
601
|
+
longitude ${longitude['$.from.ip']}
|
602
|
+
float_concat ${latitude['$.from.ip']},${longitude['$.from.ip']}
|
603
|
+
float_array [${longitude['$.from.ip']}, ${latitude['$.from.ip']}]
|
604
|
+
float_nest { "lat" : ${latitude['$.from.ip']}, "lon" : ${longitude['$.from.ip']}}
|
605
|
+
string_concat ${city['$.from.ip']},${country_name['$.from.ip']}
|
606
|
+
string_array [${city['$.from.ip']}, ${country_name['$.from.ip']}]
|
607
|
+
string_nest { "city" : ${city['$.from.ip']}, "country_name" : ${country_name['$.from.ip']}}
|
482
608
|
unknown_city ${city['unknown_key']}
|
483
609
|
undefined ${city['undefined']}
|
484
|
-
broken_array1 [${longitude['from.ip']}, ${latitude['undefined']}]
|
610
|
+
broken_array1 [${longitude['$.from.ip']}, ${latitude['undefined']}]
|
485
611
|
broken_array2 [${longitude['undefined']}, ${latitude['undefined']}]
|
486
612
|
</record>
|
487
613
|
]
|
@@ -534,13 +660,13 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
534
660
|
def test_filter_record_directive_multiple_record
|
535
661
|
config = %[
|
536
662
|
backend_library geoip2_compat
|
537
|
-
|
663
|
+
geoip_lookup_keys $.from.ip, $.to.ip
|
538
664
|
<record>
|
539
|
-
from_city ${city['from.ip']}
|
540
|
-
to_city ${city['to.ip']}
|
541
|
-
from_country ${country_name['from.ip']}
|
542
|
-
to_country ${country_name['to.ip']}
|
543
|
-
string_array [${country_name['from.ip']}, ${country_name['to.ip']}]
|
665
|
+
from_city ${city['$.from.ip']}
|
666
|
+
to_city ${city['$.to.ip']}
|
667
|
+
from_country ${country_name['$.from.ip']}
|
668
|
+
to_country ${country_name['$.to.ip']}
|
669
|
+
string_array [${country_name['$.from.ip']}, ${country_name['$.to.ip']}]
|
544
670
|
</record>
|
545
671
|
]
|
546
672
|
messages = [
|
@@ -573,7 +699,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
573
699
|
def config_quoted_record
|
574
700
|
%[
|
575
701
|
backend_library geoip2_compat
|
576
|
-
|
702
|
+
geoip_lookup_keys host
|
577
703
|
<record>
|
578
704
|
location_properties '{ "country_code" : "${country_code["host"]}", "lat": ${latitude["host"]}, "lon": ${longitude["host"]} }'
|
579
705
|
location_string ${latitude['host']},${longitude['host']}
|
@@ -634,7 +760,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
634
760
|
def test_filter_multiline_v1_config
|
635
761
|
config = %[
|
636
762
|
backend_library geoip2_compat
|
637
|
-
|
763
|
+
geoip_lookup_keys host
|
638
764
|
<record>
|
639
765
|
location_properties {
|
640
766
|
"city": "${city['host']}",
|
@@ -661,14 +787,42 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
661
787
|
filtered = filter(config, messages)
|
662
788
|
assert_equal(expected, filtered)
|
663
789
|
end
|
790
|
+
|
791
|
+
def test_filter_when_latitude_longitude_is_nil
|
792
|
+
config = %[
|
793
|
+
backend_library geoip2_compat
|
794
|
+
geoip_lookup_keys host
|
795
|
+
<record>
|
796
|
+
latitude ${latitude['host']}
|
797
|
+
longitude ${longitude['host']}
|
798
|
+
</record>
|
799
|
+
]
|
800
|
+
messages = [
|
801
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
802
|
+
]
|
803
|
+
expected = [
|
804
|
+
{
|
805
|
+
"host" => "180.94.85.84",
|
806
|
+
"message" => "nil latitude and longitude",
|
807
|
+
"latitude" => 0.0,
|
808
|
+
"longitude" => 0.0
|
809
|
+
}
|
810
|
+
]
|
811
|
+
filtered = filter(config, messages) do |d|
|
812
|
+
setup_geoip_mock(d)
|
813
|
+
end
|
814
|
+
assert_equal(expected, filtered)
|
815
|
+
end
|
664
816
|
end
|
665
817
|
|
666
818
|
sub_test_case "geoip legacy" do
|
667
819
|
def test_filter
|
668
820
|
config = %[
|
669
821
|
backend_library geoip
|
670
|
-
|
671
|
-
|
822
|
+
geoip_lookup_keys host
|
823
|
+
<record>
|
824
|
+
geoip_city ${city['host']}
|
825
|
+
</record>
|
672
826
|
]
|
673
827
|
messages = [
|
674
828
|
{'host' => '66.102.3.80', 'message' => 'valid ip'},
|
@@ -685,7 +839,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
685
839
|
def test_filter_with_dot_key
|
686
840
|
config = %[
|
687
841
|
backend_library geoip
|
688
|
-
|
842
|
+
geoip_lookup_keys ip.origin, ip.dest
|
689
843
|
<record>
|
690
844
|
origin_country ${country_code['ip.origin']}
|
691
845
|
dest_country ${country_code['ip.dest']}
|
@@ -705,8 +859,10 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
705
859
|
def test_filter_nested_attr
|
706
860
|
config = %[
|
707
861
|
backend_library geoip
|
708
|
-
|
709
|
-
|
862
|
+
geoip_lookup_keys $.host.ip
|
863
|
+
<record>
|
864
|
+
geoip_city ${city['$.host.ip']}
|
865
|
+
</record>
|
710
866
|
]
|
711
867
|
messages = [
|
712
868
|
{'host' => {'ip' => '66.102.3.80'}, 'message' => 'valid ip'},
|
@@ -723,7 +879,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
723
879
|
def test_filter_with_unknown_address
|
724
880
|
config = %[
|
725
881
|
backend_library geoip
|
726
|
-
|
882
|
+
geoip_lookup_keys host
|
727
883
|
<record>
|
728
884
|
geoip_city ${city['host']}
|
729
885
|
geopoint [${longitude['host']}, ${latitude['host']}]
|
@@ -746,7 +902,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
746
902
|
def test_filter_with_skip_unknown_address
|
747
903
|
config = %[
|
748
904
|
backend_library geoip
|
749
|
-
|
905
|
+
geoip_lookup_keys host
|
750
906
|
<record>
|
751
907
|
geoip_city ${city['host']}
|
752
908
|
geopoint [${longitude['host']}, ${latitude['host']}]
|
@@ -772,8 +928,11 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
772
928
|
def test_filter_multiple_key
|
773
929
|
config = %[
|
774
930
|
backend_library geoip
|
775
|
-
|
776
|
-
|
931
|
+
geoip_lookup_keys $.from.ip, $.to.ip
|
932
|
+
<record>
|
933
|
+
from_city ${city['$.from.ip']}
|
934
|
+
to_city ${city['$.to.ip']}
|
935
|
+
</record>
|
777
936
|
]
|
778
937
|
messages = [
|
779
938
|
{'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}},
|
@@ -791,9 +950,13 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
791
950
|
def test_filter_multiple_key_multiple_record
|
792
951
|
config = %[
|
793
952
|
backend_library geoip
|
794
|
-
|
795
|
-
|
796
|
-
|
953
|
+
geoip_lookup_keys $.from.ip, $.to.ip
|
954
|
+
<record>
|
955
|
+
from_city ${city['$.from.ip']}
|
956
|
+
from_country ${country_name['$.from.ip']}
|
957
|
+
to_city ${city['$.to.ip']}
|
958
|
+
to_country ${country_name['$.to.ip']}
|
959
|
+
</record>
|
797
960
|
]
|
798
961
|
messages = [
|
799
962
|
{'from' => {'ip' => '66.102.3.80'}, 'to' => {'ip' => '125.54.15.42'}},
|
@@ -831,21 +994,21 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
831
994
|
def test_filter_record_directive
|
832
995
|
config = %[
|
833
996
|
backend_library geoip
|
834
|
-
|
997
|
+
geoip_lookup_keys $.from.ip
|
835
998
|
<record>
|
836
|
-
from_city ${city['from.ip']}
|
837
|
-
from_country ${country_name['from.ip']}
|
838
|
-
latitude ${latitude['from.ip']}
|
839
|
-
longitude ${longitude['from.ip']}
|
840
|
-
float_concat ${latitude['from.ip']},${longitude['from.ip']}
|
841
|
-
float_array [${longitude['from.ip']}, ${latitude['from.ip']}]
|
842
|
-
float_nest { "lat" : ${latitude['from.ip']}, "lon" : ${longitude['from.ip']}}
|
843
|
-
string_concat ${city['from.ip']},${country_name['from.ip']}
|
844
|
-
string_array [${city['from.ip']}, ${country_name['from.ip']}]
|
845
|
-
string_nest { "city" : ${city['from.ip']}, "country_name" : ${country_name['from.ip']}}
|
999
|
+
from_city ${city['$.from.ip']}
|
1000
|
+
from_country ${country_name['$.from.ip']}
|
1001
|
+
latitude ${latitude['$.from.ip']}
|
1002
|
+
longitude ${longitude['$.from.ip']}
|
1003
|
+
float_concat ${latitude['$.from.ip']},${longitude['$.from.ip']}
|
1004
|
+
float_array [${longitude['$.from.ip']}, ${latitude['$.from.ip']}]
|
1005
|
+
float_nest { "lat" : ${latitude['$.from.ip']}, "lon" : ${longitude['$.from.ip']}}
|
1006
|
+
string_concat ${city['$.from.ip']},${country_name['$.from.ip']}
|
1007
|
+
string_array [${city['$.from.ip']}, ${country_name['$.from.ip']}]
|
1008
|
+
string_nest { "city" : ${city['$.from.ip']}, "country_name" : ${country_name['$.from.ip']}}
|
846
1009
|
unknown_city ${city['unknown_key']}
|
847
1010
|
undefined ${city['undefined']}
|
848
|
-
broken_array1 [${longitude['from.ip']}, ${latitude['undefined']}]
|
1011
|
+
broken_array1 [${longitude['$.from.ip']}, ${latitude['undefined']}]
|
849
1012
|
broken_array2 [${longitude['undefined']}, ${latitude['undefined']}]
|
850
1013
|
</record>
|
851
1014
|
]
|
@@ -898,13 +1061,13 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
898
1061
|
def test_filter_record_directive_multiple_record
|
899
1062
|
config = %[
|
900
1063
|
backend_library geoip
|
901
|
-
|
1064
|
+
geoip_lookup_keys $.from.ip, $.to.ip
|
902
1065
|
<record>
|
903
|
-
from_city ${city['from.ip']}
|
904
|
-
to_city ${city['to.ip']}
|
905
|
-
from_country ${country_name['from.ip']}
|
906
|
-
to_country ${country_name['to.ip']}
|
907
|
-
string_array [${country_name['from.ip']}, ${country_name['to.ip']}]
|
1066
|
+
from_city ${city['$.from.ip']}
|
1067
|
+
to_city ${city['$.to.ip']}
|
1068
|
+
from_country ${country_name['$.from.ip']}
|
1069
|
+
to_country ${country_name['$.to.ip']}
|
1070
|
+
string_array [${country_name['$.from.ip']}, ${country_name['$.to.ip']}]
|
908
1071
|
</record>
|
909
1072
|
]
|
910
1073
|
messages = [
|
@@ -937,7 +1100,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
937
1100
|
def config_quoted_record
|
938
1101
|
%[
|
939
1102
|
backend_library geoip
|
940
|
-
|
1103
|
+
geoip_lookup_keys host
|
941
1104
|
<record>
|
942
1105
|
location_properties '{ "country_code" : "${country_code["host"]}", "lat": ${latitude["host"]}, "lon": ${longitude["host"]} }'
|
943
1106
|
location_string ${latitude['host']},${longitude['host']}
|
@@ -998,7 +1161,7 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
998
1161
|
def test_filter_multiline_v1_config
|
999
1162
|
config = %[
|
1000
1163
|
backend_library geoip
|
1001
|
-
|
1164
|
+
geoip_lookup_keys host
|
1002
1165
|
<record>
|
1003
1166
|
location_properties {
|
1004
1167
|
"city": "${city['host']}",
|
@@ -1025,6 +1188,32 @@ class GeoipFilterTest < Test::Unit::TestCase
|
|
1025
1188
|
filtered = filter(config, messages)
|
1026
1189
|
assert_equal(expected, filtered)
|
1027
1190
|
end
|
1191
|
+
|
1192
|
+
def test_filter_when_latitude_longitude_is_nil
|
1193
|
+
config = %[
|
1194
|
+
backend_library geoip
|
1195
|
+
geoip_lookup_keys host
|
1196
|
+
<record>
|
1197
|
+
latitude ${latitude['host']}
|
1198
|
+
longitude ${longitude['host']}
|
1199
|
+
</record>
|
1200
|
+
]
|
1201
|
+
messages = [
|
1202
|
+
{ "host" => "180.94.85.84", "message" => "nil latitude and longitude" }
|
1203
|
+
]
|
1204
|
+
expected = [
|
1205
|
+
{
|
1206
|
+
"host" => "180.94.85.84",
|
1207
|
+
"message" => "nil latitude and longitude",
|
1208
|
+
"latitude" => 0.0,
|
1209
|
+
"longitude" => 0.0
|
1210
|
+
}
|
1211
|
+
]
|
1212
|
+
filtered = filter(config, messages) do |d|
|
1213
|
+
setup_geoip_mock(d)
|
1214
|
+
end
|
1215
|
+
assert_equal(expected, filtered)
|
1216
|
+
end
|
1028
1217
|
end
|
1029
1218
|
end
|
1030
1219
|
|