使用 Grafana 和 ClickHouse 进行可观测性
Grafana 是 ClickHouse 中可观测性数据的首选可视化工具。这是通过 Grafana 的官方 ClickHouse 插件实现的。用户可以按照此处提供的安装说明进行操作:此处.
插件的 V4 版本使日志和跟踪成为新的查询构建器体验中的第一类公民。这最大限度地减少了 SRE 编写 SQL 查询的需求,并简化了基于 SQL 的可观测性,推动了这种新兴范式的进步。其中一部分是将 Open Telemetry (OTel) 放在插件的核心位置,因为我们认为这将是未来几年基于 SQL 的可观测性的基础,以及数据收集的方式。
Open Telemetry 集成
在 Grafana 中配置 Clickhouse 数据源时,插件允许用户为日志和跟踪指定默认数据库和表,以及这些表是否符合 OTel 架构。这使插件能够返回 Grafana 中正确日志和跟踪渲染所需的列。如果你对默认 OTel 架构进行了更改,并且希望使用自己的列名,则可以指定这些列名。如果使用默认 OTel 列名(例如时间(Timestamp)、日志级别(SeverityText)或消息正文(Body)),则无需进行任何更改。
用户可以通过 HTTP 或 Native 协议将 Grafana 连接到 ClickHouse。后者提供了微不足道的性能优势,这些优势不太可能在 Grafana 用户发出的聚合查询中得到明显体现。相反,HTTP 协议通常对于用户来说更易于代理和内省。
日志配置需要时间、日志级别和消息列,以便正确渲染日志。
跟踪配置稍微复杂一些(完整列表此处)。此处需要的列是为了使后续构建完整跟踪配置文件的查询能够被抽象化。这些查询假设数据结构类似于 OTel,因此用户如果明显偏离标准架构,则需要使用视图才能利用此功能。
配置完成后,用户可以导航到Grafana Explore并开始搜索日志和跟踪。
日志
如果符合 Grafana 对日志的要求,用户可以在查询构建器中选择“查询类型:日志”,然后点击“运行查询”。查询构建器将构建一个查询以列出日志并确保它们被渲染,例如:
SELECT Timestamp as timestamp, Body as body, SeverityText as level, TraceId as traceID FROM "default"."otel_logs" WHERE ( timestamp >= $__fromTime AND timestamp <= $__toTime ) ORDER BY timestamp DESC LIMIT 1000
查询构建器提供了一种简单的方法来修改查询,避免用户需要编写 SQL。过滤(包括查找包含关键字的日志)可以在查询构建器中执行。希望编写更复杂查询的用户可以切换到 SQL 编辑器。只要返回了适当的列,并且选择了“日志”作为查询类型,结果将被渲染为日志。日志渲染所需的列列在此处.
从日志到跟踪
如果日志包含跟踪 ID,用户可以从中导航到特定日志行的跟踪。
跟踪
与上述日志体验类似,如果 Grafana 渲染跟踪所需的列得到满足(例如,通过使用 OTel 架构),查询构建器能够自动构建必要的查询。通过选择“查询类型:跟踪”并点击“运行查询”,将生成并执行类似于以下内容的查询(取决于你配置的列 - 以下假设使用 OTel)
SELECT "TraceId" as traceID,
"ServiceName" as serviceName,
"SpanName" as operationName,
"Timestamp" as startTime,
multiply("Duration", 0.000001) as duration
FROM "default"."otel_traces"
WHERE ( Timestamp >= $__fromTime AND Timestamp <= $__toTime )
AND ( ParentSpanId = '' )
AND ( Duration > 0 )
ORDER BY Timestamp DESC, Duration DESC LIMIT 1000
此查询返回 Grafana 预期的列名,将跟踪表渲染如下所示。可以在不编写 SQL 的情况下对持续时间或其他列进行过滤。
希望编写更复杂查询的用户可以切换到“SQL 编辑器”。
查看跟踪详细信息
如上所示,跟踪 ID 作为可点击的链接进行渲染。点击跟踪 ID 后,用户可以选择通过“查看跟踪”链接查看关联的跨度。这将发出以下查询(假设 OTel 列)以检索所需结构中的跨度,并将结果渲染为瀑布图。
WITH '<trace_id>' as trace_id,
(SELECT min(Start) FROM "default"."otel_traces_trace_id_ts"
WHERE TraceId = trace_id) as trace_start,
(SELECT max(End) + 1 FROM "default"."otel_traces_trace_id_ts"
WHERE TraceId = trace_id) as trace_end
SELECT "TraceId" as traceID,
"SpanId" as spanID,
"ParentSpanId" as parentSpanID,
"ServiceName" as serviceName,
"SpanName" as operationName,
"Timestamp" as startTime,
multiply("Duration", 0.000001) as duration,
arrayMap(key -> map('key', key, 'value',"SpanAttributes"[key]),
mapKeys("SpanAttributes")) as tags,
arrayMap(key -> map('key', key, 'value',"ResourceAttributes"[key]),
mapKeys("ResourceAttributes")) as serviceTags
FROM "default"."otel_traces"
WHERE traceID = trace_id
AND startTime >= trace_start
AND startTime <= trace_end
LIMIT 1000
请注意,上面的查询使用物化视图“otel_traces_trace_id_ts”来执行跟踪 ID 查找。有关更多详细信息,请参阅“加速查询 - 使用物化视图进行查找”。
从跟踪到日志
如果日志包含跟踪 ID,用户可以从跟踪导航到其关联的日志。要查看日志,请点击跟踪 ID 并选择“查看日志”。这将发出以下查询,假设默认 OTel 列。
SELECT Timestamp as "timestamp",
Body as "body", SeverityText as "level",
TraceId as "traceID" FROM "default"."otel_logs"
WHERE ( traceID = '<trace_id>' )
ORDER BY timestamp ASC LIMIT 1000
仪表盘
用户可以使用 ClickHouse 数据源在 Grafana 中构建仪表盘。我们建议参考 Grafana 和 ClickHouse 数据源文档以了解更多信息,特别是关于宏概念和变量。
插件提供了一些开箱即用的仪表盘,包括一个示例仪表盘“简单 ClickHouse OTel 仪表盘”,用于符合 OTel 规范的日志和跟踪数据。这要求用户符合 OTel 的默认列名,并且可以从数据源配置中安装。
我们在下面提供了一些构建可视化的简单技巧。
时间序列
除了统计数据之外,折线图是可观测性用例中最常用的可视化形式。如果查询返回一个名为“time”的日期时间列和一个数字列,Clickhouse 插件将自动渲染一个折线图。例如:
SELECT
$__timeInterval(Timestamp) as time,
quantile(0.99)(Duration)/1000000 AS p99
FROM otel_traces
WHERE
$__timeFilter(Timestamp)
AND ( Timestamp >= $__fromTime AND Timestamp <= $__toTime )
GROUP BY time
ORDER BY time ASC
LIMIT 100000
多折线图
如果满足以下条件,将自动渲染多折线图:
- 字段 1:别名为“time”的日期时间字段
- 字段 2:要分组的值。这应该是一个字符串。
- 字段 3+:度量值
例如:
SELECT
$__timeInterval(Timestamp) as time,
ServiceName,
quantile(0.99)(Duration)/1000000 AS p99
FROM otel_traces
WHERE $__timeFilter(Timestamp)
AND ( Timestamp >= $__fromTime AND Timestamp <= $__toTime )
GROUP BY ServiceName, time
ORDER BY time ASC
LIMIT 100000
可视化地理数据
我们已经探讨了在前面的部分中使用 IP 字典用地理坐标来丰富可观测性数据。假设你拥有“latitude”和“longitude”列,可以使用“geohashEncode”函数来可视化可观测性。这将生成与 Grafana 的地理地图图表兼容的地理散列。下面显示了一个示例查询和可视化:
WITH coords AS
(
SELECT
Latitude,
Longitude,
geohashEncode(Longitude, Latitude, 4) AS hash
FROM otel_logs_v2
WHERE (Longitude != 0) AND (Latitude != 0)
)
SELECT
hash,
count() AS heat,
round(log10(heat), 2) AS adj_heat
FROM coords
GROUP BY hash