I am continuing to struggle with the GEO_IP mapping when it comes to loading data. First, I will describe the steps I am taking in my build, then i will post my configs below that.
- Install ElasticSearch
- Install SearchGuard
- Install Logstash
- Install Kibana
- Load ElasticSearch templates (Put using curl)
- Install Filebeat
- Push nginx.access logs
- Create relevant index
- Experience missing geo.location field
- Attempt remap via kibana gui
Below is my mapping (Will use pastebin as it's a large set of data)
The important part in question is:
"nginx": {
"properties": {
"access": {
"properties": {
"agent": {
"norms": false,
"type": "text"
},
"body_sent": {
"properties": {
"bytes": {
"type": "long"
}
}
},
"geoip": {
"properties": {
"continent_name": {
"ignore_above": 1024,
"type": "keyword"
},
"country_iso_code": {
"ignore_above": 1024,
"type": "keyword"
},
"location": {
"type": "geo_point"
}
}
},
I push nginx logs to Logstash using Filebeat in the following manner:
- input_type: log
paths:
- /var/log/nginx/access.log
fields:
log_type: nginx.access
tags: nginx.access
Then here is my logstash config, to deal with that.
filter {
if [fields][log_type] == "nginx.access" {
grok {
match => { "message" => "%{HTTPD_COMBINEDLOG}" }
}
geoip {
source => "clientip"
target => "[nginx][access][geoip]"
}
}
if [fields][log_type] == "nginx.error" {
grok {
match => { "message" => "%{HTTPD20_ERRORLOG}" }
}
geoip {
source => "clientip"
target => "[nginx][error][geoip]"
}
}
if [fields][log_type] == "nginx.timings" {
grok {
match => { "message" => "%{URIHOST:host} - - %{SYSLOG5424SD:timestamp} \"%{DATA:response}\" %{GREEDYDATA:message}" }
}
geoip {
source => "URIHOST"
target => "[nginx][timings][geoip]"
}
}
if [fields][log_type] == "nginx" {
grok {
match => { "message" => "%{HTTPD_COMBINEDLOG}" }
}
geoip {
source => "clientip"
target => "[nginx][access][geoip]"
}
}
}
Now unfortunately, when I load kibana no field called geoip.location exists, I only see geo.location.lat/lon. As follows:
Then here is my mappings from curl:
I can clearly see geo_ip.loation set as a geopoint field.
What am I missing here, why does my data not correctly populate geoip.location?
EDIT:
Here is the raw JSON from a document in elasticsearch
{
"_index": "nginx-2017.09.28",
"_type": "log",
"_id": "AV7HOdx7iyoqWt3_QQwZ",
"_version": 1,
"_score": null,
"_source": {
"request": "/",
"agent": "\"Cloud mapping experiment. Contact research@pdrlabs.net\"",
"offset": 133,
"nginx": {
"access": {
"geoip": {
"timezone": "America/New_York",
"ip": "54.161.85.67",
"latitude": 39.0481,
"continent_code": "NA",
"city_name": "Ashburn",
"country_name": "United States",
"country_code2": "US",
"dma_code": 511,
"country_code3": "US",
"region_name": "Virginia",
"location": {
"lon": -77.4728,
"lat": 39.0481
},
"postal_code": "20149",
"region_code": "VA",
"longitude": -77.4728
}
}
},
You can see location is there.