@mastra/otel-bridge 1.5.5-alpha.0 → 1.5.5-alpha.2
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/README.md +7 -165
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -4,88 +4,13 @@ OpenTelemetry Bridge for Mastra Observability.
|
|
|
4
4
|
|
|
5
5
|
Enables bidirectional integration between Mastra and OpenTelemetry infrastructure, creating real OTEL spans for Mastra operations and maintaining proper trace hierarchy.
|
|
6
6
|
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
`@mastra/otel-bridge` connects Mastra's observability system with standard OpenTelemetry instrumentation through bidirectional integration:
|
|
10
|
-
|
|
11
|
-
**From OTEL to Mastra:**
|
|
12
|
-
|
|
13
|
-
- Reads from OTEL ambient context (AsyncLocalStorage) automatically
|
|
14
|
-
- Inherits trace ID and parent span ID from active OTEL spans
|
|
15
|
-
- Works with standard OTEL auto-instrumentation (no middleware needed)
|
|
16
|
-
|
|
17
|
-
**From Mastra to OTEL:**
|
|
18
|
-
|
|
19
|
-
- Creates real OTEL spans for Mastra operations (agents, LLM calls, tools, workflows)
|
|
20
|
-
- Maintains proper parent-child relationships in distributed traces
|
|
21
|
-
- Allows OTEL-instrumented code (DB calls, HTTP clients) within Mastra operations to nest correctly
|
|
22
|
-
- Exports spans with OTEL semantic conventions for GenAI operations
|
|
23
|
-
- Forwards Mastra log events to the globally-registered OTEL `LoggerProvider`. Logs that originate inside a Mastra span are emitted under that span's OTEL context, so backends correlate logs to traces using the standard OTLP fields. If no `LoggerProvider` is registered, log emission is a silent no-op.
|
|
24
|
-
|
|
25
7
|
## Installation
|
|
26
8
|
|
|
27
9
|
```bash
|
|
28
10
|
npm install @mastra/otel-bridge
|
|
29
|
-
# or
|
|
30
|
-
pnpm add @mastra/otel-bridge
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
For the standard OTEL setup (recommended), also install:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
|
|
37
|
-
# or
|
|
38
|
-
pnpm add @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Quick Start
|
|
42
|
-
|
|
43
|
-
### 1. Set up OpenTelemetry (Standard Pattern)
|
|
44
|
-
|
|
45
|
-
Create an `instrumentation.js` file and import it **before** any other code:
|
|
46
|
-
|
|
47
|
-
```javascript
|
|
48
|
-
// instrumentation.js
|
|
49
|
-
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
50
|
-
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
51
|
-
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
52
|
-
|
|
53
|
-
const sdk = new NodeSDK({
|
|
54
|
-
serviceName: 'my-service',
|
|
55
|
-
traceExporter: new OTLPTraceExporter({
|
|
56
|
-
url: 'http://localhost:4318/v1/traces',
|
|
57
|
-
}),
|
|
58
|
-
instrumentations: [
|
|
59
|
-
getNodeAutoInstrumentations({
|
|
60
|
-
// Automatically instruments Express, Fastify, HTTP, and many others
|
|
61
|
-
'@opentelemetry/instrumentation-fs': {
|
|
62
|
-
enabled: false,
|
|
63
|
-
},
|
|
64
|
-
}),
|
|
65
|
-
],
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
sdk.start();
|
|
69
|
-
|
|
70
|
-
process.on('SIGTERM', async () => {
|
|
71
|
-
await sdk.shutdown();
|
|
72
|
-
process.exit(0);
|
|
73
|
-
});
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Then import this file first in your application:
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
// IMPORTANT: Import instrumentation FIRST!
|
|
80
|
-
import './instrumentation.js';
|
|
81
|
-
|
|
82
|
-
// Now import your application code
|
|
83
|
-
import express from 'express';
|
|
84
|
-
import { Mastra } from '@mastra/core';
|
|
85
|
-
// ... rest of your imports
|
|
86
11
|
```
|
|
87
12
|
|
|
88
|
-
|
|
13
|
+
## Usage
|
|
89
14
|
|
|
90
15
|
```typescript
|
|
91
16
|
import { OtelBridge } from '@mastra/otel-bridge';
|
|
@@ -105,97 +30,14 @@ const mastra = new Mastra({
|
|
|
105
30
|
});
|
|
106
31
|
```
|
|
107
32
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
The OTEL SDK's auto-instrumentation handles context propagation automatically via AsyncLocalStorage. The bridge creates OTEL spans for all Mastra operations.
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
// Example: Express endpoint using Mastra agent
|
|
114
|
-
app.post('/chat', async (req, res) => {
|
|
115
|
-
// OTEL auto-instrumentation creates HTTP span
|
|
116
|
-
// Bridge inherits trace context and creates child spans for agent operations
|
|
117
|
-
const result = await myAgent.generate(req.body.message);
|
|
118
|
-
res.json(result);
|
|
119
|
-
});
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## How It Works
|
|
123
|
-
|
|
124
|
-
### Span Creation
|
|
125
|
-
|
|
126
|
-
When Mastra creates a span (agent run, LLM call, tool execution, etc.):
|
|
127
|
-
|
|
128
|
-
1. **Bridge creates OTEL span** at span creation time with:
|
|
129
|
-
- SpanKind (SERVER for agents/workflows, CLIENT for LLM/MCP tools, INTERNAL for others)
|
|
130
|
-
- Parent context (from active OTEL context or parent Mastra span)
|
|
131
|
-
- Initial span name
|
|
132
|
-
|
|
133
|
-
2. **Mastra uses OTEL IDs**:
|
|
134
|
-
- `spanId` = OTEL span's 16-char hex ID
|
|
135
|
-
- `traceId` = OTEL span's 32-char hex trace ID
|
|
136
|
-
- `parentSpanId` = parent OTEL span's ID
|
|
137
|
-
|
|
138
|
-
3. **Internal spans are skipped**:
|
|
139
|
-
- Only external spans (user-facing operations) create OTEL spans
|
|
140
|
-
- Internal spans (workflow internals) don't create OTEL spans to avoid orphaned references
|
|
141
|
-
|
|
142
|
-
### Span Finalization
|
|
143
|
-
|
|
144
|
-
When a Mastra span ends:
|
|
145
|
-
|
|
146
|
-
1. **Bridge retrieves OTEL span** from map using span ID
|
|
147
|
-
2. **Sets all final attributes** using SpanConverter (same formatting as otel-exporter):
|
|
148
|
-
- OTEL semantic conventions for GenAI (`gen_ai.*`)
|
|
149
|
-
- Model parameters, usage, finish reasons
|
|
150
|
-
- Tool names, inputs, outputs
|
|
151
|
-
- Error information
|
|
152
|
-
3. **Updates span name** to OTEL-compliant format (e.g., `chat gpt-4`, `agent.my-agent`)
|
|
153
|
-
4. **Ends OTEL span** and removes from map
|
|
154
|
-
|
|
155
|
-
### Context Execution
|
|
156
|
-
|
|
157
|
-
The bridge provides `executeInContext()` and `executeInContextSync()` to run code within a Mastra span's OTEL context. This allows OTEL-instrumented code (DB clients, HTTP clients) to nest correctly under Mastra spans.
|
|
158
|
-
|
|
159
|
-
### Log Forwarding
|
|
160
|
-
|
|
161
|
-
When a `LoggerProvider` is registered globally (e.g. via `@opentelemetry/sdk-logs`, or via `NodeSDK`'s `logRecordProcessor` option), the bridge forwards every Mastra log event to it as an OTEL `LogRecord`. Trace correlation is automatic:
|
|
162
|
-
|
|
163
|
-
1. If the log carries a `spanId` the bridge created an OTEL span for, the log is emitted under that span's stored OTEL context — so it nests beneath the Mastra span in distributed traces.
|
|
164
|
-
2. Otherwise, if the log carries `traceId` and `spanId`, those are attached to the emitted log record's `SpanContext` so backends can still correlate by ID.
|
|
165
|
-
3. Otherwise, the log is emitted under whatever OTEL context is currently active.
|
|
166
|
-
|
|
167
|
-
Log severity, message body, structured `data`, and `metadata` are mapped to the OTEL `LogRecord` shape. `mastra.traceId` / `mastra.spanId` attributes are also attached for backends that key off attributes only.
|
|
168
|
-
|
|
169
|
-
To wire up logs alongside traces, pass `logRecordProcessor` to `NodeSDK`:
|
|
170
|
-
|
|
171
|
-
```javascript
|
|
172
|
-
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
173
|
-
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
174
|
-
import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
175
|
-
|
|
176
|
-
const sdk = new NodeSDK({
|
|
177
|
-
// ...trace config as usual
|
|
178
|
-
logRecordProcessor: new BatchLogRecordProcessor(new OTLPLogExporter()),
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## Requirements
|
|
183
|
-
|
|
184
|
-
- **Dependencies**:
|
|
185
|
-
- `@mastra/core` >= 1.0.0
|
|
186
|
-
- `@opentelemetry/api` >= 1.9.0
|
|
187
|
-
- `@opentelemetry/api-logs` >= 0.215.0
|
|
188
|
-
|
|
189
|
-
**For Standard OTEL Setup:**
|
|
33
|
+
## Documentation
|
|
190
34
|
|
|
191
|
-
-
|
|
192
|
-
- `@opentelemetry/auto-instrumentations-node` >= 0.64.1
|
|
35
|
+
- [@mastra/otel-bridge documentation](https://mastra.ai/integrations/observability/opentelemetry)
|
|
193
36
|
|
|
194
|
-
|
|
37
|
+
## Changelog
|
|
195
38
|
|
|
196
|
-
|
|
197
|
-
- An OTLP log exporter for your protocol (e.g. `@opentelemetry/exporter-logs-otlp-http`)
|
|
39
|
+
See the [package changelog](https://github.com/mastra-ai/mastra/blob/main/observability/otel-bridge/CHANGELOG.md) for version history and release notes.
|
|
198
40
|
|
|
199
|
-
##
|
|
41
|
+
## Support
|
|
200
42
|
|
|
201
|
-
|
|
43
|
+
We have an [open community Discord](https://discord.gg/mastra-ai). Come and say hello and let us know if you have any questions or need any help getting things running.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/otel-bridge",
|
|
3
|
-
"version": "1.5.5-alpha.
|
|
3
|
+
"version": "1.5.5-alpha.2",
|
|
4
4
|
"description": "OpenTelemetry observability bridge for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@opentelemetry/api": "^1.9.1",
|
|
27
27
|
"@opentelemetry/api-logs": "^0.221.0",
|
|
28
|
-
"@mastra/
|
|
29
|
-
"@mastra/
|
|
28
|
+
"@mastra/observability": "1.17.5-alpha.2",
|
|
29
|
+
"@mastra/otel-exporter": "1.3.13-alpha.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@opentelemetry/sdk-logs": "^0.221.0",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"tsdown": "0.22.9",
|
|
36
36
|
"typescript": "^7.0.2",
|
|
37
37
|
"vitest": "4.1.10",
|
|
38
|
+
"@internal/lint": "0.0.129",
|
|
38
39
|
"@internal/types-builder": "0.0.104",
|
|
39
|
-
"@mastra/core": "1.64.0-alpha.
|
|
40
|
-
"@internal/lint": "0.0.129"
|
|
40
|
+
"@mastra/core": "1.64.0-alpha.8"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@mastra/core": ">=1.16.0-0 <2.0.0-0",
|