logstash kv filter,使用动态映射将字符串转换为整数

时间:2015-06-24 16:22:05

标签: elasticsearch logstash

我的日志格式类似于:

name=johnny amount=30 uuid=2039248934

问题是我在多个日志文件上使用此解析器,每个日志文件基本上包含许多kv对。

有没有办法识别值是什么时候整数并且不必在每个键值对上使用mutate?(而不是字符串)

我发现了这个链接但是模板json文件的设置位置非常模糊,以及我如何使用它。 Can kv be told to auto-detect numeric values and emit them as numeric JSON values?

2 个答案:

答案 0 :(得分:5)

您可以使用ruby插件来执行此操作。

input {
    stdin {}
}

filter {
    ruby {
        code => "
            fieldArray = event['message'].split(' ');
            for field in fieldArray
                name = field.split('=')[0];
                value = field.split('=')[1];
                if value =~ /\A\d+\Z/
                    event[name] = value.to_i
                else
                    event[name] = value
                end
            end
        "
    }
}
output {
    stdout { codec => rubydebug }
}

首先,通过SPACE将消息拆分为数组。 然后,对于每个k,v映射,检查值是否为numberic,如果为YES,则将其转换为Integer。

以下是您输入的示例输出:

{
       "message" => "name=johnny amount=30 uuid=2039248934",
      "@version" => "1",
    "@timestamp" => "2015-06-25T08:24:39.755Z",
          "host" => "BEN_LIM",
          "name" => "johnny",
        "amount" => 30,
          "uuid" => 2039248934
}

Logstash 5的更新解决方案:

input {
    stdin {}
}

filter {
    ruby {
        code => "
            fieldArray = event['message'].split(' ');
            for field in fieldArray
                name = field.split('=')[0];
                value = field.split('=')[1];
                if value =~ /\A\d+\Z/
                    event.set(name, value.to_i)
                else
                    event.set(name, value)
                end
            end
        "
    }
}
output {
    stdout { codec => rubydebug }
}

答案 1 :(得分:2)

请注意,如果您决定升级到Logstash 5,则会有一些重大更改:

https://www.elastic.co/guide/en/logstash/5.0/breaking-changes.html

特别是,需要修改事件才能使用event.get或event.set。以下是我以前的工作(基于Ben Lim的例子):

input {
    stdin {}
}

filter {
    ruby {
        code => "
            fieldArray = event.get('message').split(' ');
            for field in fieldArray
                name = field.split('=')[0];
                value = field.split('=')[1];
                if value =~ /\A\d+\Z/
                    event.set(name, value.to_i)
                else
                    event.set(name, value)
                end
            end
        "
    }
}
output {
    stdout { codec => rubydebug }
}