-
Notifications
You must be signed in to change notification settings - Fork 556
Feature/openclaw integration #17936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feature/openclaw integration #17936
Changes from all commits
b1f7248
e341e3f
a9dc937
66e91c4
10f02b5
b561d5b
e431c1e
dcb275d
4b823bf
e090acf
317db3a
a67ec03
7f376a9
b4870fb
cf0c9c5
897d83e
256b755
01d2649
e7eba8c
f49fe3a
7b9c824
303cf01
b02dad9
1e14297
2c251bb
da73164
24078df
96dff7f
53e8f17
ca2b0b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,4 @@ elastic-package | |
|
|
||
| # Folder created by the Sonar Scanner | ||
| .scannerwork/ | ||
| deploy_openclaw.sh | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # OpenClaw Integration | ||
|
|
||
| The OpenClaw integration allows you to ingest and monitor LLM observability metrics, session logs, and assistant usage data from the OpenClaw AI agent framework. | ||
|
|
||
| It provides a comprehensive view of: | ||
| - **Token Consumption**: Input and output tokens used per request. | ||
| - **Cost Analysis**: Financial cost incurred per model and session. | ||
| - **Tool Usage**: Which tools (skills) were executed and their frequencies. | ||
| - **Latency**: End-to-end response time of the AI agent. | ||
|
|
||
| ## Data Streams | ||
|
|
||
| This integration includes the following data streams: | ||
|
|
||
| ### Sessions Data Stream (`sessions`) | ||
|
|
||
| The `sessions` data stream collects detailed, turn-by-turn interactions from OpenClaw, capturing user prompts, agent thoughts, final responses, and internal metadata (like model versions and token counts). | ||
|
|
||
| **Exported Fields** | ||
|
|
||
| For a detailed list of exported fields, refer to the [ECS Field Reference](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) and the specific fields listed below: | ||
|
|
||
| {{fields "sessions"}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| version: "3.8" | ||
| services: | ||
| dummy: | ||
| image: busybox | ||
| command: ["sleep", "infinity"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| - version: "1.0.3" | ||
| changes: | ||
| - description: "Change text and thinking field mapping to match_only_text" | ||
| type: "bugfix" | ||
| link: "https://github.com/elastic/integrations/pull/17936" | ||
| - version: "1.0.2" | ||
| changes: | ||
| - description: "Fix missing macro expansion in README by moving it to _dev/build/docs/" | ||
| type: "bugfix" | ||
| link: "https://github.com/elastic/integrations/pull/3" | ||
| - version: "1.0.1" | ||
| changes: | ||
| - description: "Update dashboard fields and refresh deployment" | ||
| type: "bugfix" | ||
| link: "https://github.com/elastic/integrations/pull/2" | ||
| - version: "1.0.0" | ||
| changes: | ||
| - description: "Initial release" | ||
| type: "enhancement" | ||
| link: "https://github.com/elastic/integrations/pull/1" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {"timestamp":"2026-03-19T02:57:28.310Z","message":{"role":"assistant","model":"gemini-3.1-pro-preview","usage":{"input":13362,"output":437,"totalTokens":13799,"cost":{"total":0.031968}},"content":[{"type":"text","text":"Simulated text"},{"type":"thinking","thinking":"Thinking..."},{"type":"toolCall","name":"weather","arguments":{"city":"London"}}]}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| dynamic_fields: | ||
| "openclaw.agent.id": ".*" | ||
| "openclaw.session.id": ".*" | ||
| "event.ingested": ".*" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| { | ||
| "expected": [ | ||
| { | ||
| "@timestamp": "2026-03-19T02:57:28.310Z", | ||
| "event": { | ||
| "ingested": "2026-03-21T04:33:21.503436214Z" | ||
| }, | ||
| "openclaw": { | ||
| "cost": { | ||
| "usd": 0.031968 | ||
| }, | ||
| "model": "gemini-3.1-pro-preview", | ||
| "role": "assistant", | ||
| "text": "Simulated text", | ||
| "thinking": "Thinking...", | ||
| "tool_calls": [ | ||
| { | ||
| "arguments": { | ||
| "city": "London" | ||
| }, | ||
| "name": "weather" | ||
| } | ||
| ], | ||
| "usage": { | ||
| "input_tokens": 13362, | ||
| "output_tokens": 437, | ||
| "total_tokens": 13799 | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| paths: | ||
| {{#each paths}} | ||
| - {{this}} | ||
| {{/each}} | ||
| exclude_files: [".gz$"] | ||
| tags: | ||
| {{#if tags}} | ||
| {{#each tags}} | ||
| - {{this}} | ||
| {{/each}} | ||
| {{/if}} | ||
| {{#contains "forwarded" tags}} | ||
| publisher_pipeline.disable_host: true | ||
| {{/contains}} | ||
| processors: | ||
| - add_locale: ~ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| --- | ||
| description: Pipeline for parsing OpenClaw session JSONL logs | ||
| processors: | ||
| - set: | ||
| field: event.ingested | ||
| value: '{{_ingest.timestamp}}' | ||
| - json: | ||
| field: message | ||
| target_field: openclaw | ||
| ignore_failure: true | ||
| - grok: | ||
| field: log.file.path | ||
| patterns: | ||
| - '%{GREEDYDATA}/agents/(?<openclaw.agent.id>[^/]+)/sessions/(?<openclaw.session.id>[^/]+)\.jsonl$' | ||
| ignore_missing: true | ||
| ignore_failure: true | ||
| - date: | ||
| if: ctx?.openclaw?.timestamp != null | ||
| field: openclaw.timestamp | ||
| target_field: "@timestamp" | ||
| formats: | ||
| - ISO8601 | ||
| - rename: | ||
| field: openclaw.message.role | ||
| target_field: openclaw.role | ||
| ignore_missing: true | ||
| - rename: | ||
| field: openclaw.message.model | ||
| target_field: openclaw.model | ||
| ignore_missing: true | ||
| - rename: | ||
| field: openclaw.message.usage.input | ||
| target_field: openclaw.usage.input_tokens | ||
| ignore_missing: true | ||
| - rename: | ||
| field: openclaw.message.usage.output | ||
| target_field: openclaw.usage.output_tokens | ||
| ignore_missing: true | ||
| - rename: | ||
| field: openclaw.message.usage.totalTokens | ||
| target_field: openclaw.usage.total_tokens | ||
| ignore_missing: true | ||
| - rename: | ||
| field: openclaw.message.usage.cost.total | ||
| target_field: openclaw.cost.usd | ||
| ignore_missing: true | ||
| - script: | ||
| description: "Extract text, thinking, and tool_calls from content array" | ||
| lang: painless | ||
| if: "ctx.openclaw?.message?.content != null" | ||
| source: | | ||
| def content = ctx.openclaw.message.content; | ||
| if (content instanceof List) { | ||
| def tool_calls = []; | ||
| for (def item : content) { | ||
| if (item.type == 'text' && item.text != null) { | ||
| ctx.openclaw.text = item.text; | ||
| } else if (item.type == 'thinking' && item.thinking != null) { | ||
| ctx.openclaw.thinking = item.thinking; | ||
| } else if (item.type == 'toolCall') { | ||
| def tc = new HashMap(); | ||
| if (item.name != null) { | ||
| tc.put('name', item.name); | ||
| } | ||
| if (item.arguments != null) { | ||
| tc.put('arguments', item.arguments); | ||
| } | ||
| tool_calls.add(tc); | ||
| } | ||
| } | ||
| if (tool_calls.size() > 0) { | ||
| ctx.openclaw.tool_calls = tool_calls; | ||
| } | ||
| } else if (content instanceof String) { | ||
| ctx.openclaw.text = content; | ||
| } | ||
| - remove: | ||
| field: | ||
| - message | ||
| - openclaw.message | ||
| - openclaw.timestamp | ||
| ignore_missing: true | ||
| on_failure: | ||
| - set: | ||
| field: error.message | ||
| value: "{{ _ingest.on_failure_message }}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| - name: "@timestamp" | ||
| type: date | ||
| description: Event timestamp. | ||
| - name: data_stream.type | ||
| type: constant_keyword | ||
| description: Data stream type. | ||
| - name: data_stream.dataset | ||
| type: constant_keyword | ||
| description: Data stream dataset. | ||
| - name: data_stream.namespace | ||
| type: constant_keyword | ||
| description: Data stream namespace. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| - name: openclaw | ||
| type: group | ||
| fields: | ||
| - name: cost.usd | ||
| type: float | ||
| description: Cost in USD | ||
| - name: model | ||
| type: keyword | ||
| description: Model name | ||
| - name: role | ||
| type: keyword | ||
| description: Role of the message sender (user or assistant) | ||
| - name: text | ||
| type: match_only_text | ||
| description: Text content of the interaction | ||
| - name: thinking | ||
| type: match_only_text | ||
| description: Internal thinking process | ||
| - name: tool_calls | ||
| type: group | ||
| description: Tool calls invoked during the session | ||
| fields: | ||
| - name: name | ||
| type: keyword | ||
| description: Name of the tool called | ||
| - name: arguments | ||
| type: flattened | ||
| description: Arguments passed to the tool | ||
| - name: usage.input_tokens | ||
| type: long | ||
| description: Number of input tokens | ||
| - name: usage.output_tokens | ||
| type: long | ||
| description: Number of output tokens | ||
| - name: usage.total_tokens | ||
| type: long | ||
| description: Total token usage | ||
| - name: agent.id | ||
| type: keyword | ||
| description: Agent ID | ||
| - name: session.id | ||
| type: keyword | ||
| description: Session ID |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| type: logs | ||
| title: OpenClaw Sessions | ||
| release: beta | ||
| streams: | ||
| - input: logfile | ||
| title: OpenClaw Session Logs | ||
| description: Collects OpenClaw JSONL session files | ||
| vars: | ||
| - name: paths | ||
| type: text | ||
| title: Paths | ||
| multi: true | ||
| required: true | ||
| show_user: true | ||
| default: | ||
| - ~/.openclaw/agents/*/sessions/*.jsonl* | ||
|
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 High The default path default:
- - ~/.openclaw/agents/*/sessions/*.jsonl*
+ - /home/*/.openclaw/agents/*/sessions/*.jsonl*🤖 Copy this AI Prompt to have your agent fix this: |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # OpenClaw Integration | ||
|
|
||
| The OpenClaw integration allows you to ingest and monitor LLM observability metrics, session logs, and assistant usage data from the OpenClaw AI agent framework. | ||
|
|
||
| It provides a comprehensive view of: | ||
| - **Token Consumption**: Input and output tokens used per request. | ||
| - **Cost Analysis**: Financial cost incurred per model and session. | ||
| - **Tool Usage**: Which tools (skills) were executed and their frequencies. | ||
| - **Latency**: End-to-end response time of the AI agent. | ||
|
|
||
| ## Data Streams | ||
|
|
||
| This integration includes the following data streams: | ||
|
|
||
| ### Sessions Data Stream (`sessions`) | ||
|
|
||
| The `sessions` data stream collects detailed, turn-by-turn interactions from OpenClaw, capturing user prompts, agent thoughts, final responses, and internal metadata (like model versions and token counts). | ||
|
|
||
| **Exported Fields** | ||
|
|
||
| For a detailed list of exported fields, refer to the [ECS Field Reference](https://www.elastic.co/guide/en/ecs/current/ecs-field-reference.html) and the specific fields listed below: | ||
|
|
||
| **Exported fields** | ||
|
|
||
| | Field | Description | Type | | ||
| |---|---|---| | ||
| | @timestamp | Event timestamp. | date | | ||
| | data_stream.dataset | Data stream dataset. | constant_keyword | | ||
| | data_stream.namespace | Data stream namespace. | constant_keyword | | ||
| | data_stream.type | Data stream type. | constant_keyword | | ||
| | openclaw.agent.id | Agent ID | keyword | | ||
| | openclaw.cost.usd | Cost in USD | float | | ||
| | openclaw.model | Model name | keyword | | ||
| | openclaw.role | Role of the message sender (user or assistant) | keyword | | ||
| | openclaw.session.id | Session ID | keyword | | ||
| | openclaw.text | Text content of the interaction | match_only_text | | ||
| | openclaw.thinking | Internal thinking process | match_only_text | | ||
| | openclaw.tool_calls.arguments | Arguments passed to the tool | flattened | | ||
| | openclaw.tool_calls.name | Name of the tool called | keyword | | ||
| | openclaw.usage.input_tokens | Number of input tokens | long | | ||
| | openclaw.usage.output_tokens | Number of output tokens | long | | ||
| | openclaw.usage.total_tokens | Total token usage | long | | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Howdy from @elastic/ecosystem - Can we discuss more about the future of this integration and how you're expecting ownership to work here? This is the first we're seeing this and we're on the hook at codeowners here. We don't use or understand OpenClaw enough to be considered subject matter experts and maintain this package.