做运维和数据的同学应该都有这种感觉:日志和指标都堆在那边,业务方天天问“现在系统到底什么状态”“订单量涨了还是跌了”,你光靠命令行敲几个curl看结果,解释半天也讲不清楚。后面我把内部日志和业务索引统一收到 Easysearch 里,再用 Grafana 把数据画成大屏,问题一下就解决了,投到办公室电视上,谁路过都能看懂。
这篇就聊聊我实际把 Grafana 对接 Easysearch、再从零搭出一块可视化大屏的完整过程。覆盖数据源接入、索引与时间字段设置、常用图表的查询写法、大屏布局与自动刷新,最后把常见报错和排坑经验一起整理出来。如果你也想给公司做一个“数据可视化大屏”,或者只是想把 Easysearch 里的数据用更直观的方式展示出来,这篇可以直接照着抄。
1. 项目思路与方案选型
1.1 为什么是 Grafana 配 Easysearch
先说说选型。Easysearch 是国内团队维护的开源分布式搜索引擎,兼容 Elasticsearch 的 7.10 API,也就是说你原来跑在 ES 上的代码、索引、查询语法,切换过去基本不用改。我当时选它,是因为它对中文分词和国产化环境支持更友好,部署也轻量,一个 Java 服务就起来了。
那可视化端为什么用 Grafana?最直接的原因就是它不需要像 Kibana 那样“绑定”某一套搜索引擎。Grafana 本身是一个数据可视化平台,支持几十种数据源:Prometheus、MySQL、ClickHouse、Elasticsearch、Easysearch 这类 ES 兼容 API 的引擎也能直接接。这样以后就算底层换存储,大屏和告警规则可以复用,不会被一家技术栈锁死。
另外 Grafana 做大屏确实方便。面板类型丰富、布局自由、支持模板变量,还可以通过 URL 参数一键进入 kiosk 全屏模式,刷新频率能调到秒级。这些特性特别适合做业务监控大屏、日志实时监控屏,甚至数据运营展示屏。
1.2 接入路径对比:原生数据源还是中间网关
Easysearch 这套系统接 Grafana,主流有三条路,我挨个试过,给你对比下:
| 方案 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|
| Grafana Elasticsearch 数据源直连 | 在 Grafana 里添加 ES 数据源,URL 指向 Easysearch 的 HTTP 端口 | 零额外组件,配置简单,查询语法通用 | 不支持 ES SQL,必须用 Lucene 和 DSL 聚合 |
| 通过代理或网关转换 | 用 INFINI Console 或自研网关把查询请求转成 Easysearch 能识别的格式 | 可以实现更复杂的权限控制和查询改写 | 多一层组件,维护成本高 |
| 导入外部 Dashboard JSON | 直接复用社区做好的 ES Dashboard 模板 | 速度快,图表演示效果直接 | 容易出现数据源版本或字段不匹配,需要二次修改 |
我的建议是:如果你只是想做可视化展示,第一套方案就够了。ES 数据源对 Easysearch 的兼容性做得很好,我用的版本是 Grafana 10.x,数据源版本选 7.10+,实测查询、聚合、日志面板都没问题。只有当你需要把多个 Easysearch 集群统一到一个大屏、或者要做字段级权限隔离的时候,才值得考虑引入网关。
1.3 整体链路与前置准备
整套系统的链路是这样的:
Easysearch 集群负责存储日志、业务指标和订单数据,Grafana 通过 Elasticsearch 数据源插件,把 HTTP 请求发到 Easysearch 的 REST API。Grafana 收到查询结果后,在前端渲染成折线图、柱状图、饼图、表格或日志流。
实际操作前需要确认几件事:
- Easysearch 已经启动,能通过浏览器访问
http://IP:9200,并且能看到集群健康状态。 - 索引里有明确的日期字段,比如
@timestamp或timestamp,Grafana 做时间过滤和趋势图依赖这个字段。 - 你知道索引名称或通配符,比如
app-log-*、order-info-*。 - Grafana 服务器到 Easysearch 的 9200 端口网络通,如果 Easysearch 开启了认证,提前准备好账号密码。
准备工作完成后,就可以开始接数据源了。
2. Grafana 数据源接入实操
2.1 Grafana 安装与初始配置
Grafana 安装很简单,我这边是 Linux 环境,直接下载 RPM 包装上:
sudo yum install -y grafana-enterprise-10.4.0-1.x86_64.rpm sudo systemctl start grafana-server sudo systemctl enable grafana-server装好后浏览器打开http://IP:3000,默认账号密码都是 admin,首次登录会强制改密码。如果你的服务器上有 Nginx,可以反代一个域名,把大屏地址暴露给内网其他同学观看。
这一步没什么坑,但有一点值得注意:如果 Grafana 和 Easysearch 部署在不同机器,记得检查防火墙和 SELinux,我在测试环境就遇到过明明curl9200 通,但 Grafana 里测试数据源一直失败的情况,最后发现是 Grafana 所在机器有代理环境变量http_proxy,导致请求走了代理。排查时先看 Grafana 服务日志,里面会直白地告诉你连接失败原因。
2.2 添加 Easysearch 数据源
在 Grafana 左侧菜单找到 Connections → Data sources,点 Add data source,搜索 Elasticsearch,进入配置页面。注意别搜 Easysearch,因为 Grafana 官方没有单独的 Easysearch 插件,直接用 ES 数据源加上就行。
配置项我按下表填:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| Name | Easysearch | 自定义,最终会显示在大屏的数据源标签里 |
| URL | http://127.0.0.1:9200 | Easysearch 的 HTTP 接口地址 |
| Access | Server(默认) | 浏览器访问 Grafana 时,由 Grafana 转发请求到 ES |
| Index name | app-log-* | 支持通配符,多个索引用逗号分隔 |
| Time field name | @timestamp | 必填,指定时间字段 |
| Version | 7.10+ | 兼容 Easysearch 的 ES API 版本 |
| Min time interval | 30s | 限制最小查询粒度,防止误操作把 ES 打挂 |
| Max concurrent shard requests | 3 | 限制并发,集群压力大时可以调小 |
填完点 Save & test,看到绿色的 “Data source is working” 提示,数据源就算接上了。如果报错,多半是 URL 填错、端口不通、索引时间字段名不对,或者认证信息缺失,逐个排查很快。
2.3 索引模式、时间字段与版本兼容性
这里单独说下怎么避免后边查不到数据。
Grafana 每次发起查询都会自动拼一个过滤条件,把时间范围加到时间字段上,比如:
{ "query": { "bool": { "must": [ {"range": {"@timestamp": {"gte": "now-6h", "lte": "now"}}} ] } } }所以时间字段必须存在,而且类型必须是date。如果你的索引里时间字段叫timestamp,但 mapping 里是keyword类型,Grafana 会直接报 “No date field named timestamp found”,或者干脆数据是零。
版本兼容性这块,Easysearch 兼容的是 ES 7.10 API,所以 Grafana 数据源里的 Version 我强烈建议选 7.10+,不要选 8.0+ 或 2.x,因为不同版本的查询 DSL 有些细小的差异,选错了可能在部分聚合函数上出现兼容报错。我实测选 7.10+ 时,Terms 聚合、Date Histogram、Filters 聚合都能正常工作。
2.4 初次验证查询
数据源保存之后,打开 Grafana 左侧的 Explore 页面,顶部选择刚建好的 Easysearch 数据源,然后输入查询。
最简单的验证方法,可以先切到 Query Builder 模式,直接选 Count 聚合,再选 Date Histogram,字段选 @timestamp,点击 Run query,如果能看到直方图,说明链路已经通了。
如果是比较习惯 Lucene 语法,也可以直接在 Query Builder 的 Lucene Query 框里写:
level: ERROR然后 Run query,就能看到筛选后的计数趋势。Explore 模式的优势是所见即所得,查出来的结果让你对索引里到底有哪些字段、哪些数据量级一目了然,为后边建大屏打底。
3. 面板搭建与查询语法详解
3.1 经典折线图:日期直方图与计数/均值
先做一个最常用的:系统每分钟产生多少条 ERROR 日志。这个面板是大屏的标配,能直观反映系统异常出现的频率。
选择 Time series 面板,编辑查询,数据源选 Easysearch,Query 类型切到 Query Builder:
- Metric:Count(默认就是 doc_count,统计匹配文档数)
- Bucket:Date Histogram
- Field:@timestamp
- Interval:auto(也可以手动选 1m、5m、10m,看数据量决定)
- Min Doc Count:0(保证中间没数据的时段也补 0,折线不断裂)
如果想看某个业务接口的平均耗时,Metric 换成 Average,Field 选duration字段,其他不变。
这里有一个小技巧:如果你的索引里有多个业务类型,想在同一张图里对比它们的错误数变化,可以用 Terms 聚合做分组,然后在 Labels 里设置{{key}}作为图例名称。Grafana 会自动为每个 Terms 分桶生成一条线,对比效果非常直观。
3.2 分组对比:Terms 聚合与饼图/柱状图
接着做一个“TOP 10 报错服务”的柱状图。
新建面板,选 Bar chart,查询配置:
- Metric:Count
- Bucket:Terms
- Field:service.keyword(注意如果字段是 text 类型并开启了 fielddata,才可以聚合;一般建议使用 keyword 子字段)
- Size:10
- Order By:Count
- Order Direction:Desc
- Min Doc Count:1
执行后,横轴会显示服务名,纵轴显示错误条数。如果字段后面带.keyword,是因为 ES 默认对 text 类型字段做全文索引,同时生成一个service.keyword做精确匹配和聚合,Grafana 里聚合时一定选 keyword 子字段,否则要么报错,要么结果不对。
饼图同理,Buckets 选 Terms,字段选你要分类的维度,比如level.keyword、region.keyword,然后切换到 Pie chart 面板类型。饼图适合一眼看清占比,但不太适合展示太多分类,超过 10 个类别建议还是用柱状图或者横向条形图。
3.3 表格与明细数据展示
大屏上光有趋势图还不够,经常要放一张“最近 20 条异常订单”的明细表,让值班的同学直接看到单号、金额、状态、报错原因。
Grafana 新版本(9.x 之后)的 ES 数据源已经支持 Table 查询类型,操作方式如下:
在 Panel 编辑页面,Query 类型选择 Table,Grafana 会要求你指定返回字段,可以通过 “Add field” 选择需要展示的字段,也可以通过设置Fields数组的 JSON 方式,直接声明要取的字段名。同时要保留一个时间范围过滤条件,否则默认查询时间跨度内所有数据,容易超时。
如果你用的 Grafana 版本较老,或者 Table 类型不可用,备选方案是用 Logs 面板展示日志原文,或者用 Raw Data 类型输出原始 JSON。日志面板对运维大屏够用,但如果你要展示订单金额、状态这类结构化字段,最好还是升级 Grafana 版本,用 Table 类型一步到位。
3.4 日志面板与全文检索场景
当大屏需要滚动显示实时日志时,用 Logs 面板最合适。它会把每条日志按行显示,支持关键词高亮,效果类似于 Kibana 的 Discover 页面。
配置上很简单,查询类型保持默认的 Lucene 查询,查询语句写:
level: ERROR AND service: order-service面板选 Logs,Grafana 会自动把 ES 返回的_source内容按 JSON 字段展示出来。我习惯把time和message字段设置为显示列,设置路径:
Panel options → Logs → Visible fields把需要显示的字段加进来,其他字段折叠。这样大屏上的日志面板看起来非常干净,只留时间、服务名、日志内容。
3.5 变量与模板化:一台设备一个屏
大屏做到后面,你会发现不同服务、不同环境要反复做重复面板。这时千万别一个个复制粘贴,用 Grafana 的变量机制,能做到“一份面板,全业务复用”。
方法是在 Dashboard Settings → Variables 里定义一个变量,比如service,查询方式选 Query,数据源选 Easysearch,Query 填:
{"find": "terms", "field": "service.keyword", "size": 100}这样 Grafana 会自动从 Easysearch 里读取所有服务名,生成一个下拉框。然后在每个面板的查询里,用$service替代具体的服务名关键字。
Lucene 查询写法变成:
service: $service AND level: ERRORTerm 聚合的 Field 也可以写死为service.keyword,这样不影响。变量定义好后,你可以把一份面板 Duplicate 多次,或者配合 Grafana 的 Repeat 功能,实现一行面板自动按变量值重复展示。大屏上放一个服务选择器,开会时切换服务名,所有图表一起联动变化,效果非常酷。
4. 大屏编排与落地技巧
4.1 大屏布局、栅格与适配
面板都做好了,接下来就是拼大屏。Grafana 的 Dashboard 是网格布局,拖拽面板时会有辅助线,方便对齐。不过我建议不要一个个手拖,直接在 Dashboard Settings 里调整 Grid Layout 参数,或者用 Row 面板把不同类型的图表分区。
常见的监控大屏分区方式是:
- 顶部一行放核心 KPI 数字:总请求量、错误数、平均耗时、活跃用户。
- 中间区域放趋势图:按时间的错误趋势、调用量趋势。
- 下方左侧放明细表格,右侧放日志流。
- 右下角放饼图或占比图。
大屏分辨率一般是 1920x1080 或者更大,Grafana 面板在浏览器里会自动缩放。如果投放的屏幕分辨率固定,可以在大屏地址后加&kiosk参数,它会隐藏左侧菜单和顶部栏,只保留面板内容,视觉上就是一个真正的大屏。另外,用浏览器自带的全屏快捷键F11,效果会更好。
4.2 自动刷新与时间范围锁定
大屏不能一直停留在刚打开的数据上,必须定时刷新。我在 Dashboard Settings → Time options 里把“Auto refresh”设为 10s,然后右上角时间范围设置为now-1h。
这里有个操作细节:为了让大屏不被人手动拖动时间范围改乱,我一般把 Run button 勾选上,并且设置Override relative time为now-1h,这样无论用户怎么切时间范围,面板刷新都会自动回到最近 1 小时窗口。对于实时监控大屏来说,“最近 30 分钟”或“最近 1 小时”是最常用的窗口,既能看清近期趋势,又不至于因为数据量太大导致查询变慢。
4.3 kiosk 模式大屏播放
Grafana 原生支持 kiosk 模式,进入方式很简单:
http://IP:3000/d/你的DashboardUID?from=now-1h&to=now&refresh=10s&kiosk其中:
from和to锁定时间范围refresh控制刷新频率kiosk让页面自动进入全屏播放
我实际用过一段时间,kiosk 模式的体验已经足够好。如果你还需要多个大屏自动轮播,可以用浏览器插件设置定时切换标签页,或者用支持 URL 切换的流媒体服务,把 Grafana 大屏页面作为信号源推送到电视上。
4.4 整屏复用:Dashboard JSON 迁移与拷贝
做好的大屏想复制一份到另一个 Grafana 环境,或者想在同一环境里快速复制一个模板,操作路径是:
Dashboard Settings → JSON Model,复制全部 JSON 内容。到目标环境后,Dashboards → New → Import,把 JSON 粘贴进去,导入时选择对应的数据源即可。
这里就是热搜词里 “grafana 拷贝整个面板” 和 “grafana failed to upgrade legacy queries datasource” 这两个问题的高发场景。导入旧版 Dashboard JSON 时,如果 JSON 里的datasource引用的是一个老 uid,而当前环境没有这个数据源,Grafana 就会报failed to upgrade legacy queries datasource im7_otuvz was not found这类错误。
解决办法有两个:
一是导入时在界面上手动选择当前易用的 Easysearch 数据源。Grafana 导入流程会弹出数据源映射选择框,把旧的 ES 数据源映射到新的 Easysearch 数据源上。
二是直接改 JSON。找到 JSON 里所有的"datasource": {"type": "elasticsearch", "uid": "im7_otuvz"}字段,把uid替换成当前环境 Easysearch 数据源的 uid。数据源 uid 可以在 Data sources 设置页面的 URL 里看到,或者通过 Grafana API 查询:
curl -s http://admin:密码@IP:3000/api/datasources | jq .替换完成后重新导入,问题就解决了。
5. 实战问题排查与避坑清单
5.1 failed to upgrade legacy queries datasource 错误处理
这个报错在导入老面板时非常常见,我单独拎出来说。
报错原因主要是面板 JSON 中保存的是旧版 Elasticsearch 数据源的引用方式,而 Grafana 新版要求数据源按uid识别,旧 JSON 里可能写的是 number 或name,导致新版本无法完成查询格式升级。
排查步骤建议按下面的顺序来:
- 打开 Dashboard JSON,搜索
datasource,看引用是uid还是type/name字符串。 - 如果引用的
uid不存在,去数据源列表里找到当前 Easysearch 数据源的uid。 - 批量替换 JSON 中的
uid,注意不要改错位置,只替换datasource块中的。 - 如果面板里的查询还是旧版结构(
bucketAggs、metrics是老字段),建议不要强行升级,直接在编辑面板里重新选择 Query 类型,或者新建一个面板替换。
我遇到过一个更隐蔽的情况:面板 JSON 里的某个 Panel 数据源引用是null,Grafana 默认继承 Dashboard 全局数据源,但全局数据源在导入后并没有被正确关联。这种情况直接把面板的datasource改成明确的数据源引用就行。
5.2 图表不出数据的常见原因
图表不出数据,排在前三位的原因我整理成了表格:
| 现象 | 原因 | 排查方向 |
|---|---|---|
| 刷新后图表全空 | 时间字段类型不对或不存在 | 去 Easysearch 查看索引 mapping,确认时间字段是 date 类型 |
| 部分字段聚合报错 | text 类型字段不能直接聚合 | 改用.keyword子字段 |
| 查询超时 | 索引数据量太大,通配符匹配过多索引 | 缩小索引模式,限制时间范围,降低并发分片数 |
| 结果显示 0 | Lucene 查询语法写错,或者字段名大小写不对 | 在 Explore 里先用简单的*查询验证 |
| 时区显示偏差 | Grafana 默认 UTC,Easysearch 存的是本地时间 | 在 Dashboard Settings 里把时区改为东八区,或统一存储 UTC |
其中时区问题特别坑。我第一个大屏做完,发现曲线的峰值总比业务方说的接口报错时间晚 8 个小时,后来确认是 Grafana 默认用 UTC 显示,Easysearch 里存的是带时区的时间戳。解决方法是 Dashboard Settings → General → Timezone 改成(UTC+08:00) Asia/Shanghai,或者干脆在时间范围参数里追加&tz=Asia%2FShanghai,所有图表就一致了。
5.3 性能优化:查询时长、并发与字段类型
大屏一般会同时加载十几个面板,如果每个面板都触发一次重量级聚合,Easysearch 集群压力会很大。我调优的思路有几个:
一是合理设置 Min interval。数据源里我设置Min time interval为 30s,这样即使大屏每 5 秒刷新,Grafana 也会自动把查询的最小桶间隔扩大到 30s,减少不必要的聚合次数。
二是通配符尽量精确。索引模式写成order-service-*比写成*好得多,索引数量少,查询自然快。
三是限制面板数据量。Terms 聚合的 Size 不要设太大,默认 10 足够;表格面板加一个size限制,通常取最近 500 条就够屏幕展示了。日志面板如果数据量很大,可以用 Lucene 语法先过滤掉非关键级别,再显示。
四是把低频数据做大时间窗口。比如“昨日报警总量”这种汇总型面板,不需要跟随大屏每 10 秒刷新,可以在面板编辑的 Query options 里设置Interval为1h,这样既保证数据准确性,又减少集群负担。
5.4 告警扩展:从大屏到及时通知
大屏只能看,真出了问题还得有人知道。Grafana 自带的 Alerting 功能可以直接对 ES 数据源做阈值告警。我给 ERROR 日志数加了一条告警规则:
- 查询条件:
level: ERROR - 时间范围:最近 5 分钟
- 聚合方式:Count
- 阈值:大于 100 触发 Warning
- 通知渠道:钉钉机器人 webhook
配置路径是 Alerting → Alert rules → New rule,查询和数据源选择 Easysearch,表达式类型选择 Threshold,然后把告警规则绑定到一个 Notification policy,并添加联系点(Contact point)。实测下来,Grafana 新版告警引擎很稳定,告警状态能从 Pending 自动升级到 Firing,配合钉钉/企微的 webhook 能第一时间把消息推给值班群。
如果你已经有一套 Prometheus + Alertmanager 在跑,Grafana 也能把告警推给 Alertmanager,具体在 Contact point 里选 Prometheus Alertmanager 类型,配置好 Alertmanager 地址即可。不过注意,这种模式只负责把 Grafana 的告警事件转发出去,规则本身还是在 Grafana 里配置。
6. 最后再分享一点个人经验
整套系统跑到现在,最大体会是:工具链的选择不需要追求“高大上”,关键是能贴合自己手头的数据和场景。Easysearch 这两年我在生产环境用得比较顺手,它兼容 ES 又更懂国内业务的语言习惯;Grafana 的价值则在于用一套标准把“数据接入 → 可视化 → 告警”全打通。
如果你也是第一次做数据可视化大屏,我建议不要一上来就想搞一个很复杂的监控大盘,先把数据源接通,做一个日志趋势图跑顺整个链路,再逐步加表格、加日志面板、加变量、加告警。等上手了,你会发现 Grafana 的可扩展性远比你想象中强,每多接一种数据源,大屏能讲的故事就多一层。
这个项目后续如果要扩展,我计划把 Easysearch 集群本身的指标也接进来,再结合业务索引做关联分析。可视化只是开始,让数据真正辅助决策才是目的。