Grafana系列-统一展示-8-ElasticSearch日志快速搜索仪表板
系列文章
概述
我们是基于这篇文章: Grafana 系列文章(十二):如何使用 Loki 创建一个用于搜索日志的 Grafana 仪表板, 创建一个类似的, 但是基于 ElasticSearch 的日志快速搜索仪表板.
最终完整效果如下:

Notes:
其实我基于 ElasticSearch 做了2个仪表板
- 用于检索 Applog 的
- 用于检索 accesslog 的
在下面的讲解中会综合2个仪表板来进行说明.
这次不会讲述详细细节, 只选择部分关键点进行说明.
知识储备
创建 Query
使用自定义的JSON字符串编写查询,field 在Elasticsearch索引映射中被映射为一个 keyword。
如果查询是 multi-field 的 text 和 keyword 类型,使用 "field": "fieldname.keyword"(有时是fieldname.raw)来指定你查询中的关键字字段。
Query
| Query | Description |
|---|---|
{"find": "fields", "type": "keyword"} |
返回一个索引类型为keyword 的字段名列表。 |
{"find": "terms", "field": "hostname.keyword", "size": 1000} |
使用 terms 聚合返回一个 keyword 的值列表。查询将使用当前仪表板的时间范围作为时间范围查询。 |
{"find": "terms", "field": "hostname", "query": '<Lucene query>'} |
使用terms 聚合和指定的Lucene查询过滤器,返回一个keyword field 的值列表。查询将使用当前仪表板的时间范围作为查询的时间范围。 |
terms 的查询默认有500个结果的限制。要设置一个自定义的限制,需要在你的查询中设置size属性。
Variable 语法
面板标题和 metric 查询可以使用多种不同的语法来引用变量:
$varname, 这种语法很容易阅读,但它不允许你在词的中间使用变量。例如:apps.frontend.$server.requests.count${var_name}, 当你想在表达式的中间插值一个变量时,请使用这种语法。${var_name:<format>}这种格式让你对Grafana如何插值有更多控制。[[varname]]不建议使用。废弃的旧语法,将在未来的版本中删除。
高级变量格式选项
变量插值的格式取决于数据源,但在有些情况下,你可能想改变默认的格式。
例如,MySql数据源的默认格式是以逗号分隔的方式连接多个值,并加引号, 如:'server01', 'server02'.在某些情况下,你可能希望有一个不带引号的逗号分隔的字符串, 如:server01,server02。你可以用下面列出的高级变量格式化选项来实现这一目的。
通用语法
语法: ${var_name:option}
可以在Grafana Play网站上测试格式化选项。
如果指定了任何无效的格式化选项,那么 glob 就是默认/回退选项。
CSV
将具有多个值的变量形成一个逗号分隔的字符串。
servers = ['test1', 'test2']
String to interpolate: '${servers:csv}'
Interpolation result: 'test1,test2'
分布式 - OpenTSDB
以OpenTSDB的自定义格式对具有多个值的变量进行格式化。
servers = ['test1', 'test2']
String to interpolate: '${servers:distributed}'
Interpolation result: 'test1,servers=test2'
双引号
将单值和多值变量形成一个逗号分隔的字符串,在单个值中用\"转义",并将每个值用""引号括起来。
servers = ['test1', 'test2']
String to interpolate: '${servers:doublequote}'
Interpolation result: '"test1","test2"'
Glob - Graphite
将具有多个值的变量组成一个glob(用于Graphite查询)。
servers = ['test1', 'test2']
String to interpolate: '${servers:glob}'
Interpolation result: '{test1,test2}'
JSON
将具有多个值的变量形成一个逗号分隔的字符串。
servers = ['test1', 'test2']
String to interpolate: '${servers:json}'
Interpolation result: '["test1", "test2"]'
Lucene - Elasticsearch
以Lucene格式对Elasticsearch的多值变量进行格式化。
servers = ['test1', 'test2']
String to interpolate: '${servers:lucene}'
Interpolation result: '("test1" OR "test2")'
URL 编码 (Percentencode)
对单值和多值变量进行格式化,以便在URL参数中使用。
servers = ['foo()bar BAZ', 'test2']
String to interpolate: '${servers:percentencode}'
Interpolation result: 'foo%28%29bar%20BAZ%2Ctest2'
Pipe
将具有多个值的变量形成一个管道分隔的字符串。
servers = ['test1.', 'test2']
String to interpolate: '${servers:pipe}'
Interpolation result: 'test1.|test2'
Raw
关闭数据源特定的格式化,如SQL查询中的单引号。
servers = ['test.1', 'test2']
String to interpolate: '${var_name:raw}'
Interpolation result: 'test.1,test2'
Regex
将有多个值的变量形成一个regex字符串。
servers = ['test1.', 'test2']
String to interpolate: '${servers:regex}'
Interpolation result: '(test1\.|test2)'
单引号
将单值和多值变量形成一个逗号分隔的字符串,在单个值中用\'转义',并将每个值用'引号括起来。
servers = ['test1', 'test2']
String to interpolate: '${servers:singlequote}'
Interpolation result: "'test1','test2'"
Sqlstring
将单值和多值变量组成一个逗号分隔的字符串,每个值中的'用''转义,每个值用'引号括起来。
servers = ["test'1", "test2"]
String to interpolate: '${servers:sqlstring}'
Interpolation result: "'test''1','test2'"
Text
将单值和多值变量转换成其文本表示法。对于一个单变量,它将只返回文本表示法。对于多值变量,它将返回与+相结合的文本表示法。
servers = ["test1", "test2"]
String to interpolate: '${servers:text}'
Interpolation result: "test1 + test2"
查询参数
将单值和多值变量编入其查询参数表示法。例如:var-foo=value1&var-foo=value2
servers = ["test1", "test2"]
String to interpolate: '${servers:queryparam}'
Interpolation result: "servers=test1&servers=test2"
配置变量选择选项
Selection Options 是一个你可以用来管理变量选项选择的功能。所有的选择选项都是可选的,它们在默认情况下是关闭的。
Multi-value Variables
内插一个选择了多个值的变量是很棘手的,因为如何将多个值格式化为一个在使用该变量的给定环境中有效的字符串并不直接。Grafana试图通过允许每个数据源插件告知模板插值引擎对多个值使用什么格式来解决这个问题。
Notes:
变量上的Custom all value选项必须为空,以便Grafana将所有值格式化为一个字符串。如果它留空,那么Grafana就会把查询中的所有值连接起来(加在一起)。类似于
value1,value2,value3。如果使用了一个自定义的所有值,那么该值将是类似于*或all的东西。
带有Prometheus或InfluxDB数据源的多值变量
InfluxDB和Prometheus使用regex表达式,所以host1, host2, host3 变量会被插值为{host1,host2,host3}。每个值都会被regex转义。
使用Elastic数据源的多值变量
Elasticsearch使用lucene查询语法,所以同样的变量会被格式化为("host1" OR "host2" OR "host3")。在这种情况下,每一个值都必须被转义,以便该值只包含lucene控制词和引号。
Include All 选项
Grafana在变量下拉列表中添加了一个 All 选项。如果用户选择了这个选项,那么所有的变量选项都被选中。
自定义 all 的值
这个选项只有在选择了 Include All option 时才可见。
在Custom all value字段中可以输入regex、globs或lucene语法来定义All选项的值。
默认情况下,All 值包括组合表达式中的所有选项。这可能会变得非常长,而且会产生性能问题。有时,指定一个自定义的所有值可能会更好,比如通配符。
为了在 Custom all value 选项中拥有自定义的regex、globs或lucene语法,它永远不会被转义,所以你将不得不考虑什么是你的数据源的有效值。
ElasticSearch Template Variables
选择一种 Variable 语法
如上文所述, Elasticsearch数据源支持在查询字段中使用多种变量语法.
当启用 Multi-value 或 Include all value 选项时,Grafana 会将标签从纯文本转换为与 Lucene 兼容的条件。即隐式转换 $varname 为 ${varname:lucene}
实战
1. 弄清楚有哪些索引字段
首先, 最重要的, 就是弄清楚该索引有哪些索引字段(fields), 以及有哪些keywords, 选择部分字段和 keywords 作为 varibles. 可以直接通过 Kibana 界面进行查询和尝试.
如本次选择的有:
app_namelevelrequest_path( 通过多次在 Kibana 上使用发现, 查询时应该使用request_path.keyword而不是request_path)request_methodstatus_code
2. 创建 Variables
app_name
设置如下:
- Name:
app_name - Type: Query
- Data source: ES
- Query:
{"find": "terms", "field": "current_app_name"}, 另外, 如果嵌套使用, 可以类似这样{"find": "terms", "field": "pod_name", "query": "app_name:$app_name"}
request_path
设置如下:
- 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 的表达式就会变成: request_path.keyword:* 而不是 request_path.keyword:(<path1> OR <path2> ...)
request_method
request_method 常用的就这么几个:
- GET
- POST
- DELETE
- HEAD
- PUT
- PATCH
- OPTIONS
所以可以将其设置为 Custom variable, 设置如下:
- 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
日志级别可以直接使用 Custom 类型变量. 如下:
- Name:
level - Type:
Custom - Values separated by comma:
INFO, WARN, ERROR,FATAL - Multi-value: ️
- Include All option: ️
如果只关注错误日志, 那么 level 变量的默认值可以设置为同时勾选: ERROR 和 FATAL
status_code
这里会将 status_code variable 用于 Lucene 的范围语法 [](包括开头和结尾的2个数字), 所以有用到Custom all value 以及 Variable 语法配置.
- 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 状态码, 从 200 到 599)
后续要在 Query 中使用, 用法如下:
status_code:[${status_code:raw}]
直接使用 ${status_code:raw}, 这样传入就会变成:
status_code:[200 TO 299]
status_code:[200 TO 599]
按期望完成对 ES 的查询.
filter
最后, 还添加一个 Ad hoc filters variable, 方便用户进行更多自定义的过滤筛选.
- Name: filter
- Type:
Ad hoc filters - Data source:
${datasource}
后续会在该 Dashboard 的所有 Query 中自动使用. 一个典型使用场景如下:
对于 request_path, 需要过滤监控/健康检查等请求(包含info health metric 等关键词), 那么可以将该 filter 保存为默认的变量值.

3. Panel
Dashboard 只有 2 个面板组成:
- 上图: Time series, 显示日志柱状图, 并着色,
INFO日志为绿色,WARN日志为黄色,ERROR和FATAL日志为红色. - 下日志
Time series panel
如下图:

可以通过如下 Query 实现:
app_name:$app_name AND level:($level AND INFO)
app_name:$app_name AND level:($level AND ERROR or FATAL)
$level AND INFO 这种写法是一个 workaround, 为的是在 level 变量改变时, Time series panel 随之改变.
另外一个需要注意的点是, Metric 是 Count(日志条数) 而不是 Logs (具体日志).
还有, 需要配置 Override -> Color, 如下:

最后, 如果柱子太密, 可以通过调整如 3 Colors Time series panel 图中的 Interval 来调整时间间隔, 本例调整为 1m
Logs panel
在 Logs panel 中, 也可以根据实际情况做一系列调整.
如下图, 可以对日志展示方式做调整:

- Time: 是否加时间戳
- Unique labels: 是否每条日志加 label
- Common labels: 是否对 logs panel 左上角对所有日志加 common labels
- Wrap lines
- Pretify JSON: JSON 美化
- Enable log details: 启用查看日志详细信息
- Deduplication: 日志去重, 去重方式有:
- None: 不去重
- Exact: 精确去重
- Numbers: 不同数字记为同一类的去重方式
- Signature: 根据计算得出的 Signature 去重
- Order: 排序.
另外, 考虑到 ES 日志的 log details 会有很多我们不关注的 fields, 如: _source _id 等, 可以通过 Transform 进行转换调整. 具体如下图:

总结
这篇文章算是该系列文章的一个重点了. 包含了非常多的实用细节.
如:
- ES Query
- Variable 语法
- Variable raw 语法
- Lucene - Elasticsearch 语法
- …
- Multi-value Variables
- Include All 选项
- 自定义 all 的值
Ad hoc filtersVariable- ES Metric Type
- Count
- Logs
- …
- 调整Query 时间间隔
- Logs panel 设置
- Panel Transform
希望对你有所帮助.
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
Grafana系列-统一展示-8-ElasticSearch日志快速搜索仪表板的更多相关文章
- Grafana 系列文章(十二):如何使用Loki创建一个用于搜索日志的Grafana仪表板
概述 创建一个简单的 Grafana 仪表板, 以实现对日志的快速搜索. 有经验的直接用 Grafana 的 Explore 功能就可以了. 但是对于没有经验的人, 他们如何能有一个已经预设了简单的标 ...
- Grafana 系列文章(六):Grafana Explore 中的日志
️URL: https://grafana.com/docs/grafana/latest/explore/logs-integration/#labels-and-detected-fields D ...
- Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
简介 Grafana Labs 简介 Grafana 是用于时序数据的事实上的仪表盘解决方案.它支持近百个数据源. Grafana Labs 想从一个仪表盘解决方案转变成一个可观察性 (observa ...
- Grafana 系列文章(十一):Loki 中的标签如何使日志查询更快更方便
️URL: https://grafana.com/blog/2020/04/21/how-labels-in-loki-can-make-log-queries-faster-and-easier/ ...
- logstash+elasticsearch+kibana快速搭建日志平台
使用logstash+elasticsearch+kibana快速搭建日志平台 日志的分析和监控在系统开发中占非常重要的地位,系统越复杂,日志的分析和监控就越重要,常见的需求有: 根据关键字查询日 ...
- go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务
0.索引 go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务 0.1源码地址 https://github.com/liuyuede123/go-zero ...
- Grafana 系列文章(十):为什么应该使用 Loki
️URL: https://grafana.com/blog/2020/09/09/all-the-non-technical-advantages-of-loki-reduce-costs-stre ...
- Grafana 系列文章(十四):Helm 安装Loki
前言 写或者翻译这么多篇 Loki 相关的文章了, 发现还没写怎么安装 现在开始介绍如何使用 Helm 安装 Loki. 前提 有 Helm, 并且添加 Grafana 的官方源: helm repo ...
- 分布式监控系统Zabbix--使用Grafana进行图形展示
今天介绍一款高颜值监控绘图工具Grafana,在使用Zabbix监控环境中,通常我们会结合Grafana进行图形展示.Grafana默认没有zabbix作为数据源,需要手动给zabbix安装一个插 ...
- 性能测试五十:Jmeter+Influxdb+Grafana实时数据展示系统搭建
如果用生成jtl文件再分析结果的方式的话,每一次请求就会往jtl里面写一条数据,在进行长时间的稳定性测试的时候,特别是当TPS很高的时候,写入的数据会非常的大,这个时候等稳定性测试完成,再对jtl进行 ...
随机推荐
- [BUUCTF]HCTF 2018WarmUp1 write up
ctrl+U查看源代码, 如下: 访问提示中的source.php文件 发现显示了源码,且存在另一个PHP文件hint.php(提示.php),先查看文件内是否有信息 用file来传参,并且要绕过wh ...
- C#中Base64转换为byte[]再进行处理
byte[] arr = Convert.FromBase64String(temp.Substring(temp.IndexOf(",") + 1)); using (Strea ...
- idea中执行“npm/yarn”命令,提示'node/yarn' 不是内部或外部命令,也不是可运行的程序
问题:idea中执行"npm/yarn"命令,提示'node/yarn' 不是内部或外部命令,也不是可运行的程序.但是在本地打开cmd 是可以运行npm/yarn命令的 解决方法: ...
- C++温故补缺(十九):atomic类
atomic 参考:c++11 多线程(3)atomic 总结 - 简书.c++11 atomic Npgw的博客.C++11 并发指南系列 - Haippy - 博客园. atomic_flag a ...
- springboot实现短信验证码的发送
我使用的是阿里云短信服务 代码前的准备 1. 申请阿里云的短信服务 2. 添加签名,这里需要等待审核通过 3. 在模板管理设置自己的短信模板 下面添加模板,选择验证码,模板内容可以直接使用输入框内的示 ...
- VW
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue3 封装el-table时,构造$children(类式写法)
由于业务需求(组件封装),需要在获取el-table下面的el-table-column实例 在 vue2.x 当中直接使用this.$children就可以获取到该实例 但是 vue3.x 弃用了$ ...
- AlphaFold2无痛安装教程(超级详细)
目录 介绍 环境 安装 CMAKE安装 hmmer安装 HHsuite安装 Kalign安装 OpenMM安装 PDBfixer安装 Python依赖包安装 AlphaFold安装 AlphaFold ...
- 生产计划问题(动态规划)—R实现
动态规划 动态规划(英语:Dynamic programming,简称 DP),是一种在数学.管理科学.计算机科学.经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方 ...
- pywin32获取键盘状态,附带键位码
import win32apiimport win32con win32con.VK_CAPITAL # 20获取Caps Lock键编码 win32api.GetKeyState(win32con. ...