@gomcp/analytics 0.1.0 → 0.2.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/README.md +35 -14
- package/dist/analytics.d.ts +13 -1
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +18 -2
- package/dist/analytics.js.map +1 -1
- package/dist/collector.d.ts +27 -2
- package/dist/collector.d.ts.map +1 -1
- package/dist/collector.js +136 -29
- package/dist/collector.js.map +1 -1
- package/dist/exporters/otlp.js +14 -22
- package/dist/exporters/otlp.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +74 -15
- package/dist/middleware.js.map +1 -1
- package/dist/tracing.d.ts.map +1 -1
- package/dist/tracing.js +2 -1
- package/dist/tracing.js.map +1 -1
- package/dist/types.d.ts +20 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,9 @@ Lightweight analytics and observability for [Model Context Protocol](https://mod
|
|
|
8
8
|
- **Handler wrapping** — instrument individual tool handlers for granular control
|
|
9
9
|
- **Multiple exporters** — console, JSON file, OpenTelemetry OTLP, or custom functions
|
|
10
10
|
- **In-memory stats** — p50/p95/p99 latencies, error rates, call counts per tool
|
|
11
|
+
- **Session analytics** — aggregated metrics per `sessionId` with top-session ranking
|
|
11
12
|
- **Sampling** — configurable sample rate to control overhead
|
|
13
|
+
- **Bounded percentile memory** — keeps a fixed recent latency window per accumulator
|
|
12
14
|
- **Zero required deps** — only `@modelcontextprotocol/sdk` as a peer dependency
|
|
13
15
|
|
|
14
16
|
## Installation
|
|
@@ -60,6 +62,8 @@ Create an analytics instance.
|
|
|
60
62
|
| `flushIntervalMs` | `number` | `5000` | How often to flush events to the exporter |
|
|
61
63
|
| `maxBufferSize` | `number` | `10000` | Max events in the ring buffer |
|
|
62
64
|
| `metadata` | `Record<string, string>` | — | Metadata added to every event |
|
|
65
|
+
| `samplingStrategy`| `"per_call" \| "per_session"` | `"per_call"` | Sampling behavior for transport instrumentation |
|
|
66
|
+
| `toolWindowSize` | `number` | `2048` | Recent durations kept per accumulator for percentiles |
|
|
63
67
|
| `tracing` | `boolean` | `false` | Create OpenTelemetry spans via the global tracer provider |
|
|
64
68
|
|
|
65
69
|
### `analytics.instrument(transport)`
|
|
@@ -92,6 +96,7 @@ interface AnalyticsSnapshot {
|
|
|
92
96
|
errorRate: number;
|
|
93
97
|
uptimeMs: number;
|
|
94
98
|
tools: Record<string, ToolStats>;
|
|
99
|
+
sessions: Record<string, SessionStats>;
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
interface ToolStats {
|
|
@@ -104,12 +109,29 @@ interface ToolStats {
|
|
|
104
109
|
avgMs: number;
|
|
105
110
|
lastCalledAt: number; // Unix timestamp ms
|
|
106
111
|
}
|
|
112
|
+
|
|
113
|
+
interface SessionStats {
|
|
114
|
+
count: number;
|
|
115
|
+
errorCount: number;
|
|
116
|
+
errorRate: number;
|
|
117
|
+
avgMs: number;
|
|
118
|
+
lastCalledAt: number; // Unix timestamp ms
|
|
119
|
+
tools: Record<string, ToolStats>;
|
|
120
|
+
}
|
|
107
121
|
```
|
|
108
122
|
|
|
109
123
|
### `analytics.getToolStats(toolName)`
|
|
110
124
|
|
|
111
125
|
Get stats for a specific tool. Returns `undefined` if the tool hasn't been called.
|
|
112
126
|
|
|
127
|
+
### `analytics.getSessionStats(sessionId)`
|
|
128
|
+
|
|
129
|
+
Get stats for a specific session. Returns `undefined` if the session hasn't been observed.
|
|
130
|
+
|
|
131
|
+
### `analytics.getTopSessions(limit?)`
|
|
132
|
+
|
|
133
|
+
Returns sessions ordered by call count (descending). Default `limit` is `10`.
|
|
134
|
+
|
|
113
135
|
### `analytics.flush()`
|
|
114
136
|
|
|
115
137
|
Force-flush all pending events to the exporter.
|
|
@@ -122,6 +144,17 @@ Clear all collected data.
|
|
|
122
144
|
|
|
123
145
|
Stop the flush timer and flush remaining events. Call this on process exit.
|
|
124
146
|
|
|
147
|
+
## Reliability Semantics
|
|
148
|
+
|
|
149
|
+
- Flush failures do not drop events. Failed batches are re-queued and retried on the next flush.
|
|
150
|
+
- Periodic flush errors are handled internally (they are reported, but they do not crash the process).
|
|
151
|
+
- Percentile memory is bounded via `toolWindowSize` (recent-window percentile calculation).
|
|
152
|
+
|
|
153
|
+
## Migration Note
|
|
154
|
+
|
|
155
|
+
- `otlp.useGlobalProvider` has been removed. The OTLP exporter now always uses its own OTLP provider.
|
|
156
|
+
If you want spans in your app's global tracer context, use `tracing: true`.
|
|
157
|
+
|
|
125
158
|
## Exporters
|
|
126
159
|
|
|
127
160
|
### Console
|
|
@@ -161,6 +194,8 @@ new McpAnalytics({
|
|
|
161
194
|
});
|
|
162
195
|
```
|
|
163
196
|
|
|
197
|
+
Note: OTLP export emits synthetic spans derived from collected tool-call events.
|
|
198
|
+
|
|
164
199
|
### Custom Function
|
|
165
200
|
|
|
166
201
|
Provide your own export function:
|
|
@@ -199,20 +234,6 @@ This works with any OTel-compatible provider (Datadog, New Relic, Honeycomb, etc
|
|
|
199
234
|
|
|
200
235
|
When using `analytics.track()` (handler wrapping), the handler executes inside the span context, so any downstream OTel-instrumented calls (HTTP, DB, etc.) become children of the MCP tool span.
|
|
201
236
|
|
|
202
|
-
### OTLP exporter with global provider
|
|
203
|
-
|
|
204
|
-
If you're already using the OTLP exporter and want it to send spans through your global provider instead of creating an isolated one:
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
new McpAnalytics({
|
|
208
|
-
exporter: "otlp",
|
|
209
|
-
otlp: {
|
|
210
|
-
endpoint: "unused-when-global", // ignored when useGlobalProvider is true
|
|
211
|
-
useGlobalProvider: true,
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
```
|
|
215
|
-
|
|
216
237
|
### Span attributes
|
|
217
238
|
|
|
218
239
|
Each `mcp.tool_call` span includes these attributes:
|
package/dist/analytics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
2
|
-
import type { AnalyticsConfig, AnalyticsSnapshot, InstrumentedTransport, ToolStats } from "./types.js";
|
|
2
|
+
import type { AnalyticsConfig, AnalyticsSnapshot, InstrumentedTransport, SessionStats, ToolStats } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* MCP Analytics — lightweight observability for MCP servers.
|
|
5
5
|
*
|
|
@@ -26,6 +26,7 @@ export declare class McpAnalytics {
|
|
|
26
26
|
private readonly sampleRate;
|
|
27
27
|
private readonly metadata?;
|
|
28
28
|
private readonly tracing;
|
|
29
|
+
private readonly samplingStrategy;
|
|
29
30
|
constructor(config: AnalyticsConfig);
|
|
30
31
|
/**
|
|
31
32
|
* Instrument an MCP transport to automatically track all tool calls.
|
|
@@ -51,6 +52,17 @@ export declare class McpAnalytics {
|
|
|
51
52
|
* Get stats for a specific tool.
|
|
52
53
|
*/
|
|
53
54
|
getToolStats(toolName: string): ToolStats | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Get stats for a specific session.
|
|
57
|
+
*/
|
|
58
|
+
getSessionStats(sessionId: string): SessionStats | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Get top sessions ranked by total call count.
|
|
61
|
+
*/
|
|
62
|
+
getTopSessions(limit?: number): Array<{
|
|
63
|
+
sessionId: string;
|
|
64
|
+
stats: SessionStats;
|
|
65
|
+
}>;
|
|
54
66
|
/**
|
|
55
67
|
* Flush all pending events to the exporter.
|
|
56
68
|
*/
|
package/dist/analytics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAQ/E,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,qBAAqB,EACrB,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAQ/E,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,qBAAqB,EACrB,YAAY,EAEZ,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;gBAExC,MAAM,EAAE,eAAe;IAiBnC;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,qBAAqB;IAWvD;;;;;;;;;OASG;IACH,KAAK,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EACpC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EACvD,QAAQ,CAAC,EAAE,MAAM,GAChB,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC;IAYvC;;OAEG;IACH,QAAQ,IAAI,iBAAiB;IAI7B;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIrD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI5D;;OAEG;IACH,cAAc,CACZ,KAAK,SAAK,GACT,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IAIpD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,OAAO,CAAC,eAAe;CA0BxB"}
|
package/dist/analytics.js
CHANGED
|
@@ -30,19 +30,23 @@ export class McpAnalytics {
|
|
|
30
30
|
sampleRate;
|
|
31
31
|
metadata;
|
|
32
32
|
tracing;
|
|
33
|
+
samplingStrategy;
|
|
33
34
|
constructor(config) {
|
|
34
35
|
this.sampleRate = config.sampleRate ?? 1;
|
|
35
36
|
this.metadata = config.metadata;
|
|
36
37
|
this.tracing = config.tracing ?? false;
|
|
38
|
+
this.samplingStrategy = config.samplingStrategy ?? "per_call";
|
|
37
39
|
const exporter = this.resolveExporter(config);
|
|
38
|
-
this.collector = new Collector(config.maxBufferSize ?? 10_000, exporter, config.flushIntervalMs ?? 5_000
|
|
40
|
+
this.collector = new Collector(config.maxBufferSize ?? 10_000, exporter, config.flushIntervalMs ?? 5_000, {
|
|
41
|
+
toolWindowSize: config.toolWindowSize,
|
|
42
|
+
});
|
|
39
43
|
}
|
|
40
44
|
/**
|
|
41
45
|
* Instrument an MCP transport to automatically track all tool calls.
|
|
42
46
|
* Returns proxy transport that can be used in place of the original.
|
|
43
47
|
*/
|
|
44
48
|
instrument(transport) {
|
|
45
|
-
return instrumentTransport(transport, this.collector, this.sampleRate, this.metadata, this.tracing);
|
|
49
|
+
return instrumentTransport(transport, this.collector, this.sampleRate, this.metadata, this.tracing, this.samplingStrategy);
|
|
46
50
|
}
|
|
47
51
|
/**
|
|
48
52
|
* Wrap a tool handler function to track its execution.
|
|
@@ -70,6 +74,18 @@ export class McpAnalytics {
|
|
|
70
74
|
getToolStats(toolName) {
|
|
71
75
|
return this.collector.getToolStats(toolName);
|
|
72
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Get stats for a specific session.
|
|
79
|
+
*/
|
|
80
|
+
getSessionStats(sessionId) {
|
|
81
|
+
return this.collector.getSessionStats(sessionId);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get top sessions ranked by total call count.
|
|
85
|
+
*/
|
|
86
|
+
getTopSessions(limit = 10) {
|
|
87
|
+
return this.collector.getTopSessions(limit);
|
|
88
|
+
}
|
|
73
89
|
/**
|
|
74
90
|
* Flush all pending events to the exporter.
|
|
75
91
|
*/
|
package/dist/analytics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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"}
|
package/dist/collector.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type { AnalyticsSnapshot, ExporterFn, ToolCallEvent, ToolStats } from "./types.js";
|
|
1
|
+
import type { AnalyticsSnapshot, ExporterFn, SessionStats, ToolCallEvent, ToolStats } from "./types.js";
|
|
2
|
+
interface CollectorOptions {
|
|
3
|
+
toolWindowSize?: number;
|
|
4
|
+
onFlushError?: (error: unknown) => void;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* In-memory ring buffer that collects ToolCallEvents, computes stats,
|
|
4
8
|
* and periodically flushes to an exporter.
|
|
@@ -8,13 +12,17 @@ export declare class Collector {
|
|
|
8
12
|
private readonly exporter;
|
|
9
13
|
private readonly buffer;
|
|
10
14
|
private readonly accumulators;
|
|
15
|
+
private readonly sessionAccumulators;
|
|
11
16
|
private totalCalls;
|
|
12
17
|
private totalErrors;
|
|
13
18
|
private readonly startTime;
|
|
14
19
|
private flushTimer;
|
|
15
20
|
/** Events accumulated since last flush, to be sent to the exporter */
|
|
16
21
|
private pending;
|
|
17
|
-
|
|
22
|
+
private flushInFlight;
|
|
23
|
+
private readonly toolWindowSize;
|
|
24
|
+
private readonly onFlushError;
|
|
25
|
+
constructor(maxBufferSize: number, exporter: ExporterFn, flushIntervalMs: number, options?: CollectorOptions);
|
|
18
26
|
/**
|
|
19
27
|
* Record a new tool call event.
|
|
20
28
|
*/
|
|
@@ -27,6 +35,17 @@ export declare class Collector {
|
|
|
27
35
|
* Get stats for a single tool.
|
|
28
36
|
*/
|
|
29
37
|
getToolStats(toolName: string): ToolStats | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Get stats for a single session.
|
|
40
|
+
*/
|
|
41
|
+
getSessionStats(sessionId: string): SessionStats | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Get top sessions ordered by total call count.
|
|
44
|
+
*/
|
|
45
|
+
getTopSessions(limit?: number): Array<{
|
|
46
|
+
sessionId: string;
|
|
47
|
+
stats: SessionStats;
|
|
48
|
+
}>;
|
|
30
49
|
/**
|
|
31
50
|
* Flush pending events to the exporter.
|
|
32
51
|
*/
|
|
@@ -39,6 +58,12 @@ export declare class Collector {
|
|
|
39
58
|
* Stop the flush timer and flush remaining events.
|
|
40
59
|
*/
|
|
41
60
|
destroy(): Promise<void>;
|
|
61
|
+
private flushPending;
|
|
62
|
+
private newAccumulator;
|
|
63
|
+
private updateToolAccumulator;
|
|
64
|
+
private updateAccumulator;
|
|
42
65
|
private accToStats;
|
|
66
|
+
private sessionAccToStats;
|
|
43
67
|
}
|
|
68
|
+
export {};
|
|
44
69
|
//# sourceMappingURL=collector.d.ts.map
|
package/dist/collector.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AAsBpB,UAAU,gBAAgB;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAED;;;GAGG;AACH,qBAAa,SAAS;IAgBlB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAhB3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyC;IAC7E,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IAExC,OAAO,CAAC,UAAU,CAA6C;IAC/D,sEAAsE;IACtE,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2B;gBAGrC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,UAAU,EACrC,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,gBAAqB;IA0BhC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IA2BlC;;OAEG;IACH,QAAQ,IAAI,iBAAiB;IAqB7B;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAMrD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAM5D;;OAEG;IACH,cAAc,CACZ,KAAK,SAAK,GACT,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IAepD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAQhB,YAAY;IAc1B,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,iBAAiB;CAe1B"}
|
package/dist/collector.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { percentile
|
|
1
|
+
import { percentile } from "./utils.js";
|
|
2
2
|
/**
|
|
3
3
|
* In-memory ring buffer that collects ToolCallEvents, computes stats,
|
|
4
4
|
* and periodically flushes to an exporter.
|
|
@@ -8,18 +8,30 @@ export class Collector {
|
|
|
8
8
|
exporter;
|
|
9
9
|
buffer = [];
|
|
10
10
|
accumulators = new Map();
|
|
11
|
+
sessionAccumulators = new Map();
|
|
11
12
|
totalCalls = 0;
|
|
12
13
|
totalErrors = 0;
|
|
13
14
|
startTime = Date.now();
|
|
14
15
|
flushTimer;
|
|
15
16
|
/** Events accumulated since last flush, to be sent to the exporter */
|
|
16
17
|
pending = [];
|
|
17
|
-
|
|
18
|
+
flushInFlight;
|
|
19
|
+
toolWindowSize;
|
|
20
|
+
onFlushError;
|
|
21
|
+
constructor(maxBufferSize, exporter, flushIntervalMs, options = {}) {
|
|
18
22
|
this.maxBufferSize = maxBufferSize;
|
|
19
23
|
this.exporter = exporter;
|
|
24
|
+
this.toolWindowSize = Math.max(1, options.toolWindowSize ?? 2_048);
|
|
25
|
+
this.onFlushError =
|
|
26
|
+
options.onFlushError ??
|
|
27
|
+
((error) => {
|
|
28
|
+
console.error("[McpAnalytics] Exporter flush failed:", error);
|
|
29
|
+
});
|
|
20
30
|
if (flushIntervalMs > 0) {
|
|
21
31
|
this.flushTimer = setInterval(() => {
|
|
22
|
-
void this.flush()
|
|
32
|
+
void this.flush().catch((error) => {
|
|
33
|
+
this.onFlushError(error);
|
|
34
|
+
});
|
|
23
35
|
}, flushIntervalMs);
|
|
24
36
|
// Don't hold the process open for analytics flushing
|
|
25
37
|
if (this.flushTimer &&
|
|
@@ -34,32 +46,27 @@ export class Collector {
|
|
|
34
46
|
*/
|
|
35
47
|
record(event) {
|
|
36
48
|
// Ring buffer: drop oldest when full
|
|
37
|
-
if (this.
|
|
38
|
-
this.buffer.
|
|
49
|
+
if (this.maxBufferSize > 0) {
|
|
50
|
+
if (this.buffer.length >= this.maxBufferSize) {
|
|
51
|
+
this.buffer.shift();
|
|
52
|
+
}
|
|
53
|
+
this.buffer.push(event);
|
|
39
54
|
}
|
|
40
|
-
this.buffer.push(event);
|
|
41
55
|
this.pending.push(event);
|
|
42
56
|
this.totalCalls++;
|
|
43
57
|
if (!event.success)
|
|
44
58
|
this.totalErrors++;
|
|
45
59
|
// Update per-tool accumulator
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
lastCalledAt: 0,
|
|
54
|
-
};
|
|
55
|
-
this.accumulators.set(event.toolName, acc);
|
|
60
|
+
this.updateToolAccumulator(this.accumulators, event.toolName, event);
|
|
61
|
+
// Update per-session accumulator
|
|
62
|
+
const sessionKey = event.sessionId ?? "unknown";
|
|
63
|
+
let sessionAcc = this.sessionAccumulators.get(sessionKey);
|
|
64
|
+
if (!sessionAcc) {
|
|
65
|
+
sessionAcc = { ...this.newAccumulator(), tools: new Map() };
|
|
66
|
+
this.sessionAccumulators.set(sessionKey, sessionAcc);
|
|
56
67
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
acc.errorCount++;
|
|
60
|
-
acc.totalMs += event.durationMs;
|
|
61
|
-
sortedInsert(acc.durations, event.durationMs);
|
|
62
|
-
acc.lastCalledAt = event.timestamp;
|
|
68
|
+
this.updateAccumulator(sessionAcc, event);
|
|
69
|
+
this.updateToolAccumulator(sessionAcc.tools, event.toolName, event);
|
|
63
70
|
}
|
|
64
71
|
/**
|
|
65
72
|
* Get aggregated stats for all tools.
|
|
@@ -69,12 +76,17 @@ export class Collector {
|
|
|
69
76
|
for (const [name, acc] of this.accumulators) {
|
|
70
77
|
tools[name] = this.accToStats(acc);
|
|
71
78
|
}
|
|
79
|
+
const sessions = {};
|
|
80
|
+
for (const [sessionId, acc] of this.sessionAccumulators) {
|
|
81
|
+
sessions[sessionId] = this.sessionAccToStats(acc);
|
|
82
|
+
}
|
|
72
83
|
return {
|
|
73
84
|
totalCalls: this.totalCalls,
|
|
74
85
|
totalErrors: this.totalErrors,
|
|
75
86
|
errorRate: this.totalCalls > 0 ? this.totalErrors / this.totalCalls : 0,
|
|
76
87
|
uptimeMs: Date.now() - this.startTime,
|
|
77
88
|
tools,
|
|
89
|
+
sessions,
|
|
78
90
|
};
|
|
79
91
|
}
|
|
80
92
|
/**
|
|
@@ -86,15 +98,52 @@ export class Collector {
|
|
|
86
98
|
return undefined;
|
|
87
99
|
return this.accToStats(acc);
|
|
88
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Get stats for a single session.
|
|
103
|
+
*/
|
|
104
|
+
getSessionStats(sessionId) {
|
|
105
|
+
const acc = this.sessionAccumulators.get(sessionId);
|
|
106
|
+
if (!acc)
|
|
107
|
+
return undefined;
|
|
108
|
+
return this.sessionAccToStats(acc);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get top sessions ordered by total call count.
|
|
112
|
+
*/
|
|
113
|
+
getTopSessions(limit = 10) {
|
|
114
|
+
if (limit <= 0)
|
|
115
|
+
return [];
|
|
116
|
+
return [...this.sessionAccumulators.entries()]
|
|
117
|
+
.sort((a, b) => {
|
|
118
|
+
const byCount = b[1].count - a[1].count;
|
|
119
|
+
if (byCount !== 0)
|
|
120
|
+
return byCount;
|
|
121
|
+
return b[1].lastCalledAt - a[1].lastCalledAt;
|
|
122
|
+
})
|
|
123
|
+
.slice(0, limit)
|
|
124
|
+
.map(([sessionId, acc]) => ({
|
|
125
|
+
sessionId,
|
|
126
|
+
stats: this.sessionAccToStats(acc),
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
89
129
|
/**
|
|
90
130
|
* Flush pending events to the exporter.
|
|
91
131
|
*/
|
|
92
132
|
async flush() {
|
|
93
|
-
if (this.
|
|
133
|
+
if (this.flushInFlight) {
|
|
134
|
+
await this.flushInFlight;
|
|
94
135
|
return;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
136
|
+
}
|
|
137
|
+
const run = this.flushPending();
|
|
138
|
+
this.flushInFlight = run;
|
|
139
|
+
try {
|
|
140
|
+
await run;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
if (this.flushInFlight === run) {
|
|
144
|
+
this.flushInFlight = undefined;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
98
147
|
}
|
|
99
148
|
/**
|
|
100
149
|
* Reset all collected data.
|
|
@@ -103,6 +152,7 @@ export class Collector {
|
|
|
103
152
|
this.buffer.length = 0;
|
|
104
153
|
this.pending.length = 0;
|
|
105
154
|
this.accumulators.clear();
|
|
155
|
+
this.sessionAccumulators.clear();
|
|
106
156
|
this.totalCalls = 0;
|
|
107
157
|
this.totalErrors = 0;
|
|
108
158
|
}
|
|
@@ -116,16 +166,73 @@ export class Collector {
|
|
|
116
166
|
}
|
|
117
167
|
await this.flush();
|
|
118
168
|
}
|
|
169
|
+
async flushPending() {
|
|
170
|
+
while (this.pending.length > 0) {
|
|
171
|
+
const batch = this.pending;
|
|
172
|
+
this.pending = [];
|
|
173
|
+
try {
|
|
174
|
+
await this.exporter(batch);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
// Re-queue batch to avoid data loss on transient exporter failures.
|
|
178
|
+
this.pending = batch.concat(this.pending);
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
newAccumulator() {
|
|
184
|
+
return {
|
|
185
|
+
count: 0,
|
|
186
|
+
errorCount: 0,
|
|
187
|
+
totalMs: 0,
|
|
188
|
+
durations: [],
|
|
189
|
+
lastCalledAt: 0,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
updateToolAccumulator(map, toolName, event) {
|
|
193
|
+
let acc = map.get(toolName);
|
|
194
|
+
if (!acc) {
|
|
195
|
+
acc = this.newAccumulator();
|
|
196
|
+
map.set(toolName, acc);
|
|
197
|
+
}
|
|
198
|
+
this.updateAccumulator(acc, event);
|
|
199
|
+
}
|
|
200
|
+
updateAccumulator(acc, event) {
|
|
201
|
+
acc.count++;
|
|
202
|
+
if (!event.success)
|
|
203
|
+
acc.errorCount++;
|
|
204
|
+
acc.totalMs += event.durationMs;
|
|
205
|
+
acc.durations.push(event.durationMs);
|
|
206
|
+
if (acc.durations.length > this.toolWindowSize) {
|
|
207
|
+
acc.durations.shift();
|
|
208
|
+
}
|
|
209
|
+
acc.lastCalledAt = event.timestamp;
|
|
210
|
+
}
|
|
119
211
|
accToStats(acc) {
|
|
212
|
+
const sortedDurations = [...acc.durations].sort((a, b) => a - b);
|
|
213
|
+
return {
|
|
214
|
+
count: acc.count,
|
|
215
|
+
errorCount: acc.errorCount,
|
|
216
|
+
errorRate: acc.count > 0 ? acc.errorCount / acc.count : 0,
|
|
217
|
+
p50Ms: percentile(sortedDurations, 50),
|
|
218
|
+
p95Ms: percentile(sortedDurations, 95),
|
|
219
|
+
p99Ms: percentile(sortedDurations, 99),
|
|
220
|
+
avgMs: acc.count > 0 ? acc.totalMs / acc.count : 0,
|
|
221
|
+
lastCalledAt: acc.lastCalledAt,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
sessionAccToStats(acc) {
|
|
225
|
+
const tools = {};
|
|
226
|
+
for (const [toolName, toolAcc] of acc.tools) {
|
|
227
|
+
tools[toolName] = this.accToStats(toolAcc);
|
|
228
|
+
}
|
|
120
229
|
return {
|
|
121
230
|
count: acc.count,
|
|
122
231
|
errorCount: acc.errorCount,
|
|
123
232
|
errorRate: acc.count > 0 ? acc.errorCount / acc.count : 0,
|
|
124
|
-
p50Ms: percentile(acc.durations, 50),
|
|
125
|
-
p95Ms: percentile(acc.durations, 95),
|
|
126
|
-
p99Ms: percentile(acc.durations, 99),
|
|
127
233
|
avgMs: acc.count > 0 ? acc.totalMs / acc.count : 0,
|
|
128
234
|
lastCalledAt: acc.lastCalledAt,
|
|
235
|
+
tools,
|
|
129
236
|
};
|
|
130
237
|
}
|
|
131
238
|
}
|
package/dist/collector.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"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"}
|
package/dist/exporters/otlp.js
CHANGED
|
@@ -22,28 +22,20 @@ export function createOtlpExporter(config) {
|
|
|
22
22
|
}
|
|
23
23
|
async function initTracer(config) {
|
|
24
24
|
// Dynamic imports — these only resolve if the user has @opentelemetry installed
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
});
|
|
40
|
-
const provider = new BasicTracerProvider({
|
|
41
|
-
spanProcessors: [
|
|
42
|
-
new SimpleSpanProcessor(otlpExporter),
|
|
43
|
-
],
|
|
44
|
-
});
|
|
45
|
-
tracer = provider.getTracer("@gomcp/analytics");
|
|
46
|
-
}
|
|
25
|
+
const { SpanStatusCode } = await import("@opentelemetry/api");
|
|
26
|
+
// Create an isolated provider with OTLP HTTP exporter.
|
|
27
|
+
const { BasicTracerProvider, SimpleSpanProcessor } = await import("@opentelemetry/sdk-trace-base");
|
|
28
|
+
const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
|
|
29
|
+
const otlpExporter = new OTLPTraceExporter({
|
|
30
|
+
url: config.endpoint,
|
|
31
|
+
headers: config.headers,
|
|
32
|
+
});
|
|
33
|
+
const provider = new BasicTracerProvider({
|
|
34
|
+
spanProcessors: [
|
|
35
|
+
new SimpleSpanProcessor(otlpExporter),
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
const tracer = provider.getTracer("@gomcp/analytics");
|
|
47
39
|
return {
|
|
48
40
|
exportEvent(event) {
|
|
49
41
|
const span = tracer.startSpan("mcp.tool_call", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/exporters/otlp.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAkB;IAElB,0BAA0B;IAC1B,IAAI,aAA8C,CAAC;IAEnD,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEhC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAOD,KAAK,UAAU,UAAU,CAAC,MAAkB;IAC1C,gFAAgF;IAChF,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/exporters/otlp.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { McpAnalytics } from "./analytics.js";
|
|
2
|
-
export type { AnalyticsConfig, AnalyticsSnapshot, ExporterFn, InstrumentedTransport, JsonConfig, OtlpConfig, ToolCallEvent, ToolStats, } from "./types.js";
|
|
2
|
+
export type { AnalyticsConfig, AnalyticsSnapshot, ExporterFn, InstrumentedTransport, JsonConfig, OtlpConfig, SamplingStrategy, SessionStats, ToolCallEvent, ToolStats, } from "./types.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,aAAa,EACb,SAAS,GACV,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
2
2
|
import type { Collector } from "./collector.js";
|
|
3
|
-
import type { InstrumentedTransport } from "./types.js";
|
|
3
|
+
import type { InstrumentedTransport, SamplingStrategy } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Wraps a Transport to intercept tools/call requests and their responses,
|
|
6
6
|
* recording metrics to the Collector.
|
|
7
7
|
*/
|
|
8
|
-
export declare function instrumentTransport(transport: Transport, collector: Collector, sampleRate: number, globalMetadata?: Record<string, string>, tracing?: boolean): InstrumentedTransport;
|
|
8
|
+
export declare function instrumentTransport(transport: Transport, collector: Collector, sampleRate: number, globalMetadata?: Record<string, string>, tracing?: boolean, samplingStrategy?: SamplingStrategy): InstrumentedTransport;
|
|
9
9
|
/**
|
|
10
10
|
* Wraps a tool handler function to record metrics.
|
|
11
11
|
* Works with McpServer.tool() callback pattern.
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAOhD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAOhD,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAyCpB;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,OAAO,CAAC,EAAE,OAAO,EACjB,gBAAgB,GAAE,gBAA6B,GAC9C,qBAAqB,CA2LvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EAC9D,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EACvD,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,OAAO,CAAC,EAAE,OAAO,GAChB,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAiDtC"}
|
package/dist/middleware.js
CHANGED
|
@@ -22,10 +22,49 @@ function isErrorResponse(msg) {
|
|
|
22
22
|
* Wraps a Transport to intercept tools/call requests and their responses,
|
|
23
23
|
* recording metrics to the Collector.
|
|
24
24
|
*/
|
|
25
|
-
export function instrumentTransport(transport, collector, sampleRate, globalMetadata, tracing) {
|
|
25
|
+
export function instrumentTransport(transport, collector, sampleRate, globalMetadata, tracing, samplingStrategy = "per_call") {
|
|
26
26
|
const pending = new Map();
|
|
27
|
+
const sessionSamplingDecisions = new Map();
|
|
27
28
|
// Intercept incoming messages (requests from client)
|
|
28
29
|
const origOnMessage = transport.onmessage;
|
|
30
|
+
const origOnClose = transport.onclose;
|
|
31
|
+
const sampleForSession = (sessionKey) => {
|
|
32
|
+
if (samplingStrategy !== "per_session") {
|
|
33
|
+
// eslint-disable-next-line sonarjs/pseudo-random -- intentional for perf sampling, not security
|
|
34
|
+
return Math.random() < sampleRate;
|
|
35
|
+
}
|
|
36
|
+
const cached = sessionSamplingDecisions.get(sessionKey);
|
|
37
|
+
if (cached !== undefined)
|
|
38
|
+
return cached;
|
|
39
|
+
// eslint-disable-next-line sonarjs/pseudo-random -- intentional for perf sampling, not security
|
|
40
|
+
const decision = Math.random() < sampleRate;
|
|
41
|
+
sessionSamplingDecisions.set(sessionKey, decision);
|
|
42
|
+
return decision;
|
|
43
|
+
};
|
|
44
|
+
const closePendingCall = (call, success, errorMessage) => {
|
|
45
|
+
if (call.tracing) {
|
|
46
|
+
endToolSpan(call.tracing, success, errorMessage);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (call.tracingInit) {
|
|
50
|
+
void call.tracingInit
|
|
51
|
+
.then((span) => {
|
|
52
|
+
if (span) {
|
|
53
|
+
endToolSpan(span, success, errorMessage);
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
.catch(() => {
|
|
57
|
+
// ignore tracing init failures
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const cleanupPendingCalls = (reason) => {
|
|
62
|
+
for (const call of pending.values()) {
|
|
63
|
+
closePendingCall(call, false, reason);
|
|
64
|
+
}
|
|
65
|
+
pending.clear();
|
|
66
|
+
sessionSamplingDecisions.clear();
|
|
67
|
+
};
|
|
29
68
|
// We need to intercept onmessage being set (since the server sets it after we wrap)
|
|
30
69
|
// The pattern: wrap the transport so that when server sets onmessage, we inject our interceptor
|
|
31
70
|
const proxy = new Proxy(transport, {
|
|
@@ -37,8 +76,8 @@ export function instrumentTransport(transport, collector, sampleRate, globalMeta
|
|
|
37
76
|
target.onmessage = (message, extra) => {
|
|
38
77
|
// Intercept incoming tools/call requests
|
|
39
78
|
if (isRequest(message) && message.method === "tools/call") {
|
|
40
|
-
|
|
41
|
-
if (
|
|
79
|
+
const sessionKey = target.sessionId ?? "unknown";
|
|
80
|
+
if (sampleForSession(sessionKey)) {
|
|
42
81
|
const params = message.params;
|
|
43
82
|
const toolName = params?.name ?? "unknown";
|
|
44
83
|
const inputSize = byteSize(params?.arguments);
|
|
@@ -47,24 +86,33 @@ export function instrumentTransport(transport, collector, sampleRate, globalMeta
|
|
|
47
86
|
startTime: Date.now(),
|
|
48
87
|
inputSize,
|
|
49
88
|
};
|
|
50
|
-
|
|
51
|
-
// Start a tracing span (async, fire-and-forget into the pending map)
|
|
89
|
+
// Start span initialization and keep a promise to avoid race with fast responses.
|
|
52
90
|
if (tracing) {
|
|
53
|
-
startToolSpan(toolName, {
|
|
91
|
+
pendingCall.tracingInit = startToolSpan(toolName, {
|
|
54
92
|
"mcp.tool.input_size": inputSize,
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
93
|
+
})
|
|
94
|
+
.then((span) => {
|
|
95
|
+
pendingCall.tracing = span;
|
|
96
|
+
return span;
|
|
97
|
+
})
|
|
98
|
+
.catch(() => undefined);
|
|
61
99
|
}
|
|
100
|
+
pending.set(message.id, pendingCall);
|
|
62
101
|
}
|
|
63
102
|
}
|
|
64
103
|
userHandler(message, extra);
|
|
65
104
|
};
|
|
66
105
|
return true;
|
|
67
106
|
}
|
|
107
|
+
if (prop === "onclose" && typeof value === "function") {
|
|
108
|
+
const userOnClose = value;
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
target.onclose = (...args) => {
|
|
111
|
+
cleanupPendingCalls("Transport closed before tool response");
|
|
112
|
+
userOnClose(...args);
|
|
113
|
+
};
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
68
116
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
117
|
target[prop] = value;
|
|
70
118
|
return true;
|
|
@@ -106,14 +154,22 @@ export function instrumentTransport(transport, collector, sampleRate, globalMeta
|
|
|
106
154
|
};
|
|
107
155
|
collector.record(event);
|
|
108
156
|
// End the tracing span
|
|
109
|
-
|
|
110
|
-
endToolSpan(call.tracing, success, errorMessage);
|
|
111
|
-
}
|
|
157
|
+
closePendingCall(call, success, errorMessage);
|
|
112
158
|
}
|
|
113
159
|
}
|
|
114
160
|
return target.send.call(target, message, options);
|
|
115
161
|
};
|
|
116
162
|
}
|
|
163
|
+
if (prop === "close") {
|
|
164
|
+
return async (...args) => {
|
|
165
|
+
try {
|
|
166
|
+
return await target.close(...args);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
cleanupPendingCalls("Transport closed before tool response");
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
117
173
|
const value = Reflect.get(target, prop, receiver);
|
|
118
174
|
if (typeof value === "function") {
|
|
119
175
|
return value.bind(target);
|
|
@@ -125,6 +181,9 @@ export function instrumentTransport(transport, collector, sampleRate, globalMeta
|
|
|
125
181
|
if (origOnMessage) {
|
|
126
182
|
proxy.onmessage = origOnMessage;
|
|
127
183
|
}
|
|
184
|
+
if (origOnClose) {
|
|
185
|
+
proxy.onclose = origOnClose;
|
|
186
|
+
}
|
|
128
187
|
return proxy;
|
|
129
188
|
}
|
|
130
189
|
/**
|
package/dist/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAEhB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EACb,WAAW,EACX,eAAe,GAEhB,MAAM,cAAc,CAAC;AAMtB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC;;GAEG;AACH,SAAS,SAAS,CAAC,GAAmB;IAKpC,OAAO,IAAI,IAAI,GAAG,IAAI,QAAQ,IAAI,GAAG,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,GAAmB;IAEnB,OAAO,IAAI,IAAI,GAAG,IAAI,QAAQ,IAAI,GAAG,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAmB;IAI1C,OAAO,IAAI,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC;AACvC,CAAC;AAUD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAoB,EACpB,SAAoB,EACpB,UAAkB,EAClB,cAAuC,EACvC,OAAiB,EACjB,mBAAqC,UAAU;IAE/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgC,CAAC;IACxD,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE5D,qDAAqD;IACrD,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC;IAC1C,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;IAEtC,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAW,EAAE;QACvD,IAAI,gBAAgB,KAAK,aAAa,EAAE,CAAC;YACvC,gGAAgG;YAChG,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,gGAAgG;QAChG,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC;QAC5C,wBAAwB,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACnD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CACvB,IAAiB,EACjB,OAAgB,EAChB,YAAqB,EACrB,EAAE;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,WAAW;iBAClB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBACb,IAAI,IAAI,EAAE,CAAC;oBACT,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE;gBACV,+BAA+B;YACjC,CAAC,CAAC,CAAC;QACP,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,EAAE;QAC7C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC,CAAC;IAEF,oFAAoF;IACpF,gGAAgG;IAChG,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE;QACjC,mGAAmG;QACnG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK;YACrB,IAAI,IAAI,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBACxD,MAAM,WAAW,GAAG,KAAK,CAAC;gBAC1B,8DAA8D;gBAC7D,MAAc,CAAC,SAAS,GAAG,CAC1B,OAAuB,EACvB,KAAe,EACf,EAAE;oBACF,yCAAyC;oBACzC,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;wBAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;wBACjD,IAAI,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;4BACjC,MAAM,MAAM,GAAG,OAAO,CAAC,MAEV,CAAC;4BACd,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,IAAI,SAAS,CAAC;4BAC3C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;4BAC9C,MAAM,WAAW,GAAgB;gCAC/B,QAAQ;gCACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gCACrB,SAAS;6BACV,CAAC;4BAEF,kFAAkF;4BAClF,IAAI,OAAO,EAAE,CAAC;gCACZ,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC,QAAQ,EAAE;oCAChD,qBAAqB,EAAE,SAAS;iCACjC,CAAC;qCACC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oCACb,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;oCAC3B,OAAO,IAAI,CAAC;gCACd,CAAC,CAAC;qCACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;4BAC5B,CAAC;4BAED,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;wBACvC,CAAC;oBACH,CAAC;oBACD,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAC9B,CAAC,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBACtD,MAAM,WAAW,GAAG,KAAK,CAAC;gBAC1B,8DAA8D;gBAC7D,MAAc,CAAC,OAAO,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;oBAC/C,mBAAmB,CAAC,uCAAuC,CAAC,CAAC;oBAC7D,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;gBACvB,CAAC,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,8DAA8D;YAC7D,MAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACxB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,sDAAsD;gBACtD,OAAO,KAAK,EAAE,OAAuB,EAAE,OAAiB,EAAE,EAAE;oBAC1D,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC;wBACpB,MAAM,EAAE,GAAI,OAAmC,CAAC,EAAE,CAAC;wBACnD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBAC7B,IAAI,IAAI,EAAE,CAAC;4BACT,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;4BACnB,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;4BAC1C,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC;gCAC3C,CAAC,CAAE,OAA0C,CAAC,KAAK,CAAC,OAAO;gCAC3D,CAAC,CAAC,SAAS,CAAC;4BAEd,IAAI,aAAsB,CAAC;4BAC3B,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;gCAC9B,aAAa,GAAI,OAA+B,CAAC,MAAM,CAAC;4BAC1D,CAAC;iCAAM,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gCACpC,aAAa,GAAI,OAA8B,CAAC,KAAK,CAAC;4BACxD,CAAC;4BAED,MAAM,KAAK,GAAkB;gCAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gCACvB,SAAS,EAAE,MAAM,CAAC,SAAS;gCAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;gCACzB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS;gCACvC,OAAO;gCACP,SAAS,EAAE,IAAI,CAAC,SAAS;gCACzB,UAAU,EAAE,QAAQ,CAAC,aAAa,CAAC;gCACnC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI;oCAC9B,YAAY;oCACZ,SAAS,EAAG,OAAuC,CAAC,KAAK;yCACtD,IAAI;iCACR,CAAC;gCACF,GAAG,CAAC,cAAc,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;6BACpD,CAAC;4BACF,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BAExB,uBAAuB;4BACvB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;wBAChD,CAAC;oBACH,CAAC;oBACD,OAAQ,MAAM,CAAC,IAAwC,CAAC,IAAI,CAC1D,MAAM,EACN,OAAO,EACP,OAAO,CACR,CAAC;gBACJ,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,OAAO,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;oBAClC,IAAI,CAAC;wBACH,OAAO,MAAO,MAAM,CAAC,KAA+C,CAClE,GAAG,IAAI,CACR,CAAC;oBACJ,CAAC;4BAAS,CAAC;wBACT,mBAAmB,CAAC,uCAAuC,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAClD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC,CAAC;IAEH,6EAA6E;IAC7E,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC;IAClC,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,OAAO,GAAG,WAAW,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,OAAuD,EACvD,SAAoB,EACpB,UAAkB,EAClB,cAAuC,EACvC,OAAiB;IAEjB,OAAO,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,2FAA2F;QAC5I,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpC,kCAAkC;QAClC,MAAM,WAAW,GAAG,OAAO;YACzB,CAAC,CAAC,MAAM,aAAa,CAAC,QAAQ,EAAE,EAAE,qBAAqB,EAAE,SAAS,EAAE,CAAC;YACrE,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,CAAC;YACH,sEAAsE;YACtE,MAAM,MAAM,GAAG,WAAW;gBACxB,CAAC,CAAC,MAAM,eAAe,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;gBAC5D,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3B,MAAM,KAAK,GAAkB;gBAC3B,QAAQ;gBACR,SAAS,EAAE,SAAS;gBACpB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,OAAO,EAAE,IAAI;gBACb,SAAS;gBACT,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC;gBAC5B,GAAG,CAAC,cAAc,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;aACpD,CAAC;YACF,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,WAAW;gBAAE,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAChD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,YAAY,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtE,MAAM,KAAK,GAAkB;gBAC3B,QAAQ;gBACR,SAAS,EAAE,SAAS;gBACpB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,OAAO,EAAE,KAAK;gBACd,YAAY;gBACZ,SAAS;gBACT,UAAU,EAAE,CAAC;gBACb,GAAG,CAAC,cAAc,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;aACpD,CAAC;YACF,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,WAAW;gBAAE,WAAW,CAAC,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAC/D,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/tracing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAI3C,UAAU,QAAQ;IAChB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAClD,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,GAAG,IAAI,IAAI,CAAC;CACb;AAED,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAI3C,UAAU,QAAQ;IAChB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAClD,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,GAAG,IAAI,IAAI,CAAC;CACb;AAED,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAuC3C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACrC,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAclC;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI,CAQN;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAIZ"}
|
package/dist/tracing.js
CHANGED
|
@@ -40,7 +40,8 @@ export async function startToolSpan(toolName, attributes) {
|
|
|
40
40
|
...attributes,
|
|
41
41
|
},
|
|
42
42
|
});
|
|
43
|
-
|
|
43
|
+
const spanContext = api.trace.setSpan(api.context.active(), span);
|
|
44
|
+
return { span, context: spanContext };
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* End a tool span, setting error status if the call failed.
|
package/dist/tracing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH,IAAI,OAA4B,CAAC;AACjC,IAAI,cAAc,GAAG,KAAK,CAAC;AAE3B;;GAEG;AACH,KAAK,UAAU,UAAU;IACvB,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,cAAc;QAAE,OAAO,SAAS,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC/C,OAAO,GAAG,GAAyB,CAAC;QACpC,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,cAAc,GAAG,IAAI,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAOD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,UAAsC;IAEtC,MAAM,GAAG,GAAG,MAAM,UAAU,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAE3B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE;QAC7C,UAAU,EAAE;YACV,eAAe,EAAE,QAAQ;YACzB,GAAG,UAAU;SACd;KACF,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;IAClE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,OAAoB,EACpB,OAAgB,EAChB,YAAqB;IAErB,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YACrB,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK;YAClC,OAAO,EAAE,YAAY;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAoB,EACpB,EAAwB;IAExB,MAAM,GAAG,GAAG,OAAO,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,CAAC;IACtB,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -46,6 +46,18 @@ export interface AnalyticsSnapshot {
|
|
|
46
46
|
errorRate: number;
|
|
47
47
|
uptimeMs: number;
|
|
48
48
|
tools: Record<string, ToolStats>;
|
|
49
|
+
sessions: Record<string, SessionStats>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Aggregated stats for a single session.
|
|
53
|
+
*/
|
|
54
|
+
export interface SessionStats {
|
|
55
|
+
count: number;
|
|
56
|
+
errorCount: number;
|
|
57
|
+
errorRate: number;
|
|
58
|
+
avgMs: number;
|
|
59
|
+
lastCalledAt: number;
|
|
60
|
+
tools: Record<string, ToolStats>;
|
|
49
61
|
}
|
|
50
62
|
/**
|
|
51
63
|
* Custom exporter function signature.
|
|
@@ -57,9 +69,6 @@ export type ExporterFn = (events: ToolCallEvent[]) => Promise<void>;
|
|
|
57
69
|
export interface OtlpConfig {
|
|
58
70
|
endpoint: string;
|
|
59
71
|
headers?: Record<string, string>;
|
|
60
|
-
/** When true, use the global TracerProvider instead of creating an isolated one.
|
|
61
|
-
* This is useful when dd-trace or another APM registers as the global OTel provider. */
|
|
62
|
-
useGlobalProvider?: boolean;
|
|
63
72
|
}
|
|
64
73
|
/**
|
|
65
74
|
* JSON file exporter configuration.
|
|
@@ -85,11 +94,19 @@ export interface AnalyticsConfig {
|
|
|
85
94
|
maxBufferSize?: number;
|
|
86
95
|
/** User-provided metadata added to every event */
|
|
87
96
|
metadata?: Record<string, string>;
|
|
97
|
+
/** Sampling strategy used by transport-level interception. Default: "per_call" */
|
|
98
|
+
samplingStrategy?: SamplingStrategy;
|
|
99
|
+
/** Number of recent tool durations retained per accumulator for percentile calculation. Default: 2048 */
|
|
100
|
+
toolWindowSize?: number;
|
|
88
101
|
/** Enable OpenTelemetry span creation during tool execution.
|
|
89
102
|
* When true, uses the global tracer provider (compatible with dd-trace, etc.)
|
|
90
103
|
* Default: false */
|
|
91
104
|
tracing?: boolean;
|
|
92
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Controls how calls are sampled.
|
|
108
|
+
*/
|
|
109
|
+
export type SamplingStrategy = "per_call" | "per_session";
|
|
93
110
|
/**
|
|
94
111
|
* A transport that has been instrumented with analytics.
|
|
95
112
|
* Same interface as Transport — can be used anywhere a Transport is expected.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|