mcpField
O
openobserve-api

openobserve-api

github.com/fcakyonクラウド・DevOps1.2k45 回インストール今日更新
リポジトリ

openobserve-api について

curlでOpenObserveを操作するAIエージェント向けのREST APIガイドです。最新のAPI情報の取得を重視し、ダッシュボード構造やよくある注意点も説明します。

主な機能

  1. 01REST経由でログ、メトリクス、トレースを検索
  2. 02ストリーム、ダッシュボード、フォルダー、アラートを管理
  3. 03curlでJSONやバルクデータを取り込み
  4. 04パネル構造とハッシュベースの同時更新を解説
  5. 05API情報の取得と注意点を案内

活用シーン

  1. 01ログを分析し、ホストごとに件数を集計
  2. 02ダッシュボードやパネルを作成・更新
  3. 03アラートを設定し、ストリームにデータを投入

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/fcakyon/claude-codex-settings --skill openobserve-api

インストール後、Claude Code で/openobserve-apiを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
around.md
bulk.md
delete.md
index.md
json.md
list.md
loki.md
multi.md
otlp.md
schema.md
search.md
setting.md
value.md
references/recipes/
build-dashboard.sh
search-logs.sh
update-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 = 整数)。
unitnumbers | currency | bytes | seconds | milliseconds | microseconds | nanoseconds | percent | percent-1
unit_customunit=currency の場合、USD のような ISO コードを指定します。
show_legendsブール値です。グラフのみで使用します。
legends_positionright | bottom。
axis_border_showブール値です。
line_interpolationsmooth | 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 はありません)

言語リポジトリステータス
Pythongithub.com/openobserve/openobserve-python-sdkアクティブ
Gogithub.com/openobserve/openobserve-go-clientZincObserve 時代、一部対応
Helm chartgithub.com/openobserve/openobserve-helm-chartアクティブ
OTel collector distrogithub.com/openobserve/openobserve-otel-collectorアクティブ

多くのエージェントのタスクでは、REST API に対して curl を直接使うのが適切です。SDK は HTTP リクエストよりも付加価値がほとんどなく、サーバーの機能への対応も遅れています。

参考資料

コメント