@ultrathink-solutions/openclaw-logfire 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +130 -0
- package/dist/config.js.map +1 -0
- package/dist/context/propagation.d.ts +22 -0
- package/dist/context/propagation.d.ts.map +1 -0
- package/dist/context/propagation.js +93 -0
- package/dist/context/propagation.js.map +1 -0
- package/dist/context/span-store.d.ts +46 -0
- package/dist/context/span-store.d.ts.map +1 -0
- package/dist/context/span-store.js +63 -0
- package/dist/context/span-store.js.map +1 -0
- package/dist/events/inference-details.d.ts +21 -0
- package/dist/events/inference-details.d.ts.map +1 -0
- package/dist/events/inference-details.js +37 -0
- package/dist/events/inference-details.js.map +1 -0
- package/dist/hooks/agent-end.d.ts +33 -0
- package/dist/hooks/agent-end.d.ts.map +1 -0
- package/dist/hooks/agent-end.js +91 -0
- package/dist/hooks/agent-end.js.map +1 -0
- package/dist/hooks/before-agent-start.d.ts +22 -0
- package/dist/hooks/before-agent-start.d.ts.map +1 -0
- package/dist/hooks/before-agent-start.js +50 -0
- package/dist/hooks/before-agent-start.js.map +1 -0
- package/dist/hooks/before-tool-call.d.ts +20 -0
- package/dist/hooks/before-tool-call.d.ts.map +1 -0
- package/dist/hooks/before-tool-call.js +58 -0
- package/dist/hooks/before-tool-call.js.map +1 -0
- package/dist/hooks/message-received.d.ts +19 -0
- package/dist/hooks/message-received.d.ts.map +1 -0
- package/dist/hooks/message-received.js +35 -0
- package/dist/hooks/message-received.js.map +1 -0
- package/dist/hooks/tool-result-persist.d.ts +19 -0
- package/dist/hooks/tool-result-persist.d.ts.map +1 -0
- package/dist/hooks/tool-result-persist.js +62 -0
- package/dist/hooks/tool-result-persist.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/genai-metrics.d.ts +20 -0
- package/dist/metrics/genai-metrics.d.ts.map +1 -0
- package/dist/metrics/genai-metrics.js +56 -0
- package/dist/metrics/genai-metrics.js.map +1 -0
- package/dist/otel.d.ts +10 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +70 -0
- package/dist/otel.js.map +1 -0
- package/dist/trace-link.d.ts +7 -0
- package/dist/trace-link.d.ts.map +1 -0
- package/dist/trace-link.js +14 -0
- package/dist/trace-link.js.map +1 -0
- package/dist/util.d.ts +38 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +108 -0
- package/dist/util.js.map +1 -0
- package/openclaw.plugin.json +174 -0
- package/package.json +87 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@ultrathink-solutions/openclaw-logfire` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-02-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release
|
|
13
|
+
- Full agent lifecycle tracing with OTEL GenAI semantic conventions
|
|
14
|
+
- `invoke_agent` root spans with agent name, session key, workspace, and channel attribution
|
|
15
|
+
- `execute_tool` child spans with tool arguments, duration, and result size
|
|
16
|
+
- Error tracing with OTEL exception events (type, message, stack trace)
|
|
17
|
+
- Token usage metrics (`gen_ai.client.token.usage` histogram)
|
|
18
|
+
- Operation duration metrics (`gen_ai.client.operation.duration` histogram)
|
|
19
|
+
- Pydantic Logfire OTLP HTTP export (US and EU regions)
|
|
20
|
+
- Clickable Logfire trace URLs in agent logs
|
|
21
|
+
- Secret redaction for API keys, platform tokens, JWTs, and credentials
|
|
22
|
+
- W3C traceparent injection into HTTP commands for distributed tracing
|
|
23
|
+
- W3C trace context extraction from inbound webhook headers
|
|
24
|
+
- Configurable trace depth (tool input/output capture, message content, inference events)
|
|
25
|
+
- Batch and simple span processor modes
|
|
26
|
+
- Zero-config quickstart (just set `LOGFIRE_TOKEN`)
|
|
27
|
+
|
|
28
|
+
[0.1.0]: https://github.com/Ultrathink-Solutions/openclaw-logfire/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ultrathink Solutions
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# @ultrathink/openclaw-logfire
|
|
2
|
+
|
|
3
|
+
Pydantic [Logfire](https://pydantic.dev/logfire) observability plugin for [OpenClaw](https://openclaw.ai).
|
|
4
|
+
|
|
5
|
+
Full agent lifecycle tracing aligned with [OTEL GenAI semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/) — tool calls, token metrics, error stack traces, and optional distributed tracing across services.
|
|
6
|
+
|
|
7
|
+
## Quickstart
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @ultrathink/openclaw-logfire
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Set your Logfire write token:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export LOGFIRE_TOKEN="your-token"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Add to `openclaw.json`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"plugins": {
|
|
24
|
+
"entries": {
|
|
25
|
+
"logfire": {
|
|
26
|
+
"enabled": true,
|
|
27
|
+
"config": {}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Restart OpenClaw. That's it — traces appear in your Logfire dashboard.
|
|
35
|
+
|
|
36
|
+
## What You Get
|
|
37
|
+
|
|
38
|
+
### Span Hierarchy
|
|
39
|
+
|
|
40
|
+
Every agent invocation produces a trace tree:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
invoke_agent chief-of-staff (root span)
|
|
44
|
+
|-- execute_tool Read (file read)
|
|
45
|
+
|-- execute_tool exec (shell command)
|
|
46
|
+
|-- execute_tool Write (file write)
|
|
47
|
+
|-- execute_tool web_search (web search)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Attributes (OTEL GenAI Semantic Conventions)
|
|
51
|
+
|
|
52
|
+
| Attribute | Example | Description |
|
|
53
|
+
|-----------|---------|-------------|
|
|
54
|
+
| `gen_ai.operation.name` | `invoke_agent` | Operation type |
|
|
55
|
+
| `gen_ai.agent.name` | `chief-of-staff` | Agent identifier |
|
|
56
|
+
| `gen_ai.conversation.id` | `session_abc123` | Session key |
|
|
57
|
+
| `gen_ai.tool.name` | `Read` | Tool being called |
|
|
58
|
+
| `gen_ai.tool.call.arguments` | `{"path": "/..."}` | Tool input (opt-in) |
|
|
59
|
+
| `gen_ai.usage.input_tokens` | `1024` | Prompt tokens |
|
|
60
|
+
| `gen_ai.usage.output_tokens` | `512` | Completion tokens |
|
|
61
|
+
| `error.type` | `ToolExecutionError` | Error classification |
|
|
62
|
+
| `exception.stacktrace` | `Error: ...` | Full stack trace |
|
|
63
|
+
| `openclaw.workspace` | `chief-of-staff` | Workspace name |
|
|
64
|
+
| `openclaw.channel` | `slack` | Message source |
|
|
65
|
+
|
|
66
|
+
### Metrics
|
|
67
|
+
|
|
68
|
+
| Metric | Type | Description |
|
|
69
|
+
|--------|------|-------------|
|
|
70
|
+
| `gen_ai.client.token.usage` | Histogram | Token counts by type (input/output) |
|
|
71
|
+
| `gen_ai.client.operation.duration` | Histogram | Agent invocation latency (seconds) |
|
|
72
|
+
|
|
73
|
+
### Error Tracing
|
|
74
|
+
|
|
75
|
+
Tool failures include full OTEL exception events:
|
|
76
|
+
|
|
77
|
+
- `exception.type` — Error class name
|
|
78
|
+
- `exception.message` — Error description
|
|
79
|
+
- `exception.stacktrace` — Full stack trace
|
|
80
|
+
|
|
81
|
+
Errors propagate up the span tree so the root `invoke_agent` span is marked as errored.
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
All settings are optional. Sensible defaults work out of the box.
|
|
86
|
+
|
|
87
|
+
```jsonc
|
|
88
|
+
{
|
|
89
|
+
"plugins": {
|
|
90
|
+
"entries": {
|
|
91
|
+
"logfire": {
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"config": {
|
|
94
|
+
// Logfire project (enables clickable trace links in logs)
|
|
95
|
+
"projectUrl": "https://logfire.pydantic.dev/myorg/myproject",
|
|
96
|
+
"region": "us", // "us" or "eu"
|
|
97
|
+
"environment": "production",
|
|
98
|
+
"serviceName": "openclaw-agent",
|
|
99
|
+
|
|
100
|
+
// GenAI provider name for OTEL compliance
|
|
101
|
+
"providerName": "anthropic",
|
|
102
|
+
|
|
103
|
+
// Trace depth controls
|
|
104
|
+
"captureToolInput": true, // Record tool arguments
|
|
105
|
+
"captureToolOutput": false, // Record tool results (verbose)
|
|
106
|
+
"toolInputMaxLength": 2048, // Truncation limit
|
|
107
|
+
"captureStackTraces": true, // Stack traces on errors
|
|
108
|
+
"captureMessageContent": false, // Record message text (privacy)
|
|
109
|
+
"redactSecrets": true, // Strip API keys from tool args
|
|
110
|
+
|
|
111
|
+
// Distributed tracing (opt-in)
|
|
112
|
+
"distributedTracing": {
|
|
113
|
+
"enabled": false,
|
|
114
|
+
"urlPatterns": ["https://api.mycompany.com/*"]
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Metrics
|
|
118
|
+
"enableMetrics": true,
|
|
119
|
+
|
|
120
|
+
// Trace links
|
|
121
|
+
"enableTraceLinks": true
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Environment Variables
|
|
130
|
+
|
|
131
|
+
| Variable | Description |
|
|
132
|
+
|----------|-------------|
|
|
133
|
+
| `LOGFIRE_TOKEN` | Logfire write token (required) |
|
|
134
|
+
| `LOGFIRE_ENVIRONMENT` | Deployment environment fallback |
|
|
135
|
+
| `LOGFIRE_PROJECT_URL` | Project URL fallback |
|
|
136
|
+
| `LOGFIRE_PROVIDER_NAME` | Provider name fallback |
|
|
137
|
+
|
|
138
|
+
### Secret Redaction
|
|
139
|
+
|
|
140
|
+
When `redactSecrets: true` (default), the plugin strips values matching common patterns before recording tool arguments:
|
|
141
|
+
|
|
142
|
+
- API keys (`api_key: sk_live_...`)
|
|
143
|
+
- Platform tokens (`ghp_`, `gho_`, `glpat_`, `xoxb-`, etc.)
|
|
144
|
+
- JWTs (`eyJ...`)
|
|
145
|
+
- Bearer tokens, passwords, credentials
|
|
146
|
+
|
|
147
|
+
## Distributed Tracing
|
|
148
|
+
|
|
149
|
+
Connect OpenClaw traces to your backend services. When enabled, the plugin injects `traceparent` headers into HTTP calls made by exec/Bash tools.
|
|
150
|
+
|
|
151
|
+
```jsonc
|
|
152
|
+
{
|
|
153
|
+
"distributedTracing": {
|
|
154
|
+
"enabled": true,
|
|
155
|
+
"injectIntoCommands": true, // Add traceparent to curl/wget/httpie
|
|
156
|
+
"extractFromWebhooks": true, // Extract traceparent from inbound webhooks
|
|
157
|
+
"urlPatterns": [ // Only inject for matching URLs
|
|
158
|
+
"https://api.mycompany.com/*",
|
|
159
|
+
"http://localhost:8000/*"
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
This produces connected traces across services:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
OpenClaw: invoke_agent chief-of-staff
|
|
169
|
+
|-- execute_tool exec (curl POST /v1/api)
|
|
170
|
+
|-- [Backend] FastAPI: POST /v1/api
|
|
171
|
+
|-- database query
|
|
172
|
+
|-- LLM call
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Your backend must support W3C trace context extraction (most frameworks do: FastAPI with Logfire, Express with OTEL, etc.).
|
|
176
|
+
|
|
177
|
+
## Architecture
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
openclaw-logfire/src/
|
|
181
|
+
index.ts Plugin entry point + hook wiring
|
|
182
|
+
config.ts Typed configuration with defaults
|
|
183
|
+
otel.ts OTEL SDK initialization (Logfire OTLP)
|
|
184
|
+
hooks/
|
|
185
|
+
before-agent-start invoke_agent span creation
|
|
186
|
+
before-tool-call execute_tool span + context propagation
|
|
187
|
+
tool-result-persist Tool span close + errors + stack traces
|
|
188
|
+
agent-end Span close + metrics + trace link
|
|
189
|
+
message-received Channel attribution + inbound context
|
|
190
|
+
context/
|
|
191
|
+
span-store Session -> active spans (LIFO tool stack)
|
|
192
|
+
propagation W3C traceparent inject/extract
|
|
193
|
+
metrics/
|
|
194
|
+
genai-metrics Token usage + operation duration histograms
|
|
195
|
+
events/
|
|
196
|
+
inference-details Opt-in inference operation event
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### OpenClaw Hooks Used
|
|
200
|
+
|
|
201
|
+
| Hook | Purpose |
|
|
202
|
+
|------|---------|
|
|
203
|
+
| `before_agent_start` | Create root `invoke_agent` span |
|
|
204
|
+
| `before_tool_call` | Create `execute_tool` child span |
|
|
205
|
+
| `tool_result_persist` | Close tool span, record errors |
|
|
206
|
+
| `agent_end` | Close spans, emit metrics |
|
|
207
|
+
| `message_received` | Enrich with channel info |
|
|
208
|
+
|
|
209
|
+
Requires OpenClaw >= 2026.2.1 (`before_tool_call` was wired in that version).
|
|
210
|
+
|
|
211
|
+
## Development
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
git clone https://github.com/Ultrathink-Solutions/openclaw-logfire
|
|
215
|
+
cd openclaw-logfire
|
|
216
|
+
npm install
|
|
217
|
+
npm run typecheck
|
|
218
|
+
npm test
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Local testing with OpenClaw
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Symlink into OpenClaw extensions
|
|
225
|
+
ln -s $(pwd) ~/.openclaw/extensions/openclaw-logfire
|
|
226
|
+
|
|
227
|
+
# Or add to openclaw.json
|
|
228
|
+
# "plugins": { "load": { "paths": ["./path/to/openclaw-logfire"] } }
|
|
229
|
+
|
|
230
|
+
export LOGFIRE_TOKEN="your-write-token"
|
|
231
|
+
openclaw restart
|
|
232
|
+
openclaw plugins list # Should show "logfire" as enabled
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin configuration with sensible defaults.
|
|
3
|
+
*
|
|
4
|
+
* Every option can be left unset for a zero-config quickstart —
|
|
5
|
+
* just export LOGFIRE_TOKEN and enable the plugin.
|
|
6
|
+
*/
|
|
7
|
+
export interface DistributedTracingConfig {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
injectIntoCommands: boolean;
|
|
10
|
+
extractFromWebhooks: boolean;
|
|
11
|
+
urlPatterns: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface BatchConfig {
|
|
14
|
+
maxQueueSize: number;
|
|
15
|
+
maxExportBatchSize: number;
|
|
16
|
+
scheduledDelayMs: number;
|
|
17
|
+
}
|
|
18
|
+
export interface LogfirePluginConfig {
|
|
19
|
+
token: string;
|
|
20
|
+
projectUrl: string;
|
|
21
|
+
region: 'us' | 'eu';
|
|
22
|
+
environment: string;
|
|
23
|
+
serviceName: string;
|
|
24
|
+
providerName: string;
|
|
25
|
+
captureToolInput: boolean;
|
|
26
|
+
captureToolOutput: boolean;
|
|
27
|
+
toolInputMaxLength: number;
|
|
28
|
+
toolOutputMaxLength: number;
|
|
29
|
+
captureStackTraces: boolean;
|
|
30
|
+
captureMessageContent: boolean;
|
|
31
|
+
captureToolDefinitions: boolean;
|
|
32
|
+
captureInferenceEvents: boolean;
|
|
33
|
+
redactSecrets: boolean;
|
|
34
|
+
distributedTracing: DistributedTracingConfig;
|
|
35
|
+
enableMetrics: boolean;
|
|
36
|
+
metricsIntervalMs: number;
|
|
37
|
+
enableTraceLinks: boolean;
|
|
38
|
+
logLevel: 'debug' | 'info' | 'warn' | 'error';
|
|
39
|
+
resourceAttributes: Record<string, string>;
|
|
40
|
+
spanProcessorType: 'batch' | 'simple';
|
|
41
|
+
batchConfig: BatchConfig;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Merge user-provided config with defaults and env vars.
|
|
45
|
+
* Env vars serve as fallbacks when explicit config is not set.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveConfig(userConfig: Record<string, unknown> | undefined): LogfirePluginConfig;
|
|
48
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAElC,KAAK,EAAE,MAAM,CAAC;IAGd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAGpB,YAAY,EAAE,MAAM,CAAC;IAGrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sBAAsB,EAAE,OAAO,CAAC;IAChC,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IAGvB,kBAAkB,EAAE,wBAAwB,CAAC;IAG7C,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAG1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAG9C,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,iBAAiB,EAAE,OAAO,GAAG,QAAQ,CAAC;IACtC,WAAW,EAAE,WAAW,CAAC;CAC1B;AA0CD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,mBAAmB,CAoFrB"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* Plugin configuration with sensible defaults.
|
|
4
|
+
*
|
|
5
|
+
* Every option can be left unset for a zero-config quickstart —
|
|
6
|
+
* just export LOGFIRE_TOKEN and enable the plugin.
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULTS = {
|
|
9
|
+
token: '',
|
|
10
|
+
projectUrl: '',
|
|
11
|
+
region: 'us',
|
|
12
|
+
environment: '',
|
|
13
|
+
serviceName: 'openclaw-agent',
|
|
14
|
+
providerName: '',
|
|
15
|
+
captureToolInput: true,
|
|
16
|
+
captureToolOutput: false,
|
|
17
|
+
toolInputMaxLength: 2048,
|
|
18
|
+
toolOutputMaxLength: 512,
|
|
19
|
+
captureStackTraces: true,
|
|
20
|
+
captureMessageContent: false,
|
|
21
|
+
captureToolDefinitions: false,
|
|
22
|
+
captureInferenceEvents: false,
|
|
23
|
+
redactSecrets: true,
|
|
24
|
+
distributedTracing: {
|
|
25
|
+
enabled: false,
|
|
26
|
+
injectIntoCommands: true,
|
|
27
|
+
extractFromWebhooks: true,
|
|
28
|
+
urlPatterns: ['*'],
|
|
29
|
+
},
|
|
30
|
+
enableMetrics: true,
|
|
31
|
+
metricsIntervalMs: 60_000,
|
|
32
|
+
enableTraceLinks: true,
|
|
33
|
+
logLevel: 'info',
|
|
34
|
+
resourceAttributes: {},
|
|
35
|
+
spanProcessorType: 'batch',
|
|
36
|
+
batchConfig: {
|
|
37
|
+
maxQueueSize: 2048,
|
|
38
|
+
maxExportBatchSize: 512,
|
|
39
|
+
scheduledDelayMs: 5000,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Merge user-provided config with defaults and env vars.
|
|
44
|
+
* Env vars serve as fallbacks when explicit config is not set.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveConfig(userConfig) {
|
|
47
|
+
const raw = userConfig ?? {};
|
|
48
|
+
const distributedTracingRaw = raw.distributedTracing ?? {};
|
|
49
|
+
const batchConfigRaw = raw.batchConfig ?? {};
|
|
50
|
+
return {
|
|
51
|
+
token: asString(raw.token) ||
|
|
52
|
+
process.env.LOGFIRE_TOKEN ||
|
|
53
|
+
'',
|
|
54
|
+
projectUrl: asString(raw.projectUrl) ||
|
|
55
|
+
process.env.LOGFIRE_PROJECT_URL ||
|
|
56
|
+
DEFAULTS.projectUrl,
|
|
57
|
+
region: asEnum(raw.region, ['us', 'eu']) ?? DEFAULTS.region,
|
|
58
|
+
environment: asString(raw.environment) ||
|
|
59
|
+
process.env.LOGFIRE_ENVIRONMENT ||
|
|
60
|
+
'development',
|
|
61
|
+
serviceName: asString(raw.serviceName) || DEFAULTS.serviceName,
|
|
62
|
+
providerName: asString(raw.providerName) ||
|
|
63
|
+
process.env.LOGFIRE_PROVIDER_NAME ||
|
|
64
|
+
DEFAULTS.providerName,
|
|
65
|
+
captureToolInput: asBool(raw.captureToolInput) ?? DEFAULTS.captureToolInput,
|
|
66
|
+
captureToolOutput: asBool(raw.captureToolOutput) ?? DEFAULTS.captureToolOutput,
|
|
67
|
+
toolInputMaxLength: asInt(raw.toolInputMaxLength) ?? DEFAULTS.toolInputMaxLength,
|
|
68
|
+
toolOutputMaxLength: asInt(raw.toolOutputMaxLength) ?? DEFAULTS.toolOutputMaxLength,
|
|
69
|
+
captureStackTraces: asBool(raw.captureStackTraces) ?? DEFAULTS.captureStackTraces,
|
|
70
|
+
captureMessageContent: asBool(raw.captureMessageContent) ?? DEFAULTS.captureMessageContent,
|
|
71
|
+
captureToolDefinitions: asBool(raw.captureToolDefinitions) ?? DEFAULTS.captureToolDefinitions,
|
|
72
|
+
captureInferenceEvents: asBool(raw.captureInferenceEvents) ?? DEFAULTS.captureInferenceEvents,
|
|
73
|
+
redactSecrets: asBool(raw.redactSecrets) ?? DEFAULTS.redactSecrets,
|
|
74
|
+
distributedTracing: {
|
|
75
|
+
enabled: asBool(distributedTracingRaw.enabled) ??
|
|
76
|
+
DEFAULTS.distributedTracing.enabled,
|
|
77
|
+
injectIntoCommands: asBool(distributedTracingRaw.injectIntoCommands) ??
|
|
78
|
+
DEFAULTS.distributedTracing.injectIntoCommands,
|
|
79
|
+
extractFromWebhooks: asBool(distributedTracingRaw.extractFromWebhooks) ??
|
|
80
|
+
DEFAULTS.distributedTracing.extractFromWebhooks,
|
|
81
|
+
urlPatterns: asStringArray(distributedTracingRaw.urlPatterns) ??
|
|
82
|
+
DEFAULTS.distributedTracing.urlPatterns,
|
|
83
|
+
},
|
|
84
|
+
enableMetrics: asBool(raw.enableMetrics) ?? DEFAULTS.enableMetrics,
|
|
85
|
+
metricsIntervalMs: asInt(raw.metricsIntervalMs) ?? DEFAULTS.metricsIntervalMs,
|
|
86
|
+
enableTraceLinks: asBool(raw.enableTraceLinks) ?? DEFAULTS.enableTraceLinks,
|
|
87
|
+
logLevel: asEnum(raw.logLevel, ['debug', 'info', 'warn', 'error']) ??
|
|
88
|
+
DEFAULTS.logLevel,
|
|
89
|
+
resourceAttributes: asStringRecord(raw.resourceAttributes) ?? DEFAULTS.resourceAttributes,
|
|
90
|
+
spanProcessorType: asEnum(raw.spanProcessorType, ['batch', 'simple']) ??
|
|
91
|
+
DEFAULTS.spanProcessorType,
|
|
92
|
+
batchConfig: {
|
|
93
|
+
maxQueueSize: asInt(batchConfigRaw.maxQueueSize) ?? DEFAULTS.batchConfig.maxQueueSize,
|
|
94
|
+
maxExportBatchSize: asInt(batchConfigRaw.maxExportBatchSize) ??
|
|
95
|
+
DEFAULTS.batchConfig.maxExportBatchSize,
|
|
96
|
+
scheduledDelayMs: asInt(batchConfigRaw.scheduledDelayMs) ??
|
|
97
|
+
DEFAULTS.batchConfig.scheduledDelayMs,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// --- type coercion helpers ---
|
|
102
|
+
function asString(v) {
|
|
103
|
+
return typeof v === 'string' ? v : '';
|
|
104
|
+
}
|
|
105
|
+
function asBool(v) {
|
|
106
|
+
return typeof v === 'boolean' ? v : undefined;
|
|
107
|
+
}
|
|
108
|
+
function asInt(v) {
|
|
109
|
+
return typeof v === 'number' && Number.isInteger(v) ? v : undefined;
|
|
110
|
+
}
|
|
111
|
+
function asEnum(v, allowed) {
|
|
112
|
+
return typeof v === 'string' && allowed.includes(v)
|
|
113
|
+
? v
|
|
114
|
+
: undefined;
|
|
115
|
+
}
|
|
116
|
+
function asStringArray(v) {
|
|
117
|
+
return Array.isArray(v) && v.every((x) => typeof x === 'string')
|
|
118
|
+
? v
|
|
119
|
+
: undefined;
|
|
120
|
+
}
|
|
121
|
+
function asStringRecord(v) {
|
|
122
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
123
|
+
return undefined;
|
|
124
|
+
const entries = Object.entries(v);
|
|
125
|
+
if (entries.every(([, val]) => typeof val === 'string')) {
|
|
126
|
+
return v;
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W3C trace context propagation for distributed tracing.
|
|
3
|
+
*
|
|
4
|
+
* - Outbound: Injects traceparent into exec/Bash tool arguments
|
|
5
|
+
* when they contain HTTP calls matching configured URL patterns.
|
|
6
|
+
* - Inbound: Extracts traceparent from webhook headers for span linking.
|
|
7
|
+
*/
|
|
8
|
+
import { type Span, type SpanContext } from '@opentelemetry/api';
|
|
9
|
+
import type { BeforeToolCallEvent } from '../hooks/before-tool-call.js';
|
|
10
|
+
/**
|
|
11
|
+
* Inject W3C traceparent into exec/Bash tool arguments.
|
|
12
|
+
*
|
|
13
|
+
* Detects curl/wget/httpie commands and appends trace headers.
|
|
14
|
+
* Only injects if the target URL matches one of the configured patterns.
|
|
15
|
+
*/
|
|
16
|
+
export declare function injectTraceContext(event: BeforeToolCallEvent, parentSpan: Span, urlPatterns: string[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Extract W3C trace context from inbound webhook headers.
|
|
19
|
+
* Returns a SpanContext for adding as a span link, or null.
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractW3CContext(headers: Record<string, string>): SpanContext | null;
|
|
22
|
+
//# sourceMappingURL=propagation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.d.ts","sourceRoot":"","sources":["../../src/context/propagation.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,EAIL,KAAK,IAAI,EACT,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,IAAI,EAChB,WAAW,EAAE,MAAM,EAAE,GACpB,IAAI,CAwCN;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,WAAW,GAAG,IAAI,CAapB"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* W3C trace context propagation for distributed tracing.
|
|
4
|
+
*
|
|
5
|
+
* - Outbound: Injects traceparent into exec/Bash tool arguments
|
|
6
|
+
* when they contain HTTP calls matching configured URL patterns.
|
|
7
|
+
* - Inbound: Extracts traceparent from webhook headers for span linking.
|
|
8
|
+
*/
|
|
9
|
+
import { context, propagation, trace, } from '@opentelemetry/api';
|
|
10
|
+
import picomatch from 'picomatch';
|
|
11
|
+
/**
|
|
12
|
+
* Inject W3C traceparent into exec/Bash tool arguments.
|
|
13
|
+
*
|
|
14
|
+
* Detects curl/wget/httpie commands and appends trace headers.
|
|
15
|
+
* Only injects if the target URL matches one of the configured patterns.
|
|
16
|
+
*/
|
|
17
|
+
export function injectTraceContext(event, parentSpan, urlPatterns) {
|
|
18
|
+
const args = event.tool?.args;
|
|
19
|
+
if (!args)
|
|
20
|
+
return;
|
|
21
|
+
const command = typeof args === 'string'
|
|
22
|
+
? args
|
|
23
|
+
: args.command ??
|
|
24
|
+
args.cmd ??
|
|
25
|
+
'';
|
|
26
|
+
if (typeof command !== 'string')
|
|
27
|
+
return;
|
|
28
|
+
// Only inject into HTTP client commands
|
|
29
|
+
if (!isHttpCommand(command))
|
|
30
|
+
return;
|
|
31
|
+
// Check if the URL matches configured patterns
|
|
32
|
+
const url = extractUrlFromCommand(command);
|
|
33
|
+
if (!url || !matchesPatterns(url, urlPatterns))
|
|
34
|
+
return;
|
|
35
|
+
// Build the traceparent/tracestate headers
|
|
36
|
+
const carrier = {};
|
|
37
|
+
const ctx = trace.setSpan(context.active(), parentSpan);
|
|
38
|
+
propagation.inject(ctx, carrier);
|
|
39
|
+
if (!carrier.traceparent)
|
|
40
|
+
return;
|
|
41
|
+
// Append -H flags to the command
|
|
42
|
+
let headerFlags = ` -H "traceparent: ${carrier.traceparent}"`;
|
|
43
|
+
if (carrier.tracestate) {
|
|
44
|
+
headerFlags += ` -H "tracestate: ${carrier.tracestate}"`;
|
|
45
|
+
}
|
|
46
|
+
// Mutate the event's tool args to include trace headers
|
|
47
|
+
if (typeof args === 'string') {
|
|
48
|
+
event.tool.args = args + headerFlags;
|
|
49
|
+
}
|
|
50
|
+
else if (typeof args.command === 'string') {
|
|
51
|
+
args.command += headerFlags;
|
|
52
|
+
}
|
|
53
|
+
else if (typeof args.cmd === 'string') {
|
|
54
|
+
args.cmd += headerFlags;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extract W3C trace context from inbound webhook headers.
|
|
59
|
+
* Returns a SpanContext for adding as a span link, or null.
|
|
60
|
+
*/
|
|
61
|
+
export function extractW3CContext(headers) {
|
|
62
|
+
const traceparent = headers.traceparent ?? headers.Traceparent ?? headers.TRACEPARENT;
|
|
63
|
+
if (!traceparent)
|
|
64
|
+
return null;
|
|
65
|
+
const carrier = { traceparent };
|
|
66
|
+
const tracestate = headers.tracestate ?? headers.Tracestate ?? headers.TRACESTATE;
|
|
67
|
+
if (tracestate)
|
|
68
|
+
carrier.tracestate = tracestate;
|
|
69
|
+
const extractedCtx = propagation.extract(context.active(), carrier);
|
|
70
|
+
const span = trace.getSpan(extractedCtx);
|
|
71
|
+
return span?.spanContext() ?? null;
|
|
72
|
+
}
|
|
73
|
+
// --- internal helpers ---
|
|
74
|
+
function isHttpCommand(cmd) {
|
|
75
|
+
return /\b(curl|wget|httpie|http)\b/i.test(cmd);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Best-effort URL extraction from a shell command string.
|
|
79
|
+
* Handles common patterns: curl URL, curl -X POST URL, etc.
|
|
80
|
+
*/
|
|
81
|
+
function extractUrlFromCommand(cmd) {
|
|
82
|
+
// Match URLs (http:// or https://) in the command
|
|
83
|
+
const match = cmd.match(/https?:\/\/[^\s"']+/);
|
|
84
|
+
return match ? match[0] : null;
|
|
85
|
+
}
|
|
86
|
+
function matchesPatterns(url, patterns) {
|
|
87
|
+
if (patterns.length === 0)
|
|
88
|
+
return false;
|
|
89
|
+
if (patterns.includes('*'))
|
|
90
|
+
return true;
|
|
91
|
+
return patterns.some((pattern) => picomatch.isMatch(url, pattern));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=propagation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propagation.js","sourceRoot":"","sources":["../../src/context/propagation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory store mapping OpenClaw session keys to active OTEL spans.
|
|
3
|
+
*
|
|
4
|
+
* Tool spans use a stack (LIFO) so nested tool calls close in the
|
|
5
|
+
* correct order. A TTL-based cleanup prevents memory leaks from
|
|
6
|
+
* sessions that never fire agent_end (e.g. gateway crash).
|
|
7
|
+
*/
|
|
8
|
+
import type { Span, Context } from '@opentelemetry/api';
|
|
9
|
+
export interface ToolSpanEntry {
|
|
10
|
+
span: Span;
|
|
11
|
+
ctx: Context;
|
|
12
|
+
name: string;
|
|
13
|
+
callId: string;
|
|
14
|
+
startTime: number;
|
|
15
|
+
}
|
|
16
|
+
export interface SessionSpanContext {
|
|
17
|
+
/** Root span: invoke_agent */
|
|
18
|
+
agentSpan: Span;
|
|
19
|
+
agentCtx: Context;
|
|
20
|
+
/** Tool call stack (LIFO for correct nesting) */
|
|
21
|
+
toolStack: ToolSpanEntry[];
|
|
22
|
+
/** Monotonic tool call counter for sequencing */
|
|
23
|
+
toolSequence: number;
|
|
24
|
+
/** Whether any tool errored (propagated to agent span) */
|
|
25
|
+
hasError: boolean;
|
|
26
|
+
/** Request start timestamp */
|
|
27
|
+
startTime: number;
|
|
28
|
+
}
|
|
29
|
+
declare class SpanStore {
|
|
30
|
+
private sessions;
|
|
31
|
+
set(sessionKey: string, ctx: SessionSpanContext): void;
|
|
32
|
+
get(sessionKey: string): SessionSpanContext | undefined;
|
|
33
|
+
delete(sessionKey: string): void;
|
|
34
|
+
/** Push a tool span onto the session's stack. */
|
|
35
|
+
pushTool(sessionKey: string, entry: ToolSpanEntry): void;
|
|
36
|
+
/** Pop the most recent tool span (LIFO). */
|
|
37
|
+
popTool(sessionKey: string): ToolSpanEntry | undefined;
|
|
38
|
+
/** Peek at the top of the tool stack without removing. */
|
|
39
|
+
peekTool(sessionKey: string): ToolSpanEntry | undefined;
|
|
40
|
+
get size(): number;
|
|
41
|
+
/** End orphaned spans and remove stale sessions. */
|
|
42
|
+
private cleanup;
|
|
43
|
+
}
|
|
44
|
+
export declare const spanStore: SpanStore;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=span-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"span-store.d.ts","sourceRoot":"","sources":["../../src/context/span-store.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAElB,iDAAiD;IACjD,SAAS,EAAE,aAAa,EAAE,CAAC;IAE3B,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IAErB,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAElB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,cAAM,SAAS;IACb,OAAO,CAAC,QAAQ,CAAyC;IAEzD,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAKtD,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIvD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,iDAAiD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAMxD,4CAA4C;IAC5C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAMtD,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAMvD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,oDAAoD;IACpD,OAAO,CAAC,OAAO;CAahB;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|