集中式日志分析平臺 - ELK Stack - 踩坑集錦

前言

恩,開這篇文章的目的很明顯,就是因為踩坑太多,不知道去哪里記錄了,那么也一定會長期更新,遇到一個記錄一個。

問題集錦

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 HistogramFiled 選擇業務時間戳的情況下,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 下無法正常啟動,報錯如下:

image.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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容