我有一个Java应用程序,它以json格式写入日志文件。 日志中的字段是可变的。 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,但它没有用。
我该如何管理?
感谢您的帮助。
答案 0 :(得分:4)
您的问题是您的数据正在标记化。这有助于对您的数据进行任何搜索。 ES(默认情况下)会将您的字段message
拆分为不同的部分,以便能够搜索它们。例如,您可能希望在日志中搜索单词ERROR
,因此您可能希望在结果消息中看到"群集中存在错误&# 34;或" 错误处理任何"。如果您不使用tokenizers分析该字段的数据,则无法像这样进行搜索。
此分析行为在您要搜索内容时很有用,但它不允许您在具有相同内容的不同邮件时进行分组。这是你的用例。解决此问题的方法是更新您不希望分割为令牌的特定字段的not_analyzed
映射。这可能适用于您的host
字段,但可能会破坏搜索。
我通常为这种情况做的是使用index templates和multifields。索引模板允许我为与正则表达式匹配的每个索引设置映射,并且多字段允许我在同一字段中具有analyzed
和not_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_name
和{{1} })。如果您只是将映射从field_name.untouched
更改为analyzed
,则在重新索引所有数据之前,您将无法看到任何更改。
答案 1 :(得分:1)
由于您没有在elasticsearch中定义映射,因此默认设置会针对您索引中类型中的每个字段进行。字符串字段(如服务器字段)的默认设置是 分析 字段,这意味着弹性搜索会对字段内容进行标记。这就是为什么它将您的服务器名称拆分为部分。
您可以通过定义映射来克服此问题。您不必定义所有字段,只能定义您不希望弹性搜索进行分析的字段。在您的特定情况下,发送以下put命令将起到作用:
http://[host]:9200/[index_name]/_mapping/[type]
{
"type" : {
"properties" : {
"server" : {"type" : "string", "index" : "not_analyzed"}
}
}
}
您无法在现有索引上执行此操作,因为从已分析切换到not_analyzed是映射中的重大更改。