After a long time away from this issue, I've managed to get the right setup.
In my logstash config, after I've called geoip {}
I look for my IP address ranges and manually repopulate the various fields. I'm effectively declaring a new country.
if [srcip] =~ /^139\.80\./ or [srcip] =~ /^10\./ {
mutate { replace => { "[geoip][timezone]" => "Pacific/Auckland" } }
mutate { replace => { "[geoip][country_name]" => "University of Otago" } }
mutate { replace => { "[geoip][country_code2]" => "UO" } }
mutate { replace => { "[geoip][country_code3]" => "UoO" } }
mutate { remove_field => [ "[geoip][location]" ] }
mutate { add_field => { "[geoip][location]" => "170.525" } }
mutate { add_field => { "[geoip][location]" => "-45.865" } }
mutate { convert => [ "[geoip][location]", "float" ] }
mutate { replace => [ "[geoip][latitude]", -45.856 ] }
mutate { convert => [ "[geoip][latitude]", "float" ] }
mutate { replace => [ "[geoip][longitude]", 170.525 ] }
mutate { convert => [ "[geoip][longitude]", "float" ] }
}
To help keep me honest (actually, to make sure that all my settings are visible in the configuration) I explicitly set a template when writing to ES, rather than rely on state that's already there.
elasticsearch { embedded => "false"
cluster => "myclustername"
protocol => "transport"
host => "indexing host"
index => "test" # index name must be in lowercase!
template => "/etc/logstash/template.d/test"
template_name => "test"
template_overwrite => "true"
}
(Every time I drop this index, the new template will be used to re-create it.)
For my purposes, I'm using the template to switch off string analyzing (most of the fields are log data and analysis doesn't help), and to make sure I get geo_points done properly. Here's the full template from the dev box :-
{
"order" : 0,
"template" : "test*",
"settings" : { "index.refresh_interval" : "5s" },
"mappings" : {
"_default_" : {
"dynamic_templates" : [
{
"message_field" : {
"mapping" : { "index" : "analyzed", "omit_norms" : true, "type" : "string" },
"match_mapping_type" : "string",
"match" : "message" }
},
{
"string_fields" : {
"mapping" : { "index" : "not_analyzed", "ignore_above" : 256, "type" : "string" },
"match_mapping_type" : "string",
"match" : "*" }
}
],
"properties" : {
"geoip" : {
"dynamic" : true,
"path" : "full",
"properties" : { "location" : { "type" : "geo_point" } },
"type" : "object" },
"@version" : { "index" : "not_analyzed", "type" : "string" }
},
"_all" : { "enabled" : true }
}
},
"aliases" : { }
}
The end result is a custom country, with a geo-location that separates my network from the users in the same city (although the point on the map when you zoom in isn't as accurate as I want it to be, I don't think I'll worry about that!)