Class: LogStash::Filters::GeoIP
- Defined in:
- lib/logstash/filters/geoip.rb
Overview
Add GeoIP fields from Maxmind database
GeoIP filter, adds information about the geographical location of IP addresses.
Starting at version 1.3.0 of logstash, a [geoip] field is created if the GeoIP lookup returns a latitude and longitude. The field is stored in [GeoJSON](geojson.org/geojson-spec.html) format. Additionally, the default Elasticsearch template provided with the [elasticsearch output](../outputs/elasticsearch.html) maps the [geoip] field to a [geo_point](www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html).
As this field is a geo_point and it is still valid GeoJSON, you get the awesomeness of Elasticsearch’s geospatial query, facet and filter functions and the flexibility of having GeoJSON for all other applications (like Kibana’s [bettermap panel](github.com/elasticsearch/kibana/tree/master/src/app/panels/bettermap)).
Logstash releases ship with the GeoLiteCity database made available from Maxmind with a CCA-ShareAlike 3.0 license. For more details on GeoLite, see <www.maxmind.com/en/geolite>.
Constant Summary
Constants inherited from Base
Constants included from Config::Mixin
Instance Attribute Summary
Attributes included from Config::Mixin
Attributes inherited from Plugin
Instance Method Summary collapse
Methods inherited from Base
#execute, #initialize, #threadsafe?
Methods included from Config::Mixin
Methods inherited from Plugin
#eql?, #finished, #finished?, #hash, #initialize, #inspect, lookup, #reload, #running?, #shutdown, #teardown, #terminating?, #to_s
Constructor Details
This class inherits a constructor from LogStash::Filters::Base
Instance Method Details
#filter(event) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/logstash/filters/geoip.rb', line 107 def filter(event) return unless filter?(event) geo_data = nil begin ip = event[@source] ip = ip.first if ip.is_a? Array geo_data = @geoip.send(@geoip_type, ip) rescue SocketError => e @logger.error("IP Field contained invalid IP address or hostname", :field => @field, :event => event) rescue Exception => e @logger.error("Unknown error while looking up GeoIP data", :exception => e, :field => @field, :event => event) end return if geo_data.nil? geo_data_hash = geo_data.to_hash geo_data_hash.delete(:request) event[@target] = {} if event[@target].nil? geo_data_hash.each do |key, value| next if value.nil? || (value.is_a?(String) && value.empty?) if @fields.nil? || @fields.empty? # no fields requested, so add all geoip hash items to # the event's fields. # convert key to string (normally a Symbol) event[@target][key.to_s] = value elsif @fields.include?(key.to_s) # Check if the key is in our fields array # convert key to string (normally a Symbol) event[@target][key.to_s] = value end end # geo_data_hash.each if event[@target].key?('latitude') && event[@target].key?('longitude') # If we have latitude and longitude values, add the location field as GeoJSON array event[@target]['location'] = [ event[@target]["longitude"].to_f, event[@target]["latitude"].to_f ] end filter_matched(event) end |
#register ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/logstash/filters/geoip.rb', line 64 def register require "geoip" if @database.nil? if __FILE__ =~ /^(jar:)?file:\/.+!.+/ begin # Running from a jar, assume GeoLiteCity.dat is at the root. jar_path = [__FILE__.split("!").first, "/GeoLiteCity.dat"].join("!") tmp_file = Tempfile.new('logstash-geoip') tmp_file.write(File.read(jar_path)) tmp_file.close # this file is reaped when ruby exits @database = tmp_file.path rescue => ex raise "Failed to cache, due to: #{ex}\n#{ex.backtrace}" end else if File.exists?("GeoLiteCity.dat") @database = "GeoLiteCity.dat" elsif File.exists?("vendor/geoip/GeoLiteCity.dat") @database = "vendor/geoip/GeoLiteCity.dat" else raise "You must specify 'database => ...' in your geoip filter" end end end @logger.info("Using geoip database", :path => @database) @geoip = ::GeoIP.new(@database) @geoip_type = case @geoip.database_type when GeoIP::GEOIP_CITY_EDITION_REV0, GeoIP::GEOIP_CITY_EDITION_REV1 :city when GeoIP::GEOIP_COUNTRY_EDITION :country when GeoIP::GEOIP_ASNUM_EDITION :asn when GeoIP::GEOIP_ISP_EDITION, GeoIP::GEOIP_ORG_EDITION :isp else raise RuntimeException.new "This GeoIP database is not currently supported" end end |