OpenObserve v1.1.1 API 使用详解

面向需要用 API 集成或运维 OpenObserve 的工程师,逐域讲清 v1.1.1 的认证、日志摄入、查询、流管理、仪表盘、告警、用户与函数 API:端点、方法、请求体、实测响应与错误处理。全部请求与回显均在 Ubuntu 22.04.4 LTS(x86_64)+ OpenObserve v1.1.1(开源单机模式)实测通过。

OpenObserveOpenObserve2026/10/18

OpenObserve v1.1.1 API 使用详解

‍‍​​‌​> 目标:面向需要用 API 集成或运维 OpenObserve 的工程师,逐域讲清 v1.1.1 的认证、日志摄入、查询、流管理、仪表盘、告警、用户与函数 API:端点、方法、请求体、实测响应与错误处理。全部请求与回显均在 Ubuntu 22.04.4 LTS(x86_64)+ OpenObserve v1.1.1(开源单机模式)实测通过。

一、环境信息

本文所有命令与回显的实测环境:

  • 操作系统:Ubuntu 22.04.4 LTS(x86_64)
  • OpenObserve:v1.1.1(开源版单机,/config 实测 "build_type": "opensource")
  • API 基址:http://localhost:5080(HTTP 与 Web 控制台共用 5080)
  • 组织(org_id):default(首次启动自动创建的默认组织)
  • 管理账号:root@example.com / Q1w2E3r4!(演示凭据)
  • 样本流:app_logs(已摄入 5 条应用日志,含 level/job/message/status/duration_ms/host 字段)

二、前置条件

  1. 一个可访问的 OpenObserve v1.1.1 实例(部署见《OpenObserve Docker Compose 部署指南》);
  2. 具备 API 调用权限的账号(root 或 admin 角色);
  3. 熟悉 curl 基本用法;本文所有示例直接用 curl,语言绑定(Python/Go SDK)按官方 API 契约同理封装。

URL 结构约定:除少数根路径端点(如 /auth/login)外,API 一律挂在组织之下:

/api/{org_id}/{资源}

实测中 org_id 一律用 default。

三、认证与首次调用

3.1 HTTP Basic 认证(推荐给 API 调用)

官方 API 索引明确:所有 API 使用 HTTP Basic 认证(Authorization: Basic base64(用户名:密码)),curl 的 -u 参数即等价实现。首次调用验证:

curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/default/streams -o /dev/null -w "%{http_code}\n"

实测回显:

200

不带凭据访问受保护 API:

curl -s -i http://localhost:5080/api/default/streams | head -4

实测回显:

HTTP/1.1 401 Unauthorized
content-type: application/json
x-api-node: 9f4e7b5c706a
vary: origin, access-control-request-method, access-control-request-headers

3.2 会话登录(Web 控制台流程)

/auth/login 用于生成会话 Cookie(浏览器流程),API 集成直接用 Basic 即可:

curl -s -X POST http://localhost:5080/auth/login \
  -H "Content-Type: application/json" \
  -d '{"name":"root@example.com","password":"Q1w2E3r4!"}'

实测回显:

{"status":true,"message":""}

四、日志摄入 API

v1.1.1 提供 4 条日志摄入通道,均自动建流(Stream)并推断 schema。

4.1 JSON 批量摄入(/api/{org}/{stream}/_json)

curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST "http://localhost:5080/api/default/app_logs/_json" \
  -H "Content-Type: application/json" \
  -d '[
  {"level":"info","job":"api-gateway","message":"POST /api/v1/orders 200 in 12ms","status":200,"duration_ms":12,"host":"web-01"},
  {"level":"warn","job":"api-gateway","message":"GET /api/v1/cart slow response","status":200,"duration_ms":860,"host":"web-01"},
  {"level":"error","job":"payment","message":"upstream timeout while charging","status":504,"duration_ms":3005,"host":"pay-02"},
  {"level":"info","job":"payment","message":"charge succeeded order=A-1024","status":200,"duration_ms":45,"host":"pay-02"},
  {"level":"info","job":"auth","message":"user login ok uid=1001","status":200,"duration_ms":8,"host":"auth-01"}
]'

实测回显:

{"code":200,"status":[{"name":"app_logs","successful":5,"failed":0}]}

successful/failed 是 ingestion 监控的关键指标。

4.2 逐行摄入(/api/{org}/{stream}/_multi)

每行一条 JSON 记录(NDJSON):

printf '{"level":"error","job":"cron","message":"replica lag 120s","host":"db-02"}\n' > /tmp/m2.log
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST "http://localhost:5080/api/default/cron_logs/_multi" \
  -H "Content-Type: application/json" \
  --data-binary @/tmp/m2.log

实测回显:

{"code":200,"status":[{"name":"cron_logs","successful":1,"failed":0}]}

排障实录:该端点按行解析 JSON。若按传统 syslog/logfmt 思路发纯文本行(如 level=info job=cron ...),返回 400:

{"code":400,"message":"Error# Failed processing: JsonError(Error(\"expected value\", line: 1, column: 1))"}

结论:_multi 不做 logfmt 转换,文本类日志需在客户端(Vector/Fluent-bit)转成 JSON 再推。

4.3 Elasticsearch Bulk 兼容摄入(/api/{org}/_bulk)

NDJSON 协议(动作行 + 数据行交替),Filebeat/Logstash 等 ES 采集器可零改造切换:

printf '{"create":{"_index":"bulk_logs"}}\n{"level":"info","message":"bulk record one","host":"es-01"}\n{"create":{"_index":"bulk_logs"}}\n{"level":"warn","message":"bulk record two","host":"es-02"}\n' > /tmp/b.ndjson
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST "http://localhost:5080/api/default/_bulk" \
  -H "Content-Type: application/json" \
  --data-binary @/tmp/b.ndjson

实测回显(逐条确认创建成功,ES 风格响应结构):

{"took":0,"errors":false,"items":[{"index":{"_index":"bulk_logs","_id":"","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":1,"_primary_term":1,"status":200}},{"index":{"_index":"bulk_logs","_id":"","_version":1,"result":"created","_shards":{"total":1,"successful":1,"failed":0},"_seq_no":1,"_primary_term":1,"status":200}}]}

4.4 OTLP 日志摄入(/api/{org}/v1/logs)

OpenTelemetry 协议(JSON 编码的 ResourceLogs 结构):

cat > /tmp/otlp.json << 'EOF'
{"resourceLogs":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"demo-app"}}]},"scopeLogs":[{"logRecords":[{"timeUnixNano":"1792297000000000000","severityText":"INFO","body":{"stringValue":"otlp demo log from demo-app"},"attributes":[{"key":"env","value":{"stringValue":"prod"}}]}]}]}]}
EOF
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST "http://localhost:5080/api/default/v1/logs" \
  -H "Content-Type: application/json" \
  --data-binary @/tmp/otlp.json

实测回显:

{}

返回空对象且 HTTP 200 表示接收成功(OTLP 风格的静默确认);数据落入 default 流(OTLP 日志的默认落流,可用 _search 查 service.name、severity 等自动展开字段验证)。

五、查询 API

5.1 SQL 查询(/api/{org}/_search)

请求体三要素:sql、start_time、end_time(微秒时间戳):

NOW=$(date +%s)
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST "http://localhost:5080/api/default/_search" \
  -H "Content-Type: application/json" \
  -d "{\"query\":{\"sql\":\"SELECT level, job, message, duration_ms FROM app_logs ORDER BY duration_ms DESC LIMIT 3\",\"start_time\":$(( (NOW-3600)*1000000 )),\"end_time\":$(( NOW*1000000 ))}}"

实测回显(节选):

{"took":9,"took_detail":{"total":9,"cache_took":0,"file_list_took":0,"wait_in_queue":0,"idx_took":0,"search_took":8},"hits":[{"_timestamp":1792296280528199,"level":"error","job":"payment","message":"upstream timeout while charging","duration_ms":3005},{"_timestamp":1792296280528198,"level":"warn","job":"api-gateway","message":"GET /api/v1/cart slow response","duration_ms":860},{"_timestamp":1792296280528199,"level":"info","job":"payment","message":"charge succeeded order=A-1024","duration_ms":45}],"total":3,"from":0,"size":3,"cached_ratio":0,"scan_size":0,"idx_scan_size":0,"scan_records":5,"is_partial":false}

响应要点:

字段含义
hits命中记录数组,_timestamp(微秒)为内置时间字段
total / from / size总命中数与分页游标
took_detail各阶段耗时(缓存命中、文件列表、排队、索引、检索)
scan_records / scan_size实际扫描记录数与字节数(成本观测)
is_partial是否部分结果(超时/分片未完成时为 true)

聚合查询同理,例如每分钟日志量直方图:

SELECT histogram(_timestamp, '1 minute') AS t, count(*) AS c FROM app_logs GROUP BY t ORDER BY t

5.2 值列表与上下文接口(v1.1.1 实测说明)

控制台的"字段值分布"(_values)与"上下文浏览"(_around)在 v1.1.1 开源单机实测直接访问 /api/default/_values、/api/default/_around 及流级变体均返回 404 Not Found(未开放或路径变更);等价能力可用 _search 自行实现:

  • 字段值分布:SELECT level, count(*) AS c FROM app_logs GROUP BY level
  • 上下文定位:SELECT * FROM app_logs WHERE _timestamp BETWEEN a AND b ORDER BY _timestamp

💡 说明:控制台页面正常提供这些视图(由内部端点支撑),API 使用方在 v1.1.1 以 _search 聚合替代即可,升级版本后可再核对官方 API 索引。

六、流管理 API

6.1 流列表(GET /api/{org}/streams)

curl -s -u "root@example.com:Q1w2E3r4!" "http://localhost:5080/api/default/streams"

实测回显(节选):

{"list":[{"name":"app_logs","storage_type":"disk","stream_type":"logs","stats":{"created_at":1792293071331959,"doc_time_min":1792293071331959,"doc_time_max":1792293071332965,"doc_num":5,"file_num":1,"storage_size":0.0007219314575195312,"compressed_size":0.0025720596313476562,"index_size":0.004790306091308594,"mindex_size":0.0},"schema":[],"settings":{"partition_keys":{},"full_text_search_keys":["m

stats 提供文档数、存储/索引体量,适合做容量监控;doc_num:5 与摄入记录一致。

6.2 流 Schema(GET /api/{org}/streams/{stream}/schema)

curl -s -u "root@example.com:Q1w2E3r4!" "http://localhost:5080/api/default/streams/app_logs/schema"

实测回显(节选):

{"name":"app_logs","storage_type":"disk","stream_type":"logs","stats":{...},"schema":[{"name":"_timestamp","type":"Int64"},{"name":"duration_ms","type":"Int

schema 数组即摄入时自动推断的字段类型(Int64/String 等),接入前可用它核对字段名大小写(OpenObserve 字段名大小写敏感)。

6.3 删除流(DELETE /api/{org}/streams/{stream})

curl -s -u "root@example.com:Q1w2E3r4!" -X DELETE http://localhost:5080/api/default/streams/bulk_logs

实测回显:

{"code":200,"message":"stream deleted"}

删除不存在的流:

{"code":404,"message":"stream not found"}

⚠️ 注意:删除流同时清除其数据与元信息,不可恢复;triggers 等系统内置流不要删除。

七、仪表盘 API

仪表盘(Dashboard)的请求/响应采用版本化信封(v8 为 v1.1.1 的仪表盘结构版本)。

7.1 创建(POST /api/{org}/dashboards)

curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/default/dashboards \
  -H "Content-Type: application/json" \
  -d '{"title":"api-demo-dash","description":"created by API doc test"}'

实测回显(节选):

"dashboardId":"7517438982746013696","title":"api-demo-dash","description":"created by API doc test"

返回 dashboardId(服务端生成的数字 ID)。

7.2 查询单个(GET /api/{org}/dashboards/{id})

curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/default/dashboards/7517438982746013696

实测回显(节选):

{"v1":null,"v2":null,"v3":null,"v4":null,"v5":null,"v6":null,"v7":null,"v8":{"version":8,"dashboardId":"7517438982746013696","title":"api-demo-dash","description":"created by API doc test","role":"",

更新要点:更新(PUT)时请求体必须回传 GET 返回的完整信封(含 hash 字段做并发冲突检测),只传业务字段会被拒绝。

7.3 删除(DELETE /api/{org}/dashboards/{id})

curl -s -u "root@example.com:Q1w2E3r4!" -X DELETE http://localhost:5080/api/default/dashboards/7517438982746013696

实测回显:

{"code":200,"message":"Dashboard deleted"}

八、告警 API(v2)

v1.1.1 的告警 API 为 v2 版本(/api/{org}/v2/alerts),依赖两块基础资源:模板(Template)与目的地(Destination)。

8.1 模板与目的地(/api/{org}/alerts/templates、/api/{org}/alerts/destinations)

curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/default/alerts/templates \
  -H "Content-Type: application/json" \
  -d '{"name":"webhook-tpl","body":"Alert {alert_name} on {stream_name}: {alert_body}"}'

实测回显:

{"code":200,"message":"Template saved"}
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/default/alerts/destinations \
  -H "Content-Type: application/json" \
  -d '{"name":"httpbin-hook","url":"https://httpbin.org/post","method":"post","headers":{},"template_name":"webhook-tpl","skip_tls_verify":false}'

实测回显:

{"code":200,"message":"Destination saved","id":"3KqtwuyLrMqSiIX2WPRZEktHpHm","name":"httpbin-hook"}

安全防护实录(SSRF guard):目的地 URL 指向私网地址时被服务端拒绝,实测回显:

{"code":400,"message":"Destination URL blocked by SSRF guard: Access to private IP address 127.0.0.1 is not allowed for security reasons. This prevents Server-Side Request Forgery (SSRF) attacks."}

这说明 v1.1.1 对 webhook 目的地内建了 SSRF 防护(拒绝 127.0.0.1/私网/链路本地地址),设计上避免了恶意告警目的地穿透内网。

8.2 创建告警(POST /api/{org}/v2/alerts)

cat > /tmp/alert.json << 'EOF'
{"name":"app_error_alert","stream_name":"app_logs","stream_type":"logs","is_real_time":false,
 "query_condition":{"type":"sql","conditions":[],
  "sql":"SELECT count(*) AS err_count FROM app_logs WHERE level = 'error'",
  "multi_time_range":[]},
 "trigger_condition":{"period":1,"operator":">=","threshold":1,
  "frequency":1,"frequency_type":"minutes","cron":"","silence":10},
 "destinations":["httpbin-hook"],
 "description":"Alert when error log appears in app_logs",
 "enabled":true,"context_attributes":{}}
EOF
curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/v2/default/alerts \
  -H "Content-Type: application/json" \
  --data-binary @/tmp/alert.json

实测回显:

{"code":200,"message":"Alert saved","id":"3KqtwsOBziuO1yogWwnvVfW8nTk","name":"app_error_alert"}

请求体关键字段:

字段说明
query_condition.sql调度器周期执行的 SQL,type: sql
trigger_condition.period / threshold / operator统计窗口(分钟)+ 触发阈值比较
trigger_condition.frequency / frequency_type调度频率(分钟/小时/cron)
trigger_condition.silence触发后的静默期(分钟),防告警风暴
destinations目的地名称字符串数组(v2 契约)

依赖校验实录:destinations 引用不存在的目的地时创建被拒(实测删除目的地后再创建即复现):

{"code":404,"message":"Alert destination httpbin-hook not found"}

8.3 列表 / 详情 / 删除

curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/v2/default/alerts

实测回显(节选):

{"list":[{"alert_id":"3KqtwsOBziuO1yogWwnvVfW8nTk","folder_id":"default","folder_name":"default","name":"app_error_alert","owner":"root@example.com","description":"Alert when error log appears in app_logs","alert_type":"scheduled","stream_name":"app_logs","stream_type":"logs","condition":{"type":"sql","conditions":{"and":[]},"sql":"SELECT count(*) AS err_count FROM app_logs WHERE level = 'error'",...},"trigger_condition":{"period":1,"operator":">=","threshold":1,"frequency":1,...

注意列表项主键字段是 alert_id(创建响应里叫 id)。详情与删除:

curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/v2/default/alerts/3KqtwsOBziuO1yogWwnvVfW8nTk   # GET 详情
curl -s -u "root@example.com:Q1w2E3r4!" -X DELETE http://localhost:5080/api/v2/default/alerts/3KqtwsOBziuO1yogWwnvVfW8nTk

删除实测回显:

{"code":200,"message":"Alert deleted"}

九、用户与函数 API

9.1 用户管理(/api/{org}/users)

curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/default/users \
  -H "Content-Type: application/json" \
  -d '{"email":"apitest@example.com","password":"Q1w2E3r4!","role":"admin","first_name":"API","last_name":"Test"}'

实测回显:

{"code":200,"message":"User saved successfully"}

角色取值实录:role 仅接受内置角色(admin/member/viewer/root)。实测传 viewer/member 以外的自定义角色名会报 "Custom roles not allowed" 类错误;开源版自建用户用 admin 或 member。用户列表:

curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/default/users

实测回显(节选):

{"data":[{"email":"apitest@example.com","first_name":"API","last_name":"Test","role":"admin","is_external":false,"created_at":1792297140708570},{...},{"email":"root@example.com","first_name":"root","last_name":"","role":"root","is_external":false,"created_at":179226...

删除(从当前组织移除):

curl -s -u "root@example.com:Q1w2E3r4!" -X DELETE http://localhost:5080/api/default/users/apitest@example.com

实测回显:

{"code":200,"message":"User removed from organization"}

9.2 查询函数(/api/{org}/functions)

函数是 VRL(Vector Remap Language)脚本,摄入/查询时做行级数据加工:

curl -s -u "root@example.com:Q1w2E3r4!" \
  -X POST http://localhost:5080/api/default/functions \
  -H "Content-Type: application/json" \
  -d '{"name":"drop_debug","function":"if .level == \"debug\" { \"\" } else { . }","params":""}'

实测回显:

{"code":200,"message":"Function saved successfully"}
curl -s -u "root@example.com:Q1w2E3r4!" http://localhost:5080/api/default/functions

实测回显:

{"list":[{"function":"if .level == \"debug\" { \"\" } else { . } \n .","name":"drop_debug","params":"","numArgs":0,"transType":0}]}
curl -s -u "root@example.com:Q1w2E3r4!" -X DELETE http://localhost:5080/api/default/functions/drop_debug

实测回显:

{"code":200,"message":"Function deleted"}

十、错误处理与通用约定

状态码语义(实测归纳):

状态码典型场景响应形态
200成功业务对象或 {"code":200,"message":"..."}
400请求体不合法 / 业务规则拒绝{"code":400,"message":"Error# ..."}(如 _multi 非 JSON)
401缺失/错误凭据空 body + HTTP/1.1 401 Unauthorized
404资源不存在 / 引用依赖缺失{"code":404,"message":"... not found"}

通用约定:

  1. 时间参数一律微秒时间戳(start_time/end_time/_timestamp;秒 ×1,000,000);
  2. 流(Stream)无需预建,首次写入自动创建并推断 schema;字段名大小写敏感;
  3. 组织路径 /api/default/ 中的 default 为 org_id,多组织部署替换为对应组织标识;
  4. 删除类 API 语义直接(stream/dashboard/alert 等删除即生效),生产集成建议先查后删;
  5. 告警 v2 的 destinations 是字符串数组,且目的地必须已存在(404 强校验);
  6. x-api-node 响应头可识别处理节点,集群排障时配合日志使用。

十一、参考链接