openobserve-api について
curlでOpenObserveを操作するAIエージェント向けのREST APIガイドです。最新のAPI情報の取得を重視し、ダッシュボード構造やよくある注意点も説明します。
主な機能
- 01REST経由でログ、メトリクス、トレースを検索
- 02ストリーム、ダッシュボード、フォルダー、アラートを管理
- 03curlでJSONやバルクデータを取り込み
- 04パネル構造とハッシュベースの同時更新を解説
- 05API情報の取得と注意点を案内
活用シーン
- 01ログを分析し、ホストごとに件数を集計
- 02ダッシュボードやパネルを作成・更新
- 03アラートを設定し、ストリームにデータを投入
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fcakyon/ claude-codex-settings --skill openobserve-apiインストール後、Claude Code で/openobserve-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/around.mdbulk.mddelete.mdindex.mdjson.mdlist.mdloki.mdmulti.mdotlp.mdschema.mdsearch.mdsetting.mdvalue.mdreferences/recipes/build-dashboard.shsearch-logs.shupdate-panel.sh詳細
OpenObserve REST API スキル
AI エージェントから OpenObserve をプログラムで利用できます。curl とドキュメント化された REST API を使って、任意の OpenObserve インスタンス(Cloud またはセルフホスト可能)に接続します。CLI は不要です。OpenObserve 公式の CLI はありません。
まず情報を取得する
OpenObserve API の形式に関する知識は古くなっている可能性があります。事前学習済みの知識よりも、情報の取得を優先してください。
| ソース | 取得方法 | 用途 |
|---|---|---|
| ドキュメントリポジトリ | gh api repos/openobserve/openobserve-docs/contents/docs/reference/api/{path}.md -q .content | base64 -d | 信頼できるリクエスト/レスポンスのサンプル |
| サーバーソース | gh api repos/openobserve/openobserve/contents/src/handler/http/request/dashboards/mod.rs -q .content | base64 -d | エンドポイントのパス、クエリパラメーター、ステータスコード |
| パネルスキーマ | gh api repos/openobserve/openobserve/contents/src/config/src/meta/dashboards/v8/mod.rs -q .content | base64 -d | 正確なパネル JSON 構造(Rust 構造体) |
ドキュメントとサーバーソースが食い違う場合は、サーバーソースを信頼してください。ハンドラーの更新はドキュメントよりも速いためです。
1. 認証
メールアドレスとパスワードを使った HTTPS Basic 認証です。トークンエンドポイントはありません。
# Method 1: curl -u shorthand
curl -u "[email protected]:PASSWORD" "https://eu1.openobserve.ai/api/<org>/streams"
# Method 2: explicit header
TOKEN=$(printf '%s' "[email protected]:PASSWORD" | base64)
curl -H "Authorization: Basic $TOKEN" "https://eu1.openobserve.ai/api/<org>/streams"
以下のエンドポイントでは、BASE=https://<host>/api/<org> と AUTH="-u [email protected]:PASSWORD" を前提とします。
2. 検索/クエリ — POST $BASE/_search
オプションのクエリ文字列 ?type=logs|metrics|traces(デフォルトは logs)。
curl $AUTH -H 'Content-Type: application/json' \
"$BASE/_search?type=logs" \
-d '{
"query": {
"sql": "SELECT host_name, COUNT(*) AS n FROM \"my_stream\" GROUP BY host_name ORDER BY n DESC",
"start_time": 1777000000000000,
"end_time": 1777999999000000,
"from": 0,
"size": 100
},
"search_type": "ui"
}'
- タイムスタンプの単位はマイクロ秒です(Unix エポック × 1_000_000)。必ず
start_time/end_timeを指定してください。指定しないとすべてのデータがスキャンされます。 search_typeはui | dashboards | reports | alertsのいずれかです。レート制限と監査ログに影響します。- ページネーション:
from(オフセット)+size(上限、リクエストあたり最大約 10000)。 - レスポンス:
{ took, hits[], total, from, size, scan_size }。 - SQL の種類:DataFusion / Arrow SQL。識別子はダブルクォート(
"stream_name")、文字列はシングルクォート('value')で囲みます。 - 時間バケット単位のグループ化:
SELECT histogram(_timestamp, '5 minute') AS ts, COUNT(*) FROM "stream" GROUP BY ts ORDER BY ts。 - 用語の集計:
SELECT k8s_namespace, COUNT(*) FROM "stream" GROUP BY k8s_namespace。 - 全文検索:
match_all('text')、str_match(field, 'text')。デフォルトの全文検索フィールド:log, message, msg, content, data, json。 - メトリクスに対する PromQL:
POST $BASE/prometheus/api/v1/query_range。 - トレースのコンテキストウィンドウ:
GET $BASE/{stream}/_around?key=<ts_us>&size=N。
3. ストリーム — GET $BASE/streams
# List
curl $AUTH "$BASE/streams?fetchSchema=false&type=logs"
# Schema
curl $AUTH "$BASE/streams/<stream>/schema?type=logs"
# Update settings
curl $AUTH -X PUT -H 'Content-Type: application/json' "$BASE/streams/<stream>/settings" -d '{"partition_keys":["host_name"]}'
# Delete
curl $AUTH -X DELETE "$BASE/streams/<stream>?type=logs"
フィールドの型:Utf8 | Int64 | Float64 | Timestamp | Boolean。タイムスタンプフィールドは常に _timestamp(マイクロ秒)です。
4. ダッシュボード — GET|POST|PUT|DELETE $BASE/dashboards
すべて ?folder=<folder_id> を指定します(デフォルトは default)。
# List
curl $AUTH "$BASE/dashboards?folder=default"
# Get one (returns versioned wrapper {v1..v8, version, hash, updatedAt})
curl $AUTH "$BASE/dashboards/<dashboard_id>?folder=default"
# Create — body is the UNWRAPPED inner v8 object
curl $AUTH -X POST -H 'Content-Type: application/json' \
"$BASE/dashboards?folder=default" \
-d @dashboard-v8.json
# Update — REQUIRES the current hash for optimistic concurrency
HASH=$(curl -s $AUTH "$BASE/dashboards/<id>?folder=default" | jq -r .hash)
curl $AUTH -X PUT -H 'Content-Type: application/json' \
"$BASE/dashboards/<id>?folder=default&hash=$HASH" \
-d @updated-dashboard.json
# Delete
curl $AUTH -X DELETE "$BASE/dashboards/<id>?folder=default"
# Move between folders
curl $AUTH -X PUT -H 'Content-Type: application/json' \
"$BASE/folders/dashboards/<id>" \
-d '{"from":"default","to":"<target_folder_id>"}'
重要:PUT/POST の本文には、ラップされていない v8 の内部オブジェクトを指定してください。{v1..v8, version, hash} 全体のラッパーではありません。サーバーはラッパーを返しますが、送信時には内部オブジェクトのみを指定する必要があります。
# Read, mutate, write — the correct pattern
RAW=$(curl -s $AUTH "$BASE/dashboards/<id>?folder=default")
HASH=$(echo "$RAW" | jq -r .hash)
echo "$RAW" | jq '.v8 | .title = "New Title"' \
| curl -s $AUTH -X PUT -H 'Content-Type: application/json' \
"$BASE/dashboards/<id>?folder=default&hash=$HASH" -d @-
409 Conflict レスポンスは、ハッシュが古いことを意味します。再取得して再試行してください。
パネル単位の操作(v8 のみ — 新しいハッシュを返します)
# Add panel
curl $AUTH -X POST -H 'Content-Type: application/json' \
"$BASE/dashboards/<id>/panels?folder=default&hash=$HASH" \
-d '{"panel": {...}, "tabId": "default"}'
# Update panel
curl $AUTH -X PUT -H 'Content-Type: application/json' \
"$BASE/dashboards/<id>/panels/<panel_id>?folder=default&hash=$HASH" \
-d '{...panel...}'
# Delete panel
curl $AUTH -X DELETE \
"$BASE/dashboards/<id>/panels/<panel_id>?folder=default&hash=$HASH&tabId=default"
5. パネル JSON(v8)
ダッシュボードのツリー:dashboard.tabs[].panels[]。各パネル:
{
"id": "panel-1",
"type": "table",
"title": "Per-host stats",
"description": "",
"queryType": "sql",
"queries": [
{
"query": "SELECT host_name, COUNT(*) AS n FROM \"my_stream\" GROUP BY host_name ORDER BY n DESC",
"vrlFunctionQuery": "",
"customQuery": true,
"fields": {
"stream": "my_stream",
"stream_type": "logs",
"x": [
{ "label": "Host", "alias": "host_name", "column": "host_name", "color": null, "aggregationFunction": null }
],
"y": [
{
"label": "Count",
"alias": "n",
"column": "n",
"color": null,
"aggregationFunction": null,
"treatAsNonTimeseries": true
}
],
"z": [],
"breakdown": [],
"filter": { "filterType": "group", "logicalOperator": "AND", "conditions": [] }
},
"config": { "promql_legend": "", "layer_type": "scatter", "weight_fixed": 1, "limit": 0, "min": 0, "max": 100 }
}
],
"config": {
"show_legends": true,
"decimals": 2,
"unit": "currency",
"unit_custom": "USD"
},
"layout": { "x": 0, "y": 0, "w": 48, "h": 14, "i": 1 }
}
パネルの type 値
metric(大きな数値を 1 つ表示)・table・bar・h-bar・stacked・h-stacked・line・area・area-stacked・scatter・pie・donut・heatmap・gauge・geomap・maps・sankey・html・markdown。
レイアウトグリッド
グリッドの幅は 96 列 です(2026 年 4 月、OpenObserve Cloud で返されたパネルレイアウトを調査して確認)。古いドキュメントには 192 列や 48 列と記載されています。判断に迷った場合は、同じ組織の既存のダッシュボードを GET し、表示された w の値をコピーしてください。高さは単位のない行数です(h: 7 = 小さなメトリクスパネル、h: 14 = 標準的なテーブル)。
便利な config キー
| キー | 効果 |
|---|---|
decimals | すべての数値列の小数点以下の桁数です(0 = 整数)。 |
unit | numbers | currency | bytes | seconds | milliseconds | microseconds | nanoseconds | percent | percent-1 |
unit_custom | unit=currency の場合、USD のような ISO コードを指定します。 |
show_legends | ブール値です。グラフのみで使用します。 |
legends_position | right | bottom。 |
axis_border_show | ブール値です。 |
line_interpolation | smooth | linear | step-start | step-end。 |
connect_nulls | ブール値です。折れ線/面グラフのみで使用します。 |
top_results | 折れ線/棒グラフの系列数の上限です(例:10)。 |
mark_line | [{name, type:'avg'|'max'|'min', value}] — 水平の基準線です。 |
6. 重大な落とし穴
6a. customQuery: true の場合の再集計 — 最もよくあるバグです。
手書きの SQL にすでに COUNT(*)、SUM(...)、AVG(...) などが含まれている場合、fields.y(および fields.x)の各項目で aggregationFunction: null を設定する必要があります。デフォルトの 'sum' により、OpenObserve はクライアント側で集計済みの列をさらに集計し、行が重複して数値が大幅に水増しされます。
// WRONG — produces duplicate rows
"y": [{"column":"messages", "aggregationFunction":"count"}]
// RIGHT — SQL already did the aggregation
"y": [{"column":"messages", "aggregationFunction":null, "treatAsNonTimeseries":true}]
6b. Table パネルでの複数の fields.y — 各 Y 項目が個別の系列/行として表示される場合があります。グループごとに 1 行だけを表示する Table では、fields.y の項目は 1 つだけ(任意の列)にしてください。レンダラーが SQL のすべての列をテーブルの列として表示します。
6c. customQuery: true を使用するメトリックパネル — 結果列を fields.y に明示的にマッピングする必要があります。
"y": [{"label":"Value", "alias":"value", "column":"value", "aggregationFunction":"sum", "treatAsNonTimeseries":false}]
メトリックパネルでは、表示する数値がどの列にあるかを把握する必要があります。
6d. ROUND とワイルドカードによるタイムスタンプの展開 — SUM(col) を ROUND(...) で囲むクエリに、OpenObserve のプランナーが _timestamp を自動的に挿入することがあります。その結果、Column "_timestamp" must appear in the GROUP BY clause エラーが発生します。回避策として、ROUND() を削除してパネルの decimals 設定を使用するか、事前にキャストします:CAST(SUM(...) AS DOUBLE)。
6e. PUT におけるハッシュベースの同時実行制御 — PUT が成功するたびにダッシュボードのハッシュが変わります。2 つのスクリプトから続けてダッシュボードを変更する場合、2 つ目のスクリプトでは再取得が必要です。現在のハッシュを取得するため、各 PUT の前に必ず再度 GET してください。
6f. start_time/end_time はマイクロ秒単位 — ミリ秒ではなく Date.now() * 1000 を使用します。1000 倍のずれがあると、エラーは発生しませんが、ヒットは返されません。
7. フォルダー/アラート/データ取り込み
フォルダー(v2 API):
curl $AUTH "$BASE/folders/dashboards" # list
curl $AUTH -X POST "$BASE/folders/dashboards" -d '{"name":"my-folder"}'
curl $AUTH "$BASE/folders/dashboards/name/<folder_name>" # lookup by name
folder_type ∈ dashboards | alerts | reports。
アラート:
curl $AUTH "$BASE/{stream}/alerts" # list per-stream
curl $AUTH -X POST "$BASE/{stream}/alerts" -d '{...}'
# templates and destinations are referenced by alert definitions:
curl $AUTH "$BASE/alerts/templates"
curl $AUTH "$BASE/alerts/destinations"
データ取り込み(独自のデータを POST します):
# JSON
curl $AUTH -X POST "$BASE/<stream>/_json" -d '[{"event":"foo","level":"info"}]'
# Multi-line JSON (one per line)
curl $AUTH -X POST "$BASE/<stream>/_multi" --data-binary @file.ndjson
# Elasticsearch bulk
curl $AUTH -X POST "$BASE/_bulk" --data-binary @bulk.txt
# OTLP HTTP
curl $AUTH -X POST "$BASE/v1/logs" -d @otlp-logs.json
curl $AUTH -X POST "$BASE/v1/traces" -d @otlp-traces.json
curl $AUTH -X POST "$BASE/v1/metrics" -d @otlp-metrics.json
# Loki
curl $AUTH -X POST "$BASE/loki/api/v1/push" -d @loki.json
# Prometheus remote-write (binary protobuf)
curl $AUTH -X POST "$BASE/prometheus/api/v1/write" --data-binary @write.pb
8. よく使うレシピ
メッセージ数が多いホストを取得する(過去24時間):
NOW=$(($(date +%s) * 1000000))
DAY=$((NOW - 86400 * 1000000))
curl $AUTH -H 'Content-Type: application/json' \
"$BASE/_search?type=logs" \
-d "{\"query\":{\"sql\":\"SELECT host_name, COUNT(*) AS n FROM \\\"my_stream\\\" GROUP BY host_name ORDER BY n DESC\",\"start_time\":$DAY,\"end_time\":$NOW,\"size\":50}}"
既存のダッシュボードにメトリックパネルを追加する(単発実行、ハッシュを考慮):
DASH_ID=<dashboard_id>
HASH=$(curl -s $AUTH "$BASE/dashboards/$DASH_ID?folder=default" | jq -r .hash)
curl $AUTH -X POST -H 'Content-Type: application/json' \
"$BASE/dashboards/$DASH_ID/panels?folder=default&hash=$HASH" \
-d '{
"tabId": "default",
"panel": {
"id": "p-cost",
"type": "metric",
"title": "Total cost (USD)",
"queryType": "sql",
"queries": [{
"query": "SELECT SUM(CAST(cost_usd AS DOUBLE)) AS value FROM \"my_stream\"",
"customQuery": true,
"fields": {
"stream":"my_stream", "stream_type":"logs",
"x":[], "z":[], "breakdown":[],
"y":[{"label":"Value","alias":"value","column":"value","aggregationFunction":"sum","treatAsNonTimeseries":false}],
"filter":{"filterType":"group","logicalOperator":"AND","conditions":[]}
},
"config":{}
}],
"config": {"unit":"currency","unit_custom":"USD","decimals":2},
"layout": {"x":0,"y":0,"w":32,"h":7,"i":99}
}
}'
ダッシュボードをゼロから作成する:既存のダッシュボードのパネル JSON をテンプレートとして GET します(サーバーが受け付ける正確なフィールド形式を確認するには、これが最も安全な方法です)。次に、tabs[0].panels 配列を変更し、ラップされていない v8 本文を PUT で戻します。動作する例については、このスキルに含まれる references/recipes/build-dashboard.sh スクリプトを参照してください。
9. SDK/クライアント(ファーストパーティの CLI はありません)
| 言語 | リポジトリ | ステータス |
|---|---|---|
| Python | github.com/openobserve/openobserve-python-sdk | アクティブ |
| Go | github.com/openobserve/openobserve-go-client | ZincObserve 時代、一部対応 |
| Helm chart | github.com/openobserve/openobserve-helm-chart | アクティブ |
| OTel collector distro | github.com/openobserve/openobserve-otel-collector | アクティブ |
多くのエージェントのタスクでは、REST API に対して curl を直接使うのが適切です。SDK は HTTP リクエストよりも付加価値がほとんどなく、サーバーの機能への対応も遅れています。
参考資料
- API ドキュメント(正式版):https://github.com/openobserve/openobserve-docs(パス:`docs/reference/api/`)
- サーバーのソース:https://github.com/openobserve/openobserve(パス:`src/handler/http/request/`、`src/config/src/meta/dashboards/v8/mod.rs`)
- クラウドコンソール:https://cloud.openobserve.ai(リージョン:us1、eu1、ap1)
- このスキルの
references/ディレクトリには、オフラインで参照できるよう、openobserve-docsの選択したドキュメントが含まれています。