@frontmcp/observability 1.9.1 → 1.9.3
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/esm/index.mjs +396 -219
- package/esm/package.json +3 -3
- package/index.js +466 -290
- package/otel/otel.types.d.ts +1 -1
- package/package.json +3 -3
- package/plugin/observability.hooks.d.ts +28 -0
- package/plugin/observability.plugin.d.ts +10 -2
- package/process-stats/process-stats.collector.d.ts +1 -1
- package/request-log/request-log.collector.d.ts +4 -0
- package/request-log/request-log.hooks.d.ts +35 -0
- package/request-log/request-log.types.d.ts +1 -1
- package/telemetry/telemetry.context-extension.d.ts +3 -3
package/otel/otel.types.d.ts
CHANGED
|
@@ -133,7 +133,7 @@ export interface TracingOptions {
|
|
|
133
133
|
oauthSpans?: boolean;
|
|
134
134
|
/** Instrument elicitation request/result flows (default: true) */
|
|
135
135
|
elicitationSpans?: boolean;
|
|
136
|
-
/** Emit startup
|
|
136
|
+
/** Emit a `frontmcp.startup` span once the server is ready (default: true) */
|
|
137
137
|
startupReport?: boolean;
|
|
138
138
|
}
|
|
139
139
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/observability",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.3",
|
|
4
4
|
"description": "OpenTelemetry instrumentation, structured JSON logging, and request log objects for FrontMCP",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@opentelemetry/api": "^1.9.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@frontmcp/sdk": "1.9.
|
|
55
|
-
"@frontmcp/utils": "1.9.
|
|
54
|
+
"@frontmcp/sdk": "1.9.3",
|
|
55
|
+
"@frontmcp/utils": "1.9.3",
|
|
56
56
|
"@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
|
|
57
57
|
"@opentelemetry/sdk-node": "^0.219.0",
|
|
58
58
|
"@opentelemetry/sdk-trace-base": "^2.8.0",
|
|
@@ -32,6 +32,8 @@ export declare const ACTIVE_SPAN_KEY: unique symbol;
|
|
|
32
32
|
export declare const ACTIVE_OTEL_CTX_KEY: unique symbol;
|
|
33
33
|
/** Timestamp of the last recorded stage event */
|
|
34
34
|
export declare const STAGE_TS_KEY: unique symbol;
|
|
35
|
+
/** OTel context of the request's HTTP span, on the FrontMcpContext: the parent of the spans of the flows it runs */
|
|
36
|
+
export declare const HTTP_SPAN_CTX_KEY: unique symbol;
|
|
35
37
|
/**
|
|
36
38
|
* Generate a privacy-safe session tracing ID.
|
|
37
39
|
* 16-char truncated SHA-256 — sufficient for trace correlation,
|
|
@@ -43,6 +45,17 @@ export interface FlowContextLike {
|
|
|
43
45
|
get?(key: symbol): unknown;
|
|
44
46
|
state?: Record<symbol | string, any>;
|
|
45
47
|
}
|
|
48
|
+
/** Why a flow failed, as the client sees it in production. */
|
|
49
|
+
export interface FlowFailure {
|
|
50
|
+
/** The error itself: what `this.fail()` was given, not the control-flow signal that carried it */
|
|
51
|
+
error: Error;
|
|
52
|
+
type: string;
|
|
53
|
+
message: string;
|
|
54
|
+
code: string;
|
|
55
|
+
errorId: string;
|
|
56
|
+
}
|
|
57
|
+
/** The failure behind a flow's `state.flowError`, mapped as the SDK maps it for the client (same error ID). */
|
|
58
|
+
export declare function flowFailureOf(flowError: unknown): FlowFailure;
|
|
46
59
|
export declare function onHttpWillTrace(options: TracingOptions, flowCtx: any): void;
|
|
47
60
|
export declare function onHttpWillAcquireQuota(flowCtx: any): void;
|
|
48
61
|
export declare function onHttpDidAcquireQuota(flowCtx: any): void;
|
|
@@ -91,4 +104,19 @@ export declare function onAuthStage(stageName: string, flowCtx: any): void;
|
|
|
91
104
|
export declare function onAuthDidFinalize(flowCtx: any): void;
|
|
92
105
|
export declare function wrapContextFetch(options: TracingOptions, flowCtx: any): void;
|
|
93
106
|
export declare function onAgentDidExecuteEnrich(flowCtx: any): void;
|
|
107
|
+
/** Wraps each hook a plugin, app or entry injected into a flow of the request: `run` runs the hook. */
|
|
108
|
+
export type HookObserver = (hook: {
|
|
109
|
+
flowName: string;
|
|
110
|
+
stage: string;
|
|
111
|
+
target: unknown;
|
|
112
|
+
flowContext: unknown;
|
|
113
|
+
}, run: () => Promise<void>) => Promise<void>;
|
|
114
|
+
/** Installs `observer` for the request the flow `flowCtx` serves, unless one watches it already. */
|
|
115
|
+
export declare function installHookObserver(flowCtx: FlowContextLike, observer: HookObserver): void;
|
|
116
|
+
/** Runs one hook inside a `hook <stage>` span, a child of its flow's span. `fail` and `abort` end it as an error; other control-flow signals end it OK. */
|
|
117
|
+
export declare function runInHookSpan(flowCtx: any, hook: {
|
|
118
|
+
flowName: string;
|
|
119
|
+
stage: string;
|
|
120
|
+
owner?: string;
|
|
121
|
+
}, run: () => Promise<void>): Promise<void>;
|
|
94
122
|
export declare function reportStartup(data: StartupTelemetryData): void;
|
|
@@ -25,6 +25,15 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
|
|
|
25
25
|
private tracingOpts;
|
|
26
26
|
constructor(options?: ObservabilityPluginOptionsInput);
|
|
27
27
|
private get tracingEnabled();
|
|
28
|
+
private get requestLogsEnabled();
|
|
29
|
+
/** Whether tracing is on and its `kind` option isn't off. */
|
|
30
|
+
private traces;
|
|
31
|
+
/** Wraps each other hook the request runs: names it on the request's log, and gives it a span with `hookSpans`. */
|
|
32
|
+
private readonly observeHook;
|
|
33
|
+
/** Watches the hooks of the request `ctx` serves, from the first flow of it that this plugin sees. */
|
|
34
|
+
private watchHooks;
|
|
35
|
+
/** Names the entry a request serves on its request log, and records the entry flow's failure. */
|
|
36
|
+
private annotateRequestLog;
|
|
28
37
|
_httpWillTrace(ctx: unknown): void;
|
|
29
38
|
_httpWillQuota(ctx: unknown): void;
|
|
30
39
|
_httpDidSemaphore(ctx: unknown): void;
|
|
@@ -145,8 +154,7 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
|
|
|
145
154
|
_toolDidCreateCtxFetch(ctx: unknown): void;
|
|
146
155
|
_agentDidExecuteMeta(ctx: unknown): void;
|
|
147
156
|
/**
|
|
148
|
-
* Emit startup
|
|
149
|
-
* Call after scope.initialize() completes with component counts.
|
|
157
|
+
* Emit the `frontmcp.startup` span (`tracing.startupReport`). The scope calls it once it is ready.
|
|
150
158
|
*/
|
|
151
159
|
reportStartupTelemetry(data: StartupTelemetryData): void;
|
|
152
160
|
static dynamicProviders: (input: ObservabilityPluginOptionsInput) => ProviderType[];
|
|
@@ -53,7 +53,7 @@ export declare class ProcessStatsCollector {
|
|
|
53
53
|
private readonly getActiveHandles?;
|
|
54
54
|
private readonly getActiveRequests?;
|
|
55
55
|
private readonly readFdCount;
|
|
56
|
-
private cpuStart
|
|
56
|
+
private cpuStart?;
|
|
57
57
|
constructor(init?: ProcessStatsCollectorOptions);
|
|
58
58
|
collect(): GaugeSnapshotEntry[];
|
|
59
59
|
/**
|
|
@@ -73,6 +73,10 @@ export declare class RequestLogCollector {
|
|
|
73
73
|
* Set request status.
|
|
74
74
|
*/
|
|
75
75
|
setStatus(status: RequestLog['status'], statusCode?: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* Set the HTTP status the request was answered with; one of 400 or more marks it failed.
|
|
78
|
+
*/
|
|
79
|
+
setStatusCode(statusCode: number): void;
|
|
76
80
|
/**
|
|
77
81
|
* Set error details.
|
|
78
82
|
*/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RequestLogCollector } from './request-log.collector';
|
|
2
|
+
import type { RequestLogCollectorOptions } from './request-log.types';
|
|
3
|
+
interface RequestLogFlowContext {
|
|
4
|
+
get?(token: unknown): unknown;
|
|
5
|
+
rawInput?: {
|
|
6
|
+
request?: {
|
|
7
|
+
method?: string;
|
|
8
|
+
path?: string;
|
|
9
|
+
body?: unknown;
|
|
10
|
+
headers?: Record<string, unknown>;
|
|
11
|
+
};
|
|
12
|
+
response?: {
|
|
13
|
+
statusCode?: unknown;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
state?: Record<string | symbol, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/** The open request log of the request `flowCtx` serves; entry flows annotate it. */
|
|
19
|
+
export declare function currentRequestLog(flowCtx: RequestLogFlowContext): RequestLogCollector | undefined;
|
|
20
|
+
/** Opens the request's log, kept on the request context so the entry flows and log entries reach it. */
|
|
21
|
+
export declare function startRequestLog(flowCtx: RequestLogFlowContext, options: RequestLogCollectorOptions): void;
|
|
22
|
+
/** Records why an entry flow failed (its `state.flowError`) on the request's log, as the client sees it. */
|
|
23
|
+
export declare function recordRequestLogFailure(flowCtx: RequestLogFlowContext): void;
|
|
24
|
+
/**
|
|
25
|
+
* Records how the HTTP flow authenticated the request (its `state.verifyResult`): `auth_type` is the scheme of
|
|
26
|
+
* the `Authorization` header (`bearer`), or `anonymous` for a caller without one or with an anonymous subject.
|
|
27
|
+
*/
|
|
28
|
+
export declare function recordRequestLogAuth(flowCtx: RequestLogFlowContext): void;
|
|
29
|
+
/**
|
|
30
|
+
* Closes the request's log with its HTTP status, which fires `requestLogs.onRequestComplete`: the status the
|
|
31
|
+
* flow responded with (`state.statusCode`), else the one a transport wrote to the response itself. A status
|
|
32
|
+
* of 400 or more marks the request failed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function completeRequestLog(flowCtx: RequestLogFlowContext): Promise<void>;
|
|
35
|
+
export {};
|
|
@@ -75,7 +75,7 @@ export interface RequestLog {
|
|
|
75
75
|
export interface RequestLogCollectorOptions {
|
|
76
76
|
/** Maximum entries to collect per request (default: 500) */
|
|
77
77
|
maxEntries?: number;
|
|
78
|
-
/**
|
|
78
|
+
/** Accepted, but not read yet: request logs carry no input or output summaries. */
|
|
79
79
|
includeSummaries?: boolean;
|
|
80
80
|
/** Callback when request log is complete */
|
|
81
81
|
onRequestComplete?: (log: RequestLog) => void | Promise<void>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Module augmentation for TypeScript — adds `this.telemetry` to every
|
|
3
3
|
* execution context: ExecutionContextBase (ToolContext, ResourceContext,
|
|
4
|
-
* AgentContext, JobContext, SkillContext, ...)
|
|
4
|
+
* AgentContext, JobContext, SkillContext, PromptContext, ...).
|
|
5
5
|
*
|
|
6
6
|
* This file provides type information only. The runtime getter is
|
|
7
7
|
* installed by the SDK's context extension mechanism when the
|
|
8
|
-
* ObservabilityPlugin registers its `contextExtensions`, on
|
|
9
|
-
*
|
|
8
|
+
* ObservabilityPlugin registers its `contextExtensions`, on
|
|
9
|
+
* ExecutionContextBase.prototype, which PromptContext inherits.
|
|
10
10
|
*/
|
|
11
11
|
import type { TelemetryAccessor } from './telemetry.accessor';
|
|
12
12
|
declare module '@frontmcp/sdk' {
|