logstash-filter-geoip2 3.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f6d0a06e9957b67fa3340d637493e4411ac679c0
4
+ data.tar.gz: ce3978802ccf43fe78e5d0e22c6d7297c0a3345c
5
+ SHA512:
6
+ metadata.gz: f3397663e70461a490f449b374c1d2251702408c516e7c266c13e1e22d767aa6aad21b9a721371eb91df281b1fb390763aeddd3f7463c9587d48039732d1f486
7
+ data.tar.gz: 15c9209954939b615a2018bac9b60cf4025ff182e3c90cb696fb8f905717a8eadc5c493af7b48e1c68a0fcb371c742d53fcc026b132d00cfbffac266fd95a507
@@ -0,0 +1,33 @@
1
+ # 3.0.0-beta1
2
+ - Changed plugin to use GeoIP2 database. See http://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/
3
+
4
+ # 2.0.7
5
+ - Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
6
+ # 2.0.6
7
+ - New dependency requirements for logstash-core for the 5.0 release
8
+ ## 2.0.5
9
+ - Use proper field references
10
+
11
+ ## 2.0.4
12
+ - Refactor GeoIP Struct to hash conversion to minimise repeated manipulation
13
+
14
+ ## 2.0.3
15
+ - Fix Issue 50, incorrect data returned when geo lookup fails
16
+
17
+ ## 2.0.2
18
+ - Update core dependency in gemspec
19
+
20
+ ## 2.0.1
21
+ - Remove filter? call
22
+
23
+ ## 2.0.0
24
+ - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
25
+ instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
26
+ - Dependency on logstash-core update to 2.0
27
+
28
+ * 1.1.2
29
+ - Be more defensive with threadsafety, mostly for specs
30
+ * 1.1.1
31
+ - Lazy-load LRU cache
32
+ * 1.1.0
33
+ - Add LRU cache
@@ -0,0 +1,26 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors:
5
+ * Aaron Mildenstein (untergeek)
6
+ * Avishai Ish-Shalom (avishai-ish-shalom)
7
+ * Brad Fritz (bfritz)
8
+ * Colin Surprenant (colinsurprenant)
9
+ * Jordan Sissel (jordansissel)
10
+ * Kurt Hurtado (kurtado)
11
+ * Leandro Moreira (leandromoreira)
12
+ * Nick Ethier (nickethier)
13
+ * Pier-Hugues Pellerin (ph)
14
+ * Pieter Lexis (pieterlexis)
15
+ * Richard Pijnenburg (electrical)
16
+ * Suyog Rao (suyograo)
17
+ * Vincent Batts (vbatts)
18
+ * avleen
19
+ * Guy Boertje (guyboertje)
20
+ * Thomas Decaux (qwant)
21
+ * Gary Gao (garyelephant)
22
+
23
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
24
+ Logstash, and you aren't on the list above and want to be, please let us know
25
+ and we'll make sure you're here. Contributions from folks like you are what make
26
+ open source awesome.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012–2016 Elasticsearch <http://www.elastic.co>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
@@ -0,0 +1,110 @@
1
+ # Logstash Plugin
2
+
3
+ [![Travis Build Status](https://travis-ci.org/logstash-plugins/logstash-filter-geoip.svg)](https://travis-ci.org/logstash-plugins/logstash-filter-geoip)
4
+
5
+ This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
+
7
+ It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
8
+
9
+ ## Documentation
10
+
11
+ Logstash provides infrastructure to automatically generate documentation for this plugin. We use the asciidoc format to write documentation so any comments in the source code will be first converted into asciidoc and then into html. All plugin documentation are placed under one [central location](http://www.elastic.co/guide/en/logstash/current/).
12
+
13
+ - For formatting code or config example, you can use the asciidoc `[source,ruby]` directive
14
+ - For more asciidoc formatting tips, see the excellent reference here https://github.com/elastic/docs#asciidoc-guide
15
+
16
+ ## Need Help?
17
+
18
+ Need help? Try #logstash on freenode IRC or the https://discuss.elastic.co/c/logstash discussion forum.
19
+
20
+ ## Developing
21
+
22
+ ### 1. Plugin Developement and Testing
23
+
24
+ #### Code
25
+ - To get started, you'll need JRuby with the Bundler gem installed.
26
+
27
+ - Create a new plugin or clone and existing from the GitHub [logstash-plugins](https://github.com/logstash-plugins) organization. We also provide [example plugins](https://github.com/logstash-plugins?query=example).
28
+
29
+ - Install dependencies
30
+ ```sh
31
+ bundle install
32
+ ```
33
+
34
+ #### Test
35
+
36
+ - Update your dependencies
37
+
38
+ ```sh
39
+ bundle install
40
+ ```
41
+
42
+ - Pull down GeoIP database files
43
+
44
+ ```sh
45
+ bundle exec rake vendor
46
+ ```
47
+
48
+ - Install jar dependencies
49
+
50
+ ```
51
+ bundle exec rake install_jars
52
+ ```
53
+
54
+ - Run tests
55
+
56
+ ```sh
57
+ bundle exec rspec
58
+ ```
59
+
60
+ ### 2. Running your unpublished Plugin in Logstash
61
+
62
+ #### 2.1 Run in a local Logstash clone
63
+
64
+ - Edit Logstash `Gemfile` and add the local plugin path, for example:
65
+ ```ruby
66
+ gem "logstash-filter-awesome", :path => "/your/local/logstash-filter-awesome"
67
+ ```
68
+ - Install plugin
69
+ ```sh
70
+ # Logstash 2.3 and higher
71
+ bin/logstash-plugin install --no-verify
72
+
73
+ # Prior to Logstash 2.3
74
+ bin/plugin install --no-verify
75
+
76
+ ```
77
+ - Run Logstash with your plugin
78
+ ```sh
79
+ bin/logstash -e 'filter {awesome {}}'
80
+ ```
81
+ At this point any modifications to the plugin code will be applied to this local Logstash setup. After modifying the plugin, simply rerun Logstash.
82
+
83
+ #### 2.2 Run in an installed Logstash
84
+
85
+ You can use the same **2.1** method to run your plugin in an installed Logstash by editing its `Gemfile` and pointing the `:path` to your local plugin development directory or you can build the gem and install it using:
86
+
87
+ - Build your plugin gem
88
+ ```sh
89
+ gem build logstash-filter-awesome.gemspec
90
+ ```
91
+ - Install the plugin from the Logstash home
92
+ ```sh
93
+ # Logstash 2.3 and higher
94
+ bin/logstash-plugin install --no-verify
95
+
96
+ # Prior to Logstash 2.3
97
+ bin/plugin install --no-verify
98
+
99
+ ```
100
+ - Start Logstash and proceed to test the plugin
101
+
102
+ ## Contributing
103
+
104
+ All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
105
+
106
+ Programming is not a required skill. Whatever you've seen about open source and maintainers or community members saying "send patches or die" - you will not see that here.
107
+
108
+ It is more important to the community that you are able to contribute.
109
+
110
+ For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
@@ -0,0 +1,8 @@
1
+ # this is a generated file, to avoid over-writing it just delete this comment
2
+ require 'jar_dependencies'
3
+
4
+ require_jar( 'com.fasterxml.jackson.core', 'jackson-databind', '2.6.4' )
5
+ require_jar( 'com.maxmind.db', 'maxmind-db', '1.1.0' )
6
+ require_jar( 'com.maxmind.geoip2', 'geoip2', '2.5.0' )
7
+ require_jar( 'com.fasterxml.jackson.core', 'jackson-annotations', '2.6.0' )
8
+ require_jar( 'com.fasterxml.jackson.core', 'jackson-core', '2.6.4' )
@@ -0,0 +1,218 @@
1
+ # encoding: utf-8
2
+ require "logstash/filters/base"
3
+ require "logstash/namespace"
4
+
5
+ require "logstash-filter-geoip2_jars"
6
+
7
+ java_import "java.net.InetAddress"
8
+ java_import "com.maxmind.geoip2.DatabaseReader"
9
+ java_import "com.maxmind.geoip2.model.CityResponse"
10
+ java_import "com.maxmind.geoip2.record.Country"
11
+ java_import "com.maxmind.geoip2.record.Subdivision"
12
+ java_import "com.maxmind.geoip2.record.City"
13
+ java_import "com.maxmind.geoip2.record.Postal"
14
+ java_import "com.maxmind.geoip2.record.Location"
15
+ java_import "com.maxmind.db.CHMCache"
16
+
17
+ def suppress_all_warnings
18
+ old_verbose = $VERBOSE
19
+ begin
20
+ $VERBOSE = nil
21
+ yield if block_given?
22
+ ensure
23
+ # always re-set to old value, even if block raises an exception
24
+ $VERBOSE = old_verbose
25
+ end
26
+ end
27
+
28
+ # create a new instance of the Java class File without shadowing the Ruby version of the File class
29
+ module JavaIO
30
+ include_package "java.io"
31
+ end
32
+
33
+
34
+ # The GeoIP2 filter adds information about the geographical location of IP addresses,
35
+ # based on data from the Maxmind database.
36
+ #
37
+ # Starting with version 1.3.0 of Logstash, a `[geoip][location]` field is created if
38
+ # the GeoIP lookup returns a latitude and longitude. The field is stored in
39
+ # http://geojson.org/geojson-spec.html[GeoJSON] format. Additionally,
40
+ # the default Elasticsearch template provided with the
41
+ # <<plugins-outputs-elasticsearch,`elasticsearch` output>> maps
42
+ # the `[geoip][location]` field to an http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html#_mapping_options[Elasticsearch geo_point].
43
+ #
44
+ # As this field is a `geo_point` _and_ it is still valid GeoJSON, you get
45
+ # the awesomeness of Elasticsearch's geospatial query, facet and filter functions
46
+ # and the flexibility of having GeoJSON for all other applications (like Kibana's
47
+ # map visualization).
48
+ #
49
+ # This product includes GeoLite2 data created by MaxMind, available from
50
+ # <http://dev.maxmind.com/geoip/geoip2/geolite2/>.
51
+ class LogStash::Filters::GeoIP2 < LogStash::Filters::Base
52
+ config_name "geoip2"
53
+
54
+ # The path to the GeoIP2 database file which Logstash should use. Only City database is supported by now.
55
+ #
56
+ # If not specified, this will default to the GeoLiteCity database that ships
57
+ # with Logstash.
58
+ config :database, :validate => :path
59
+
60
+ # The field containing the IP address or hostname to map via geoip. If
61
+ # this field is an array, only the first value will be used.
62
+ config :source, :validate => :string, :required => true
63
+
64
+ # An array of geoip fields to be included in the event.
65
+ #
66
+ # Possible fields depend on the database type. By default, all geoip fields
67
+ # are included in the event.
68
+ #
69
+ # For the built-in GeoLiteCity database, the following are available:
70
+ # `city_name`, `continent_code`, `country_code2`, `country_code3`, `country_name`,
71
+ # `dma_code`, `ip`, `latitude`, `longitude`, `postal_code`, `region_name` and `timezone`.
72
+ config :fields, :validate => :array, :default => ['city_name', 'continent_code',
73
+ 'country_code2', 'country_code3', 'country_name',
74
+ 'dma_code', 'ip', 'latitude',
75
+ 'longitude', 'postal_code', 'region_name',
76
+ 'region_code', 'timezone', 'location']
77
+
78
+ # Specify the field into which Logstash should store the geoip data.
79
+ # This can be useful, for example, if you have `src\_ip` and `dst\_ip` fields and
80
+ # would like the GeoIP information of both IPs.
81
+ #
82
+ # If you save the data to a target field other than `geoip` and want to use the
83
+ # `geo\_point` related functions in Elasticsearch, you need to alter the template
84
+ # provided with the Elasticsearch output and configure the output to use the
85
+ # new template.
86
+ #
87
+ # Even if you don't use the `geo\_point` mapping, the `[target][location]` field
88
+ # is still valid GeoJSON.
89
+ config :target, :validate => :string, :default => 'geoip'
90
+
91
+ # GeoIP lookup is surprisingly expensive. This filter uses an cache to take advantage of the fact that
92
+ # IPs agents are often found adjacent to one another in log files and rarely have a random distribution.
93
+ # The higher you set this the more likely an item is to be in the cache and the faster this filter will run.
94
+ # However, if you set this too high you can use more memory than desired.
95
+ # Since the Geoip API upgraded to v2, there is not any eviction policy so far, if cache is full, no more record can be added.
96
+ # Experiment with different values for this option to find the best performance for your dataset.
97
+ #
98
+ # This MUST be set to a value > 0. There is really no reason to not want this behavior, the overhead is minimal
99
+ # and the speed gains are large.
100
+ #
101
+ # It is important to note that this config value is global to the geoip_type. That is to say all instances of the geoip filter
102
+ # of the same geoip_type share the same cache. The last declared cache size will 'win'. The reason for this is that there would be no benefit
103
+ # to having multiple caches for different instances at different points in the pipeline, that would just increase the
104
+ # number of cache misses and waste memory.
105
+ config :cache_size, :validate => :number, :default => 1000
106
+
107
+ # GeoIP lookup is surprisingly expensive. This filter uses an LRU cache to take advantage of the fact that
108
+ # IPs agents are often found adjacent to one another in log files and rarely have a random distribution.
109
+ # The higher you set this the more likely an item is to be in the cache and the faster this filter will run.
110
+ # However, if you set this too high you can use more memory than desired.
111
+ #
112
+ # Experiment with different values for this option to find the best performance for your dataset.
113
+ #
114
+ # This MUST be set to a value > 0. There is really no reason to not want this behavior, the overhead is minimal
115
+ # and the speed gains are large.
116
+ #
117
+ # It is important to note that this config value is global to the geoip_type. That is to say all instances of the geoip filter
118
+ # of the same geoip_type share the same cache. The last declared cache size will 'win'. The reason for this is that there would be no benefit
119
+ # to having multiple caches for different instances at different points in the pipeline, that would just increase the
120
+ # number of cache misses and waste memory.
121
+ config :lru_cache_size, :validate => :number, :default => 1000
122
+
123
+ public
124
+ def register
125
+ suppress_all_warnings do
126
+ if @database.nil?
127
+ @database = ::Dir.glob(::File.join(::File.expand_path("../../../vendor/", ::File.dirname(__FILE__)),"GeoLite2-City.mmdb")).first
128
+
129
+ if @database.nil? || !File.exists?(@database)
130
+ raise "You must specify 'database => ...' in your geoip filter (I looked for '#{@database}')"
131
+ end
132
+ end
133
+
134
+ @logger.info("Using geoip database", :path => @database)
135
+
136
+ db_file = JavaIO::File.new(@database)
137
+ begin
138
+ @parser = DatabaseReader::Builder.new(db_file).withCache(CHMCache.new(@cache_size)).build();
139
+ rescue Java::ComMaxmindDb::InvalidDatabaseException => e
140
+ @logger.error("The Geoip2 MMDB database provided is invalid or corrupted.", :exception => e, :field => @source)
141
+ raise e
142
+ end
143
+ end
144
+ end # def register
145
+
146
+ public
147
+ def filter(event)
148
+ return unless filter?(event)
149
+
150
+ begin
151
+ ip = event[@source]
152
+ ip = ip.first if ip.is_a? Array
153
+ ip_address = InetAddress.getByName(ip)
154
+ response = @parser.city(ip_address)
155
+ country = response.getCountry()
156
+ subdivision = response.getMostSpecificSubdivision()
157
+ city = response.getCity()
158
+ postal = response.getPostal()
159
+ location = response.getLocation()
160
+
161
+ geo_data_hash = Hash.new()
162
+
163
+ @fields.each do |field|
164
+ case field
165
+ when "city_name"
166
+ geo_data_hash["city_name"] = city.getName()
167
+ when "country_name"
168
+ geo_data_hash["country_name"] = country.getName()
169
+ when "continent_code"
170
+ geo_data_hash["continent_code"] = response.getContinent().getCode()
171
+ when "continent_name"
172
+ geo_data_hash["continent_name"] = response.getContinent().getName()
173
+ when "country_code2"
174
+ geo_data_hash["country_code2"] = country.getIsoCode()
175
+ when "country_code3"
176
+ geo_data_hash["country_code3"] = country.getIsoCode()
177
+ when "ip"
178
+ geo_data_hash["ip"] = ip_address.getHostAddress()
179
+ when "postal_code"
180
+ geo_data_hash["postal_code"] = postal.getCode()
181
+ when "dma_code"
182
+ geo_data_hash["dma_code"] = location.getMetroCode()
183
+ when "region_name"
184
+ geo_data_hash["region_name"] = subdivision.getName()
185
+ when "region_code"
186
+ geo_data_hash["region_code"] = subdivision.getIsoCode()
187
+ when "timezone"
188
+ geo_data_hash["timezone"] = location.getTimeZone()
189
+ when "location"
190
+ geo_data_hash["location"] = [ location.getLongitude(), location.getLatitude() ]
191
+ when "latitude"
192
+ geo_data_hash["latitude"] = location.getLatitude()
193
+ when "longitude"
194
+ geo_data_hash["longitude"] = location.getLongitude()
195
+ else
196
+ raise Exception.new("[#{field}] is not a supported field option.")
197
+ end
198
+ end
199
+
200
+ rescue com.maxmind.geoip2.exception.AddressNotFoundException => e
201
+ @logger.debug("IP not found!", :exception => e, :field => @source, :event => event)
202
+ event[@target] = {}
203
+ return
204
+ rescue java.net.UnknownHostException => e
205
+ @logger.error("IP Field contained invalid IP address or hostname", :exception => e, :field => @source, :event => event)
206
+ event[@target] = {}
207
+ return
208
+ rescue Exception => e
209
+ @logger.error("Unknown error while looking up GeoIP data", :exception => e, :field => @source, :event => event)
210
+ event[@target] = {}
211
+ return
212
+ end
213
+
214
+ event[@target] = geo_data_hash
215
+
216
+ filter_matched(event)
217
+ end # def filter
218
+ end # class LogStash::Filters::GeoIP
@@ -0,0 +1,34 @@
1
+ Gem::Specification.new do |s|
2
+
3
+ s.name = 'logstash-filter-geoip2'
4
+ s.version = '3.0.0'
5
+ s.licenses = ['Apache License (2.0)']
6
+ s.summary = "$summary"
7
+ s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program. Config key is geoip2."
8
+ s.authors = ["Elastic"]
9
+ s.email = 'ebuildy@gmail.com'
10
+ s.homepage = "https://github.com/ebuildy/logstash-filter-geoip"
11
+ s.require_paths = ["lib"]
12
+ s.platform = "java"
13
+
14
+ # Files
15
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
16
+
17
+ # Tests
18
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
19
+
20
+ # Special flag to let us know this is actually a logstash plugin
21
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
22
+
23
+ # Gem dependencies
24
+ s.add_runtime_dependency "logstash-core-plugin-api", "~> 1.0"
25
+
26
+ s.requirements << "jar com.maxmind.geoip2:geoip2, 2.5.0, :exclusions=> [com.google.http-client:google-http-client]"
27
+
28
+ s.add_development_dependency "jar-dependencies"
29
+
30
+ s.add_development_dependency 'ruby-maven', '~> 3.3'
31
+
32
+ s.add_development_dependency 'logstash-devutils'
33
+ end
34
+
@@ -0,0 +1,218 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/filters/geoip"
3
+
4
+ CITYDB = ::Dir.glob(::File.expand_path("../../vendor/", ::File.dirname(__FILE__))+"/GeoLite2-City.mmdb").first
5
+
6
+ describe LogStash::Filters::GeoIP do
7
+
8
+ describe "defaults" do
9
+ config <<-CONFIG
10
+ filter {
11
+ geoip {
12
+ source => "ip"
13
+ #database => "#{CITYDB}"
14
+ }
15
+ }
16
+ CONFIG
17
+
18
+ sample("ip" => "8.8.8.8") do
19
+ insist { subject }.include?("geoip")
20
+
21
+ expected_fields = %w(ip country_code2 country_code3 country_name
22
+ continent_code region_name city_name postal_code
23
+ latitude longitude dma_code timezone
24
+ location )
25
+ expected_fields.each do |f|
26
+ insist { subject["geoip"] }.include?(f)
27
+ end
28
+ end
29
+
30
+ sample("ip" => "127.0.0.1") do
31
+ # assume geoip fails on localhost lookups
32
+ expect(subject["geoip"]).to eq({})
33
+ end
34
+ end
35
+
36
+ describe "normal operations" do
37
+ config <<-CONFIG
38
+ filter {
39
+ geoip {
40
+ source => "ip"
41
+ #database => "#{CITYDB}"
42
+ target => src_ip
43
+ add_tag => "done"
44
+ }
45
+ }
46
+ CONFIG
47
+
48
+ context "when specifying the target" do
49
+
50
+ sample("ip" => "8.8.8.8") do
51
+ expect(subject).to include("src_ip")
52
+
53
+ expected_fields = %w(ip country_code2 country_code3 country_name
54
+ continent_code region_name city_name postal_code
55
+ latitude longitude dma_code timezone
56
+ location )
57
+ expected_fields.each do |f|
58
+ expect(subject["src_ip"]).to include(f)
59
+ end
60
+ end
61
+
62
+ sample("ip" => "127.0.0.1") do
63
+ # assume geoip fails on localhost lookups
64
+ expect(subject["src_ip"]).to eq({})
65
+ end
66
+ end
67
+
68
+ context "when specifying add_tag" do
69
+ sample("ip" => "8.8.8.8") do
70
+ expect(subject["tags"]).to include("done")
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "correct encodings with default db" do
76
+ config <<-CONFIG
77
+ filter {
78
+ geoip {
79
+ source => "ip"
80
+ }
81
+ }
82
+ CONFIG
83
+ expected_fields = %w(ip country_code2 country_code3 country_name
84
+ continent_code region_name city_name postal_code
85
+ dma_code timezone)
86
+
87
+ sample("ip" => "1.1.1.1") do
88
+ checked = 0
89
+ expected_fields.each do |f|
90
+ next unless subject["geoip"][f]
91
+ checked += 1
92
+ insist { subject["geoip"][f].encoding } == Encoding::UTF_8
93
+ end
94
+ insist { checked } > 0
95
+ end
96
+
97
+ sample("ip" => "189.2.0.0") do
98
+ checked = 0
99
+ expected_fields.each do |f|
100
+ next unless subject["geoip"][f]
101
+ checked += 1
102
+ insist { subject["geoip"][f].encoding } == Encoding::UTF_8
103
+ end
104
+ insist { checked } > 0
105
+ end
106
+
107
+ end
108
+
109
+ describe "location field" do
110
+ shared_examples_for "an event with a [geoip][location] field" do
111
+ subject(:event) { LogStash::Event.new("message" => "8.8.8.8") }
112
+ let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "fields" => ["country_name", "location", "longitude"]) }
113
+
114
+ before do
115
+ plugin.register
116
+ plugin.filter(event)
117
+ end
118
+
119
+ it "should have a location field" do
120
+ expect(event["[geoip][location]"]).not_to(be_nil)
121
+ end
122
+ end
123
+
124
+ context "when latitude field is excluded" do
125
+ let(:fields) { ["country_name", "location", "longitude"] }
126
+ it_behaves_like "an event with a [geoip][location] field"
127
+ end
128
+
129
+ context "when longitude field is excluded" do
130
+ let(:fields) { ["country_name", "location", "latitude"] }
131
+ it_behaves_like "an event with a [geoip][location] field"
132
+ end
133
+
134
+ context "when both latitude and longitude field are excluded" do
135
+ let(:fields) { ["country_name", "location"] }
136
+ it_behaves_like "an event with a [geoip][location] field"
137
+ end
138
+ end
139
+
140
+ describe "an invalid IP" do
141
+ config <<-CONFIG
142
+ filter {
143
+ geoip {
144
+ source => "ip"
145
+ database => "#{CITYDB}"
146
+ }
147
+ }
148
+ CONFIG
149
+ describe "should not raise an error" do
150
+ sample("ip" => "-") do
151
+ expect{ subject }.to_not raise_error
152
+ end
153
+
154
+ sample("ip" => "~") do
155
+ expect{ subject }.to_not raise_error
156
+ end
157
+ end
158
+
159
+ describe "filter method outcomes" do
160
+ let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "add_tag" => "done", "database" => CITYDB) }
161
+ let(:event) { LogStash::Event.new("message" => ipstring) }
162
+
163
+ before do
164
+ plugin.register
165
+ plugin.filter(event)
166
+ end
167
+
168
+ context "when the bad IP is N/A" do
169
+ # regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/50
170
+ let(:ipstring) { "N/A" }
171
+
172
+ it "should set the target field to an empty hash" do
173
+ expect(event["geoip"]).to eq({})
174
+ end
175
+
176
+ it "should not have added any tags" do
177
+ expect(event["tags"]).to be_nil
178
+ end
179
+ end
180
+
181
+ context "when the bad IP is two ip comma separated" do
182
+ # regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/51
183
+ let(:ipstring) { "123.45.67.89,61.160.232.222" }
184
+
185
+ it "should set the target field to an empty hash" do
186
+ expect(event["geoip"]).to eq({})
187
+ end
188
+ end
189
+ end
190
+
191
+ context "should return the correct source field in the logging message" do
192
+ sample("ip" => "-") do
193
+ expect(LogStash::Filters::GeoIP.logger).to receive(:error).with(anything, include(:field => "ip"))
194
+ subject
195
+ end
196
+ end
197
+
198
+ end
199
+
200
+ describe "an invalid database" do
201
+ config <<-CONFIG
202
+ filter {
203
+ geoip {
204
+ source => "ip"
205
+ database => "./Gemfile"
206
+ }
207
+ }
208
+ CONFIG
209
+
210
+ context "should return the correct sourcefield in the logging message" do
211
+ sample("ip" => "8.8.8.8") do
212
+ expect(LogStash::Filters::GeoIP.logger).to receive(:error).with(anything, include(:field => "ip"))
213
+ expect { subject }.to raise_error
214
+ end
215
+ end
216
+ end
217
+
218
+ end
Binary file
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-geoip2
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.0
5
+ platform: java
6
+ authors:
7
+ - Elastic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ name: logstash-core-plugin-api
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ name: jar-dependencies
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.3'
47
+ name: ruby-maven
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ name: logstash-devutils
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program. Config key is geoip2.
70
+ email: ebuildy@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - CHANGELOG.md
76
+ - CONTRIBUTORS
77
+ - Gemfile
78
+ - LICENSE
79
+ - NOTICE.TXT
80
+ - README.md
81
+ - lib/com/fasterxml/jackson/core/jackson-annotations/2.6.0/jackson-annotations-2.6.0.jar
82
+ - lib/com/fasterxml/jackson/core/jackson-annotations/2.7.0/jackson-annotations-2.7.0.jar
83
+ - lib/com/fasterxml/jackson/core/jackson-core/2.6.4/jackson-core-2.6.4.jar
84
+ - lib/com/fasterxml/jackson/core/jackson-core/2.7.0/jackson-core-2.7.0.jar
85
+ - lib/com/fasterxml/jackson/core/jackson-databind/2.6.4/jackson-databind-2.6.4.jar
86
+ - lib/com/fasterxml/jackson/core/jackson-databind/2.7.0/jackson-databind-2.7.0.jar
87
+ - lib/com/maxmind/db/maxmind-db/1.1.0/maxmind-db-1.1.0.jar
88
+ - lib/com/maxmind/db/maxmind-db/1.2.0/maxmind-db-1.2.0.jar
89
+ - lib/com/maxmind/geoip2/geoip2/2.5.0/geoip2-2.5.0.jar
90
+ - lib/com/maxmind/geoip2/geoip2/2.6.0/geoip2-2.6.0.jar
91
+ - lib/logstash-filter-geoip2_jars.rb
92
+ - lib/logstash/filters/geoip2.rb
93
+ - logstash-filter-geoip.gemspec
94
+ - spec/filters/geoip_spec.rb
95
+ - vendor/GeoLite2-City.mmdb
96
+ homepage: https://github.com/ebuildy/logstash-filter-geoip
97
+ licenses:
98
+ - Apache License (2.0)
99
+ metadata:
100
+ logstash_plugin: 'true'
101
+ logstash_group: filter
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements:
117
+ - jar com.maxmind.geoip2:geoip2, 2.5.0, :exclusions=> [com.google.http-client:google-http-client]
118
+ rubyforge_project:
119
+ rubygems_version: 2.4.8
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: "$summary"
123
+ test_files:
124
+ - spec/filters/geoip_spec.rb