系列文章
概述
我們是基于這篇文章: Grafana 系列文章(十二):如何使用 Loki 創(chuàng)建一個(gè)用于搜索日志的 Grafana 儀表板, 創(chuàng)建一個(gè)類(lèi)似的, 但是基于 ElasticSearch 的日志快速搜索儀表板.
最終完整效果如下:
??Notes:
其實(shí)我基于 ElasticSearch 做了2個(gè)儀表板
- 用于檢索 Applog 的
- 用于檢索 accesslog 的
在下面的講解中會(huì)綜合2個(gè)儀表板來(lái)進(jìn)行說(shuō)明.
這次不會(huì)講述詳細(xì)細(xì)節(jié), 只選擇部分關(guān)鍵點(diǎn)進(jìn)行說(shuō)明.
知識(shí)儲(chǔ)備
創(chuàng)建 Query
使用自定義的JSON字符串編寫(xiě)查詢(xún),field 在Elasticsearch索引映射中被映射為一個(gè) keyword囊扳。
如果查詢(xún)是 multi-field 的 text
和 keyword
類(lèi)型椅亚,使用 "field": "fieldname.keyword"
(有時(shí)是fieldname.raw
)來(lái)指定你查詢(xún)中的關(guān)鍵字字段遇八。
Query
Query | Description |
---|---|
{"find": "fields", "type": "keyword"} |
返回一個(gè)索引類(lèi)型為keyword 的字段名列表雷蹂。 |
{"find": "terms", "field": "hostname.keyword", "size": 1000} |
使用 terms 聚合返回一個(gè) keyword 的值列表滔岳。查詢(xún)將使用當(dāng)前儀表板的時(shí)間范圍作為時(shí)間范圍查詢(xún)身隐。 |
{"find": "terms", "field": "hostname", "query": '<Lucene query>'} |
使用terms 聚合和指定的Lucene查詢(xún)過(guò)濾器邀泉,返回一個(gè)keyword field 的值列表。查詢(xún)將使用當(dāng)前儀表板的時(shí)間范圍作為查詢(xún)的時(shí)間范圍胚迫。 |
terms
的查詢(xún)默認(rèn)有500個(gè)結(jié)果的限制堕仔。要設(shè)置一個(gè)自定義的限制,需要在你的查詢(xún)中設(shè)置size
屬性晌区。
Variable 語(yǔ)法
面板標(biāo)題和 metric 查詢(xún)可以使用多種不同的語(yǔ)法來(lái)引用變量:
-
$varname
, 這種語(yǔ)法很容易閱讀摩骨,但它不允許你在詞的中間使用變量。例如:apps.frontend.$server.requests.count
-
${var_name}
, 當(dāng)你想在表達(dá)式的中間插值一個(gè)變量時(shí)朗若,請(qǐng)使用這種語(yǔ)法恼五。 -
${var_name:<format>}
這種格式讓你對(duì)Grafana如何插值有更多控制。 -
[[varname]]
不建議使用哭懈。廢棄的舊語(yǔ)法灾馒,將在未來(lái)的版本中刪除。
高級(jí)變量格式選項(xiàng)
變量插值的格式取決于數(shù)據(jù)源遣总,但在有些情況下睬罗,你可能想改變默認(rèn)的格式轨功。
例如,MySql數(shù)據(jù)源的默認(rèn)格式是以逗號(hào)分隔的方式連接多個(gè)值容达,并加引號(hào), 如:'server01', 'server02'
.在某些情況下古涧,你可能希望有一個(gè)不帶引號(hào)的逗號(hào)分隔的字符串, 如:server01,server02
。你可以用下面列出的高級(jí)變量格式化選項(xiàng)來(lái)實(shí)現(xiàn)這一目的花盐。
通用語(yǔ)法
語(yǔ)法: ${var_name:option}
可以在Grafana Play網(wǎng)站上測(cè)試格式化選項(xiàng)羡滑。
如果指定了任何無(wú)效的格式化選項(xiàng),那么 glob
就是默認(rèn)/回退選項(xiàng)算芯。
CSV
將具有多個(gè)值的變量形成一個(gè)逗號(hào)分隔的字符串柒昏。
servers = ['test1', 'test2']
String to interpolate: '${servers:csv}'
Interpolation result: 'test1,test2'
分布式 - OpenTSDB
以O(shè)penTSDB的自定義格式對(duì)具有多個(gè)值的變量進(jìn)行格式化。
servers = ['test1', 'test2']
String to interpolate: '${servers:distributed}'
Interpolation result: 'test1,servers=test2'
雙引號(hào)
將單值和多值變量形成一個(gè)逗號(hào)分隔的字符串熙揍,在單個(gè)值中用\"
轉(zhuǎn)義"
职祷,并將每個(gè)值用""
引號(hào)括起來(lái)。
servers = ['test1', 'test2']
String to interpolate: '${servers:doublequote}'
Interpolation result: '"test1","test2"'
Glob - Graphite
將具有多個(gè)值的變量組成一個(gè)glob(用于Graphite查詢(xún))届囚。
servers = ['test1', 'test2']
String to interpolate: '${servers:glob}'
Interpolation result: '{test1,test2}'
JSON
將具有多個(gè)值的變量形成一個(gè)逗號(hào)分隔的字符串有梆。
servers = ['test1', 'test2']
String to interpolate: '${servers:json}'
Interpolation result: '["test1", "test2"]'
Lucene - Elasticsearch
以Lucene格式對(duì)Elasticsearch的多值變量進(jìn)行格式化。
servers = ['test1', 'test2']
String to interpolate: '${servers:lucene}'
Interpolation result: '("test1" OR "test2")'
URL 編碼 (Percentencode)
對(duì)單值和多值變量進(jìn)行格式化奖亚,以便在URL參數(shù)中使用。
servers = ['foo()bar BAZ', 'test2']
String to interpolate: '${servers:percentencode}'
Interpolation result: 'foo%28%29bar%20BAZ%2Ctest2'
Pipe
將具有多個(gè)值的變量形成一個(gè)管道分隔的字符串析砸。
servers = ['test1.', 'test2']
String to interpolate: '${servers:pipe}'
Interpolation result: 'test1.|test2'
Raw
關(guān)閉數(shù)據(jù)源特定的格式化昔字,如SQL查詢(xún)中的單引號(hào)。
servers = ['test.1', 'test2']
String to interpolate: '${var_name:raw}'
Interpolation result: 'test.1,test2'
Regex
將有多個(gè)值的變量形成一個(gè)regex字符串首繁。
servers = ['test1.', 'test2']
String to interpolate: '${servers:regex}'
Interpolation result: '(test1\.|test2)'
單引號(hào)
將單值和多值變量形成一個(gè)逗號(hào)分隔的字符串作郭,在單個(gè)值中用\'
轉(zhuǎn)義'
,并將每個(gè)值用'
引號(hào)括起來(lái)弦疮。
servers = ['test1', 'test2']
String to interpolate: '${servers:singlequote}'
Interpolation result: "'test1','test2'"
Sqlstring
將單值和多值變量組成一個(gè)逗號(hào)分隔的字符串夹攒,每個(gè)值中的'
用''
轉(zhuǎn)義,每個(gè)值用'
引號(hào)括起來(lái)胁塞。
servers = ["test'1", "test2"]
String to interpolate: '${servers:sqlstring}'
Interpolation result: "'test''1','test2'"
Text
將單值和多值變量轉(zhuǎn)換成其文本表示法咏尝。對(duì)于一個(gè)單變量,它將只返回文本表示法啸罢。對(duì)于多值變量编检,它將返回與+
相結(jié)合的文本表示法。
servers = ["test1", "test2"]
String to interpolate: '${servers:text}'
Interpolation result: "test1 + test2"
查詢(xún)參數(shù)
將單值和多值變量編入其查詢(xún)參數(shù)表示法扰才。例如:var-foo=value1&var-foo=value2
servers = ["test1", "test2"]
String to interpolate: '${servers:queryparam}'
Interpolation result: "servers=test1&servers=test2"
配置變量選擇選項(xiàng)
Selection Options 是一個(gè)你可以用來(lái)管理變量選項(xiàng)選擇的功能允懂。所有的選擇選項(xiàng)都是可選的,它們?cè)谀J(rèn)情況下是關(guān)閉的衩匣。
Multi-value Variables
內(nèi)插一個(gè)選擇了多個(gè)值的變量是很棘手的蕾总,因?yàn)槿绾螌⒍鄠€(gè)值格式化為一個(gè)在使用該變量的給定環(huán)境中有效的字符串并不直接粥航。Grafana試圖通過(guò)允許每個(gè)數(shù)據(jù)源插件告知模板插值引擎對(duì)多個(gè)值使用什么格式來(lái)解決這個(gè)問(wèn)題。
??Notes:
變量上的Custom all value選項(xiàng)必須為空生百,以便Grafana將所有值格式化為一個(gè)字符串递雀。如果它留空,那么Grafana就會(huì)把查詢(xún)中的所有值連接起來(lái)(加在一起)置侍。類(lèi)似于
value1,value2,value3
映之。如果使用了一個(gè)自定義的所有值,那么該值將是類(lèi)似于*
或all
的東西蜡坊。
帶有Prometheus或InfluxDB數(shù)據(jù)源的多值變量
InfluxDB和Prometheus使用regex表達(dá)式杠输,所以host1
, host2
, host3
變量會(huì)被插值為{host1,host2,host3}
。每個(gè)值都會(huì)被regex轉(zhuǎn)義秕衙。
使用Elastic數(shù)據(jù)源的多值變量
Elasticsearch使用lucene查詢(xún)語(yǔ)法蠢甲,所以同樣的變量會(huì)被格式化為("host1" OR "host2" OR "host3")
。在這種情況下据忘,每一個(gè)值都必須被轉(zhuǎn)義鹦牛,以便該值只包含lucene控制詞和引號(hào)。
Include All 選項(xiàng)
Grafana在變量下拉列表中添加了一個(gè) All
選項(xiàng)勇吊。如果用戶選擇了這個(gè)選項(xiàng)曼追,那么所有的變量選項(xiàng)都被選中。
自定義 all 的值
這個(gè)選項(xiàng)只有在選擇了 Include All option 時(shí)才可見(jiàn)汉规。
在Custom all value字段中可以輸入regex礼殊、globs或lucene語(yǔ)法來(lái)定義All選項(xiàng)的值。
默認(rèn)情況下针史,All
值包括組合表達(dá)式中的所有選項(xiàng)晶伦。這可能會(huì)變得非常長(zhǎng),而且會(huì)產(chǎn)生性能問(wèn)題啄枕。有時(shí)婚陪,指定一個(gè)自定義的所有值可能會(huì)更好,比如通配符频祝。
為了在 Custom all value 選項(xiàng)中擁有自定義的regex泌参、globs或lucene語(yǔ)法,它永遠(yuǎn)不會(huì)被轉(zhuǎn)義常空,所以你將不得不考慮什么是你的數(shù)據(jù)源的有效值及舍。
ElasticSearch Template Variables
選擇一種 Variable 語(yǔ)法
如上文所述, Elasticsearch數(shù)據(jù)源支持在查詢(xún)字段中使用多種變量語(yǔ)法.
當(dāng)啟用 Multi-value 或 Include all value 選項(xiàng)時(shí),Grafana 會(huì)將標(biāo)簽從純文本轉(zhuǎn)換為與 Lucene 兼容的條件窟绷。即隱式轉(zhuǎn)換 $varname
為 ${varname:lucene}
實(shí)戰(zhàn)
1. 弄清楚有哪些索引字段
首先, 最重要的, 就是弄清楚該索引有哪些索引字段(fields), 以及有哪些keywords, 選擇部分字段和 keywords 作為 varibles. 可以直接通過(guò) Kibana 界面進(jìn)行查詢(xún)和嘗試.
如本次選擇的有:
app_name
level
-
request_path
(?? 通過(guò)多次在 Kibana 上使用發(fā)現(xiàn), 查詢(xún)時(shí)應(yīng)該使用request_path.keyword
而不是request_path
) request_method
status_code
2. 創(chuàng)建 Variables
app_name
設(shè)置如下:
- Name:
app_name
- Type: Query
- Data source: ES
- Query:
{"find": "terms", "field": "current_app_name"}
, 另外, 如果嵌套使用, 可以類(lèi)似這樣{"find": "terms", "field": "pod_name", "query": "app_name:$app_name"}
request_path
設(shè)置如下:
- Name:
request_path
- Type: Query
- Data source: ES
- Query:
{"find": "terms", "field": "request_path.keyword", "query": "app_name:$app_name"}
- Multi-value: ??
- Include All option: ??
- Custom all value:
*
?? 注意, 這里使用了 Custom all value, 最終 Query All 的表達(dá)式就會(huì)變成: request_path.keyword:*
而不是 request_path.keyword:(<path1> OR <path2> ...)
request_method
request_method
常用的就這么幾個(gè):
- GET
- POST
- DELETE
- HEAD
- PUT
- PATCH
- OPTIONS
所以可以將其設(shè)置為 Custom
variable, 設(shè)置如下:
- Name:
request_method
- Type: Custom
- Values separated by comma:
GET,POST,DELETE,HEAD, PUT,PATCH,OPTIONS
- Multi-value: ??
- Include All option: ??
- Custom all value:
*
level
日志級(jí)別可以直接使用 Custom 類(lèi)型變量. 如下:
- Name:
level
- Type:
Custom
- Values separated by comma:
INFO, WARN, ERROR,FATAL
- Multi-value: ??
- Include All option: ??
如果只關(guān)注錯(cuò)誤日志, 那么 level 變量的默認(rèn)值可以設(shè)置為同時(shí)勾選: ERROR
和 FATAL
status_code
這里會(huì)將 status_code
variable 用于 Lucene 的范圍語(yǔ)法 []
(包括開(kāi)頭和結(jié)尾的2個(gè)數(shù)字), 所以有用到Custom all value
以及 Variable 語(yǔ)法配置.
- Name:
status_code
- Type:
Custom
- Values separated by comma:
200 TO 299, 300 TO 399, 400 TO 499, 500 TO 599
- Include All option: ??
- Custom all value:
200 TO 599
(??Note: 即包括所有的 http 狀態(tài)碼, 從 200 到 599)
后續(xù)要在 Query 中使用, 用法如下:
status_code:[${status_code:raw}]
直接使用 ${status_code:raw}
, 這樣傳入就會(huì)變成:
status_code:[200 TO 299]
status_code:[200 TO 599]
按期望完成對(duì) ES 的查詢(xún).
filter
最后, 還添加一個(gè) Ad hoc filters
variable, 方便用戶進(jìn)行更多自定義的過(guò)濾篩選.
- Name: filter
- Type:
Ad hoc filters
- Data source:
${datasource}
后續(xù)會(huì)在該 Dashboard 的所有 Query 中自動(dòng)使用. 一個(gè)典型使用場(chǎng)景如下:
對(duì)于 request_path
, 需要過(guò)濾監(jiān)控/健康檢查等請(qǐng)求(包含info
health
metric
等關(guān)鍵詞), 那么可以將該 filter
保存為默認(rèn)的變量值.
3. Panel
Dashboard 只有 2 個(gè)面板組成:
- 上圖: Time series, 顯示日志柱狀圖, 并著色,
INFO
日志為綠色,WARN
日志為黃色,ERROR
和FATAL
日志為紅色. - 下日志
Time series panel
如下圖:
可以通過(guò)如下 Query 實(shí)現(xiàn):
app_name:$app_name AND level:($level AND INFO)
app_name:$app_name AND level:($level AND ERROR or FATAL)
$level AND INFO
這種寫(xiě)法是一個(gè) workaround, 為的是在 level 變量改變時(shí), Time series panel 隨之改變.
另外一個(gè)需要注意的點(diǎn)是, Metric
是 Count
(日志條數(shù)) 而不是 Logs
(具體日志).
還有, 需要配置 Override -> Color, 如下:
最后, 如果柱子太密, 可以通過(guò)調(diào)整如 3 Colors Time series panel
圖中的 Interval
來(lái)調(diào)整時(shí)間間隔, 本例調(diào)整為 1m
Logs panel
在 Logs panel 中, 也可以根據(jù)實(shí)際情況做一系列調(diào)整.
如下圖, 可以對(duì)日志展示方式做調(diào)整:
- Time: 是否加時(shí)間戳
- Unique labels: 是否每條日志加 label
- Common labels: 是否對(duì) logs panel 左上角對(duì)所有日志加 common labels
- Wrap lines
- Pretify JSON: JSON 美化
- Enable log details: 啟用查看日志詳細(xì)信息
- Deduplication: 日志去重, 去重方式有:
- None: 不去重
- Exact: 精確去重
- Numbers: 不同數(shù)字記為同一類(lèi)的去重方式
- Signature: 根據(jù)計(jì)算得出的 Signature 去重
- Order: 排序.
另外, 考慮到 ES 日志的 log details 會(huì)有很多我們不關(guān)注的 fields, 如: _source
_id
等, 可以通過(guò) Transform 進(jìn)行轉(zhuǎn)換調(diào)整. 具體如下圖:
總結(jié)
這篇文章算是該系列文章的一個(gè)重點(diǎn)了. 包含了非常多的實(shí)用細(xì)節(jié).
如:
- ES Query
- Variable 語(yǔ)法
- Variable raw 語(yǔ)法
- Lucene - Elasticsearch 語(yǔ)法
- …
- Multi-value Variables
- Include All 選項(xiàng)
- 自定義 all 的值
-
Ad hoc filters
Variable - ES Metric Type
- Count
- Logs
- …
- 調(diào)整Query 時(shí)間間隔
- Logs panel 設(shè)置
- Panel Transform
希望對(duì)你有所幫助.
三人行, 必有我?guī)? 知識(shí)共享, 天下為公. 本文由東風(fēng)微鳴技術(shù)博客 EWhisper.cn 編寫(xiě).