@frontmcp/observability 1.9.2 → 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.
@@ -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 telemetry report on first request (default: true) */
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.2",
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.2",
55
- "@frontmcp/utils": "1.9.2",
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;
@@ -26,6 +26,12 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
26
26
  constructor(options?: ObservabilityPluginOptionsInput);
27
27
  private get tracingEnabled();
28
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;
29
35
  /** Names the entry a request serves on its request log, and records the entry flow's failure. */
30
36
  private annotateRequestLog;
31
37
  _httpWillTrace(ctx: unknown): void;
@@ -148,8 +154,7 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
148
154
  _toolDidCreateCtxFetch(ctx: unknown): void;
149
155
  _agentDidExecuteMeta(ctx: unknown): void;
150
156
  /**
151
- * Emit startup telemetry report.
152
- * Call after scope.initialize() completes with component counts.
157
+ * Emit the `frontmcp.startup` span (`tracing.startupReport`). The scope calls it once it is ready.
153
158
  */
154
159
  reportStartupTelemetry(data: StartupTelemetryData): void;
155
160
  static dynamicProviders: (input: ObservabilityPluginOptionsInput) => ProviderType[];
@@ -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
  */
@@ -7,6 +7,7 @@ interface RequestLogFlowContext {
7
7
  method?: string;
8
8
  path?: string;
9
9
  body?: unknown;
10
+ headers?: Record<string, unknown>;
10
11
  };
11
12
  response?: {
12
13
  statusCode?: unknown;
@@ -18,11 +19,17 @@ interface RequestLogFlowContext {
18
19
  export declare function currentRequestLog(flowCtx: RequestLogFlowContext): RequestLogCollector | undefined;
19
20
  /** Opens the request's log, kept on the request context so the entry flows and log entries reach it. */
20
21
  export declare function startRequestLog(flowCtx: RequestLogFlowContext, options: RequestLogCollectorOptions): void;
21
- /** Records why an entry flow failed (its `state.flowError`) on the request's log. */
22
+ /** Records why an entry flow failed (its `state.flowError`) on the request's log, as the client sees it. */
22
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;
23
29
  /**
24
30
  * Closes the request's log with its HTTP status, which fires `requestLogs.onRequestComplete`: the status the
25
- * flow responded with (`state.statusCode`), else the one a transport wrote to the response itself.
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.
26
33
  */
27
34
  export declare function completeRequestLog(flowCtx: RequestLogFlowContext): Promise<void>;
28
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
- /** Include input/output summaries (default: true) */
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>;