http://www.jianshu.com/p/2d86eafc3e94
前言
恩,开这篇文章的目的很明显,就是因为踩坑太多,不知道去哪里记录了,那么也一定会长期更新,遇到一个记录一个。
问题集锦
Kibana 篇
Question - K001 :
打开 Kibana 界面遇到 Login is disabled because your license has expired. Please extend your license or disable Security in Elasticsearch.
Answer :
说明体验的 x-pack 功能证书过期,需要 disable 之后才可以恢复使用,在 elasticsearch.yml
中添加:
xpack.security.enabled: false
后进行重启即可。
Question - K002 :
修改了 default index pattern 之后打开 Kibana 界面的 Management 页面报错( URL 请求为:http://172.16.134.3:5601/elasticsearch/packetbeat-*/_mapping/field/*?_=1490863194201&ignore_unavailable=false&allow_no_indices=false&include_defaults=true
): 404 Not Found.
Answer :
因为设置了一个不存在的 elasticsearch index,情况类似https://github.com/elastic/kibana/issues/9028, 需要重置 default index:
curl -XPOST 'http://${ES_HOSTNAME}:${ES_HOST_PORT}/.kibana/_update_by_query?pretty&wait_for_completion&refresh' -H 'Content-Type: application/json' -d' { "script": { "inline": "ctx._source.defaultIndex = null", "lang": "painless" }, "query": { "term": { "_type": "config" } } } '
Question - K003 :
浏览器总是无法显示数据,但是在链路中 debug 数据是正常流转的。
Answer:
可能是操作系统时间问题,Kibana 的时间选取是以操作系统的时间戳作为基础的。
Question - K004 :
卸载 ES 和 Kibana 的 X-pack 之后,Kibana 报错:
license information could not be obtained from elasticsearch
Answer:
需要在 kibana.yml 中申明 xpack.security.enabled: false
。
Logstash 篇
Question - L001 :
假设输入是 Kafka,采集端是 filebeat,如何得到 beat 中的相关指标,比如日志源 hostname?
Answer
这个问题困扰了我一会,看到了网上的解法:https://discuss.elastic.co/t/reading-beats-fields-from-kafka-input/76206/3, 那么细节配置大致为修改 logstash.conf
中的 filter
块:
...filter { json { source => "message" target => "message_json" } mutate { add_field => { "${new_field_name}" => "%{[message_json][beat][hostname]}" } } } ...
还有一种办法是在 input
段中配置:
input { kafka { codec => "json" } }
Question - L002 :
如何把自定义类似时间戳的 pattern 解析到的字段转化成 date 类型,以供排序?
Answer:
官方文档明确说明尽量不要使用 text filed 去做排序聚合,否则会使用大量的内存:https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html。
报错类型如下:
Fielddata is disabled on text fields by default. Set fielddata=true on [your_field_name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.
所以我们要对自定义时间戳 pattern 解析到的字段转成 date 类型,具体方法如下:
Step1. 在 patterns 目录下新建 extra 文件用于申明自定义 pattern;
Step2. 在 logstash 的 filter 块中,使用 pattern 去匹配字段:
...filter { grok { patterns_dir => "./patterns" match => [ "message" => "%{TIMESTAMP_PYTHON:log_timestamp}" ] } } ...
Step3. 在 logstash 的 filter 块中,使用 date 去转换字段为 date 类型:
...filter { ... date { match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss,SSS" ] target => "log_timestamp" } } ...
Question - L003:
采集 cron 日志 ( /var/log/cron
) 时,得到的指令数据中含有 unicode 编码,比如运行指令为 /usr/bin/tsar --cron >/dev/null 2>&1
被解析成了 /usr/bin/tsar --cron \u003e/dev/null 2\u003e\u00261
。
Answer:
在 input
配置块中添加 codec => "json"
,这样可以解码后再进行解析,得到想要的结果。
参考文献:Filebeat error. Returns unicode character code instead of symbol
Question - L004:
ES 索引已经建立的情况下,修改 logstash 解析规则,想让原先已经是 String 类型的 field 转换成 integer,但是做了如下修改(参考文献), ES 中的字段类型却没有改变:
# 方法一:在 pattern 中申明强转filter { grok { match => { "message" => "%{NUMBER:your_field_name:int}" } } }# 方法二:在 mutate 中申明强转filter { mutate { convert => { "your_field_name" => "integer" } } }
次奥,为什么我遇到了和这个哥们一样的问题:How can convert field to int, float
Answer:
我们使用如下方法首先确认 logstash 中是否有被正常解析,在 logstash.conf
中添加如下配置:
output { stdout { codec => rubydebug } }
我们在 /var/log/messages
中查看数据格式是否正确,一般来说 logstash 不会有问题,正常输出如下:
# 正常输出"your_field_name" => 1# 错误输出"your_field_name" => "1"
因此我们只需要删除 ES index 即可完成类型更新,原因是在 logstash 端进行了转换之后, ES 仍旧会按照最初的类型进行定义,我们来尝试删除 index:
curl -XDELETE 'localhost:9200/%{index_prefix}-*?pretty'
切记必须删除所有前缀匹配的 index,否则 Kibana 端会报类型冲突。
Question - L005:
Logstash 报错发现写入 ES 时返回 429:
[2017-05-22T15:59:33,624][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 429 ({"type"=>"es_rejected_execution_exception", "reason"=>"rejected execution of org.elasticsearch.transport.TransportService$7@4469fa3b on EsThreadPoolExecutor[bulk, queue capacity = 50, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@38eb0898[Running, pool size = 12, active threads = 12, queued tasks = 56, completed tasks = 3864]]"}) [2017-05-22T15:59:34,269][ERROR][logstash.outputs.elasticsearch] Action
并且数据统计后发现缺失;
Answer:
请注意看这个 issue,里面提到了类似问题。日志的解释是因为 ES threadpool.bulk.queue_size 受限导致 Logstash 写入被拒绝,对于 bulk action failed 这个事件的报错语义不清晰的问题会在6.X版本修复,但是没有解释问题的本身(为什么有数据缺失)。关键不是这个,是解决方法,调整 ES Xss=10m。
Question - L006:
我想替换掉默认的 @timestamp
字段,不用它进行数据排序,而是使用我的日志时间戳,但是使用业务时间戳在进行报表渲染的时候加载数据非常慢,比如这样的场景:选择 line-chart
,Y轴选择任意指标聚合,X轴选择 Date Histogram
,Filed
选择业务时间戳的情况下,Interval
不能选择 auto
。这样在大时间 range 的聚合时,报表会显示非常慢,经常超时无法完成请求。原因是比如我们 Interval
选择分钟,但是我时间跨度选择一个月,那样需要绘制的点就茫茫多自然慢(其实跨度一个月,我按照天去绘制点就够了),怎么办?
Answer:
使用业务时间戳替换掉 @timestamp
,因为默认的业务时间戳是支持 auto 的,如下图:
屏幕快照 2017-05-23 下午8.46.37.png
解法是在 date
过滤器中进行如下配置:
date { match => [ "log_timestamp", "MMM dd HH:mm:ss" ] }
其中 MMM dd HH:mm:ss 是业务时间戳的格式。
Filebeat 篇
Question - F001:
Filebeat 5.2.1 在 centOS 7 下无法正常启动,报错如下:
p_w_picpath.png
Exiting: Could not start registrar: Error loading state: Error decoding states: EOF
Answer:
类似 Filebeat Fails After Power Failure,在断电或者版本升级之后都可能概率性触发,root couse 是在异常情况下 registry 文件没有 EOF 标识符。这种情况下,需要删除 registry 文件才可以启动成功。
rm -r registry systemctl reset-failed filebeat systemctl start filebeat