【问题标题】:Logstash + Kibana terms panel without breaking wordsLogstash + Kibana 术语面板没有断词
【发布时间】:2014-11-14 19:36:45
【问题描述】:

我有一个以 json 格式写入日志文件的 Java 应用程序。 日志中的字段是可变的。 logstash 读取此日志文件并将其发送到 Kibana。

我已经使用以下文件配置了 logstash:

input {
        file {
                path => ["[log_path]"]
                codec => "json"
        }
}

filter{
        json {
                source => "message"
        }

        date {
                match => [ "data", "dd-MM-yyyy HH:mm:ss.SSS" ]
                timezone => "America/Sao_Paulo"
        }
}

output {
        elasticsearch_http {
                flush_size => 1
                host => "[host]"
                index => "application-%{+YYYY.MM.dd}"
        }
}

我已经成功地在 Kibana 中正确显示了所有内容,而无需任何映射。 但是当我尝试创建一个术语面板来显示发送这些消息的服务器的数量时,我遇到了问题。 我的 json 中有一个名为 server 的字段,它显示服务器名称(例如:a1-name-server1),但术语面板由于“-”而拆分了服务器名称。 我还想统计出现错误消息的次数,但同样的问题会发生,因为术语面板因为空格而拆分了错误消息。

我正在使用 Kibana 3 和 Logstash 1.4。 我在网上搜索了很多,找不到任何解决方案。 我也尝试使用 logstash 中的 .raw,但没有成功。

我该如何管理?

感谢您的帮助。

【问题讨论】:

    标签: java json logstash kibana


    【解决方案1】:

    您的问题是您的数据正在被标记化。这有助于对您的数据进行任何搜索。 ES(默认情况下)会将您的字段 message 拆分为不同的部分,以便能够搜索它们。例如,您可能希望在日志中搜索单词 ERROR,因此您可能希望在结果消息中看到“集群中有 错误”或“错误处理任何“。如果您不使用tokenizers 分析该字段的数据,您将无法进行这样的搜索。

    这种分析行为在您想要搜索内容时很有帮助,但它不允许您在具有相同内容的不同消息时进行分组。这是你的用例。对此的解决方案是更新您的映射,将 not_analyzed 用于您不想拆分为标记的特定字段。这可能适用于您的 host 字段,但可能会中断搜索。

    对于这种情况,我通常会使用index templatesmultifields。索引模板允许我为与正则表达式匹配的每个索引设置映射,并且多字段允许我在同一字段中具有 analyzednot_analyzed 行为。

    使用以下查询可以解决您的问题:

    curl -XPUT https://example.org/_template/name_of_index_template -d '
    {
        "template": "indexname*",
        "mappings": {
            "type": {
                "properties": {
                   "field_name": {
                      "type": "multi_field",
                      "fields": {
                         "field_name": {
                             "type": "string",
                             "index": "analyzed"
                         },
                         "untouched": {
                             "type": "string",
                             "index": "not_analyzed"
                         }                      
                     }
                }
            }
        }
    }'
    

    然后在您的术语面板中,您可以使用field.untouched,在计算不同元素的数量时考虑该字段的全部内容。

    如果您不想使用索引模板(也许您的数据在单个索引中),使用 Put Mapping API 设置映射也可以。如果使用多字段,则无需重新索引数据,因为从您为索引设置新映射的那一刻起,新数据将在这两个子字段(field_namefield_name.untouched)中重复。如果您只是将映射从 analyzed 更改为 not_analyzed,您将无法看到任何更改,直到您重新索引所有数据。

    【讨论】:

    • 我是否需要传递确切的字段名称而不是“field_name”,或者只是这样做将适用于所有字段?
    • @brunodahora 您必须指定字段名称。
    【解决方案2】:

    由于您没有在 elasticsearch 中定义映射,因此默认设置会针对您索引中类型中的每个字段进行。字符串字段(如您的服务器字段)的默认设置是分析字段,这意味着弹性搜索将标记字段内容。这就是为什么它将您的服务器名称拆分为多个部分的原因。

    您可以通过定义映射来解决此问题。您不必定义所有字段,只需定义您不想让 elasticsearch 分析的字段。在您的特定情况下,发送以下 put 命令可以解决问题:

    http://[host]:9200/[index_name]/_mapping/[type]
    
    {
        "type" : {
            "properties" : {
                "server" : {"type" : "string", "index" : "not_analyzed"}
            }
        }
    }
    

    您不能在已经存在的索引上执行此操作,因为从分析到 not_analyzed 的切换是映射的重大变化。

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多