从 Loki 迁移
本指南介绍如何将 Loki 日志写入迁移到 GreptimeDB。 GreptimeDB 支持 Loki Push API 写入日志,因此现有的 Loki 兼容写入端通常只需少量配置变更即可将日志发送到 GreptimeDB。
GreptimeDB 的 Loki 兼容端点用于日志写入。 对于查询和仪表盘,请使用 GreptimeDB SQL、全文检索、GreptimeDB Dashboard 以及 Grafana 集成,而不是 LogQL。
迁移前须知
请先检查当前 Loki 部署,并决定日志在 GreptimeDB 中的存储方式:
- 梳理所有向 Loki 写入日志的组件,例如 Grafana Alloy、OpenTelemetry Collector、Promtail、Fluent Bit、Vector 或自定义客户端。
- 规划目标 GreptimeDB 数据库和表名。如果没有提供表名 Header,GreptimeDB 会将 Loki 日志写入
loki_logs。 - 检查 Loki stream labels。GreptimeDB 会将 labels 存储为标签列,因此应避免使用 request ID、user ID、trace ID 等高基数字段作为 label。
- 确认是否只需要保存原始日志行,还是需要使用 GreptimeDB Pipeline 将日志行解析为结构化列。
- 规划历史数据迁移。GreptimeDB 不会直接导入 Loki chunk 或 index 文件;请通过原始日志源、归档文件或导出的记录,将历史日志重放到 GreptimeDB 的日志写入 API。
对于新的采集器配置,推荐使用 Grafana Alloy。 如果仍在使用已有的 Loki 兼容客户端,可以通过修改 Loki Push URL 并添加 GreptimeDB Header,将其重定向到 GreptimeDB。
迁移步骤
配置 GreptimeDB Loki 端点
将 Loki Push 请求发送到:
http{s}://<host>:4000/v1/loki/api/v1/push
使用以下 GreptimeDB 专用 Header:
| Header | 是否必需 | 说明 |
|---|---|---|
X-Greptime-DB-Name | 否 | 目标数据库名,默认值为 public。 |
X-Greptime-Log-Table-Name | 否 | 目标日志表名,默认值为 loki_logs。 |
Authorization | 取决于部署 | 使用 Base64 编码的 <username>:<password> 进行 Basic 认证。 |
X-Greptime-Pipeline-Name 或 X-Greptime-Log-Pipeline-Name | 否 | 在写入前用于解析 Loki 条目的 Pipeline 名称。 |
GreptimeDB 接受与 Loki 相同的 Push 请求体格式:
Content-Type: application/x-protobuf:Snappy 压缩的 LokiPushRequest。Content-Type: application/json:包含顶层streams数组的 JSON 请求体。
以下 JSON 请求可用于快速检查连通性:
curl -X POST "http://localhost:4000/v1/loki/api/v1/push" \
-H "Content-Type: application/json" \
-H "X-Greptime-DB-Name: public" \
-H "X-Greptime-Log-Table-Name: loki_demo_logs" \
--data-raw '{
"streams": [
{
"stream": {
"job": "api",
"env": "prod"
},
"values": [
["1731748568804293888", "request completed", {"trace_id": "abc"}]
]
}
]
}'
双写 Loki 和 GreptimeDB
迁移期间,请同时写入 Loki 和 GreptimeDB,直到完成写入、保留策略、仪表盘和告警验证。
以下 Alloy 示例保留现有 Loki sink,并新增一个 GreptimeDB Loki 兼容 sink:
loki.source.file "app" {
targets = [
{__path__ = "/var/log/app/*.log"},
]
forward_to = [loki.process.app.receiver]
file_match {
enabled = true
}
}
loki.process "app" {
forward_to = [
loki.write.existing_loki.receiver,
loki.write.greptimedb.receiver,
]
stage.static_labels {
values = {
job = "app",
env = "prod",
}
}
}
loki.write "existing_loki" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
loki.write "greptimedb" {
endpoint {
url = "http://greptimedb:4000/v1/loki/api/v1/push"
headers = {
"X-Greptime-DB-Name" = "public",
"X-Greptime-Log-Table-Name" = "loki_app_logs",
}
basic_auth {
username = "<greptime_user>"
password = "<greptimedb_password>"
}
}
}