I set field mappings for IP address fields to { "type" : "ip" } and things are great until a logging device (Fortigate) doesn't have an IP address and sends N/A.
"error"=>{"type"=>"mapper_parsing_exception"
"reason"=>"failed to parse [assignip]"
"caused_by"=>{"type"=>"illegal_argument_exception"
"reason"=>"'N/A' is not an IP string literal."}}}}
:level=>:warn}
My desire was to replace N/A with 0.0.0.0 via a mutate/gsub logstash filter, so ES would ingest the data without fail. But mutate/gsub will only work on string fields.
Is there a way to get the same effect via another method?
Even though the IP address is an IP to you and me, Elasticsearch will think of it as a string. For it to be more, you have to tell Elasticsearch how to treat the value, and the way to do that is with a mapping. If an IP is mapped as type ip in Elasticsearch, you can do a query, and filter by an IP range—you can even use CIDR notation—to include only IPs within a given subnet.
But if I map these fields as type ip, then I can't use gsub:
Convert a string field by applying a regular expression and a replacement. If the field is not a string, no action will be taken.
At this point I'm thinking I either need to not use type ip on these different fields or perhaps use gsub -> replace.
Am I understanding (you and/or this situation) correctly?
Logstash type and ElasticSearch type are 2 different things.
Logstash will send it as string, and then ElasticSearch will analyze that string and break it down as an IP (which is actually an integer internally). But it' still a string until it reaches ES.
Bottom line, ElasticSearch mappings won't block you from gsub-ing a string.
So my 'fix' isn't parsing in LS, but isn't crashing LS, either.
I've tried gsub and replace :
if "N\/A" in ["assignip"] {
mutate {
gsub => ["assignip","N\/A","0\.0\.0\.0"]
#replace => {"assignip" => "0\.0\.0\.0"}
}
}
(I've alternately commented out the gsub statement and commented-in the replace statement).
I'm still getting this specific error-
(only including the interesting information snippet from the full error log entry):
"assignip"=>"N/A", ... "eventstatement"=>"progress IPsec phase 2"}, "type"]}>>], :response=>{"index"=>{"_index"=>"logstash-2017.06.29", "_type"=>"fortigate", "_id"=>"AVz0P_x-xWFZrN1eX51d", "status"=>400, "error"=>{"type"=>"mapper_parsing_exception", "reason"=>"failed to parse [assignip]", "caused_by"=>{"type"=>"illegal_argument_exception", "reason"=>"'N/A' is not an IP string literal."}}}}, :level=>:warn}
Just tried that on both, including not escaping N/A but escaping the ip address, not escaping anything, and of course, escaping everything.
I understand the explanation that LS will not worry about the type that ES will use for the field but it really appears to be doing so with the error ... that's an LS error entry, not an ES error entry.
I've even tried if "N/A" in ["assignip"] {mutate {remove_field => ["assignip"]}} and the same error occurs.
I've solved my issue, it was my fault (of course!). I was already using a mutate above this and I guess it only runs once per nested set of conditionals? I say this because I plopped the gsub statement into the mutate above and it worked!
In this example, the dst_ipmutate filter is effectively ignored (that's where the assignip gsub was) . kv hands off the newly-minted fields to mutate, which does it's work. But another nested conditional that calls upon mutate again will be ignored (apparently).
Thank-you very much for your help, I could not have gotten to this point without it.
I understand the explanation that LS will not worry about the type that ES will use for the field but it really appears to be doing so with the error ... that's an LS error entry, not an ES error entry.
Yes, but it's only relaying an ES error message.
In this example, the dst_ip mutate filter is effectively ignored
Probably because you should've used
if "N/A" in [dst_ip] {
instead of
if "N/A" in ["dst_ip"] {
Watch out when using multiple options in the same mutate filter. They're not executed in the order listed (necessarily anyway). If you're doing stuff with different fields it doesn't matter but if you modify the same field in a sequence of operations that will likely fail.
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.