Tools
Logfire
Pydantic Logfire observability plugin for OpenClaw — OTEL GenAI semantic conventions, distributed tracing, token metrics
Install
npm install @ultrathink/openclaw-logfire
Configuration Example
{
"plugins": {
"entries": {
"logfire": {
"enabled": true,
"config": {}
}
}
}
}
README
# @ultrathink/openclaw-logfire
Pydantic [Logfire](https://pydantic.dev/logfire) observability plugin for [OpenClaw](https://openclaw.ai).
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.
## Quickstart
```bash
npm install @ultrathink/openclaw-logfire
```
Set your Logfire write token:
```bash
export LOGFIRE_TOKEN="your-token"
```
Add to `openclaw.json`:
```json
{
"plugins": {
"entries": {
"logfire": {
"enabled": true,
"config": {}
}
}
}
}
```
Restart OpenClaw. That's it — traces appear in your Logfire dashboard.
## What You Get
### Span Hierarchy
Every agent invocation produces a trace tree:
```
invoke_agent chief-of-staff (root span)
|-- execute_tool Read (file read)
|-- execute_tool exec (shell command)
|-- execute_tool Write (file write)
|-- execute_tool web_search (web search)
```
### Attributes (OTEL GenAI Semantic Conventions)
| Attribute | Example | Description |
|-----------|---------|-------------|
| `gen_ai.operation.name` | `invoke_agent` | Operation type |
| `gen_ai.agent.name` | `chief-of-staff` | Agent identifier |
| `gen_ai.conversation.id` | `session_abc123` | Session key |
| `gen_ai.tool.name` | `Read` | Tool being called |
| `gen_ai.tool.call.arguments` | `{"path": "/..."}` | Tool input (opt-in) |
| `gen_ai.usage.input_tokens` | `1024` | Prompt tokens |
| `gen_ai.usage.output_tokens` | `512` | Completion tokens |
| `error.type` | `ToolExecutionError` | Error classification |
| `exception.stacktrace` | `Error: ...` | Full stack trace |
| `openclaw.workspace` | `chief-of-staff` | Workspace name |
| `openclaw.channel` | `slack` | Message source |
### Metrics
| Metric | Type | Description |
|--------|------|-------------|
| `gen_ai.client.token.usage` | Histogram | Token counts by type (input/output) |
| `gen_ai.client.operation.duration` | Histogram | Agent invocation latency (seconds) |
### Error Tracing
Tool failures include full OTEL exception events:
- `exception.type` — Error class name
- `exception.message` — Error description
- `exception.stacktrace` — Full stack trace
Errors propagate up the span tree so the root `invoke_agent` span is marked as errored.
## Configuration
All settings are optional. Sensible defaults work out of the box.
```jsonc
{
"plugins": {
"entries": {
"logfire": {
"enabled": true,
"config": {
// Logfire project (enables clickable trace links in logs)
"projectUrl": "https://logfire.pydantic.dev/myorg/myproject",
"region": "us", // "us" or "eu"
"environment": "production",
"serviceName": "openclaw-agent",
// GenAI provider name for OTEL compliance
"providerName": "anthropic",
// Trace depth controls
"captureToolInput": true, // Record tool arguments
"captureToolOutput": false, // Record tool results (verbose)
"toolInputMaxLength": 2048, // Truncation limit
"captureStackTraces": true, // Stack traces on errors
"captureMessageContent": false, // Record message text (privacy)
"redactSecrets": true, // Strip API keys from tool args
// Distributed tracing (opt-in)
"distributedTracing": {
"enabled": false,
"urlPatterns": ["https://api.mycompany.com/*"]
},
// Metrics
"enableMetrics": true,
// Trace links
"enableTraceLinks": true
}
}
}
}
}
```
### Environment Variables
| Variable | Description |
|----------|-------------|
| `LOGFIRE_TOKEN` | Logfire write token (required) |
| `LOGFIRE_ENVIRONMENT` | Deployment environment fallback |
| `LOGFIRE_PROJECT_URL` | Project URL fallback |
| `LOGFIRE_PROVIDER_NAME` | Provider name fallback |
### Secret Redaction
When `redactSecrets: true` (default), the plugin strips values matching common patterns before recording tool arguments:
- API keys (`api_key: sk_live_...`)
- Platform tokens (`ghp_`, `gho_`, `glpat_`, `xoxb-`, etc.)
- JWTs (`eyJ...`)
- Bearer tokens, passwords, credentials
## Distributed Tracing
Connect OpenClaw traces to your backend services. When enabled, the plugin injects `traceparent` headers into HTTP calls made by exec/Bash tools.
```jsonc
{
"distributedTracing": {
"enabled": true,
"injectIntoCommands": true, // Add traceparent to curl/wget/httpie
"extractFromWebhooks": true, // Extract traceparent from inbound webhooks
"urlPatterns": [ // Only inject for matching URLs
"https://api.mycompany.com/*",
"http://localhost:8000/*"
]
}
}
```
This produces connected traces across services:
```
OpenClaw: invoke_agent chief-of-staff
|-- execute_tool exec (curl POST /v1/api)
|-- [Backend] FastAPI: POST /v1/api
|-- database query
|-- LLM call
```
Your backend must support W3C trace context extraction (most frameworks do: FastAPI with Logfire, Express with OTEL, etc.).
## Architecture
```
openclaw-logfire/src/
index.ts Plugin entry point + hook wiring
config.ts Typed configuration with defaults
otel.ts OTEL SDK initialization (Logfire OTLP)
hooks/
before-agent-start invoke_agent span creation
before-tool-call execute_tool span + context propagation
tool-result-persist Tool span close + errors + stack traces
agent-end Span close + metrics + trace link
message-received Channel attribution + inbound context
context/
span-store Session -> active spans (LIFO tool stack)
propagation W3C traceparent inject/extract
metrics/
genai-metrics Token usage + operation duration histograms
events/
inference-details Opt-in inference operation event
```
### OpenClaw Hooks Used
| Hook | Purpose |
|------|---------|
| `before_agent_start` | Create root `invoke_agent` span |
| `before_tool_call` | Create `execute_tool` child span |
| `tool_result_persist` | Close tool span, record errors |
| `agent_end` | Close spans, emit metrics |
| `message_received` | Enrich with channel info |
Requires OpenClaw >= 2026.2.1 (`before_tool_call` was wired in that version).
## Development
```bash
git clone https://github.com/Ultrathink-Solutions/openclaw-logfire
cd openclaw-logfire
npm install
npm run typecheck
npm test
```
### Local testing with OpenClaw
```bash
# Symlink into OpenClaw extensions
ln -s $(pwd) ~/.openclaw/extensions/openclaw-logfire
# Or add to openclaw.json
# "plugins": { "load": { "paths": ["./path/to/openclaw-logfire"] } }
export LOGFIRE_TOKEN="your-write-token"
openclaw restart
openclaw plugins list # Should show "logfire" as enabled
```
## License
MIT
tools
Comments
Sign in to leave a comment