@@ -17,8 +17,8 @@ import {
1717 TerminalError ,
1818} from "../../types/errors.js" ;
1919import type {
20- ProtocolMode ,
2120 Endpoint as EndpointManifest ,
21+ ProtocolMode ,
2222} from "../discovery.js" ;
2323import type { Component , ComponentHandler } from "../components.js" ;
2424import { parseUrlComponents } from "../components.js" ;
@@ -37,6 +37,7 @@ import {
3737} from "../../logging/console_logger_transport.js" ;
3838import {
3939 LoggerContext ,
40+ type LoggerTransport ,
4041 LogSource ,
4142 RestateLogLevel ,
4243} from "../../logging/logger_transport.js" ;
@@ -83,6 +84,47 @@ const ENDPOINT_MANIFEST_V2 = "application/vnd.restate.endpointmanifest.v2+json";
8384const ENDPOINT_MANIFEST_V3 = "application/vnd.restate.endpointmanifest.v3+json" ;
8485const ENDPOINT_MANIFEST_V4 = "application/vnd.restate.endpointmanifest.v4+json" ;
8586
87+ export function tryCreateContextualLogger (
88+ loggerTransport : LoggerTransport ,
89+ url : string ,
90+ headers : Headers ,
91+ additionalContext ?: { [ name : string ] : string }
92+ ) : Logger | undefined {
93+ try {
94+ const path = new URL ( url , "https://example.com" ) . pathname ;
95+ const parsed = parseUrlComponents ( path ) ;
96+ if ( parsed . type !== "invoke" ) {
97+ return undefined ;
98+ }
99+ const invocationId = invocationIdFromHeaders ( headers ) ;
100+ return createLogger (
101+ loggerTransport ,
102+ LogSource . SYSTEM ,
103+ new LoggerContext (
104+ invocationId ,
105+ parsed . componentName ,
106+ parsed . handlerName ,
107+ undefined ,
108+ undefined ,
109+ additionalContext
110+ )
111+ ) ;
112+ } catch ( e ) {
113+ return undefined ;
114+ }
115+ }
116+
117+ function invocationIdFromHeaders ( headers : Headers ) {
118+ const invocationIdHeader = headers [ "x-restate-invocation-id" ] ;
119+ const invocationId =
120+ typeof invocationIdHeader === "string"
121+ ? invocationIdHeader
122+ : Array . isArray ( invocationIdHeader )
123+ ? invocationIdHeader [ 0 ] ?? "unknown id"
124+ : "unknown id" ;
125+ return invocationId ;
126+ }
127+
86128/**
87129 * This is an internal API to support 'fetch' like handlers.
88130 * It supports both request-reply mode and bidirectional streaming mode.
@@ -130,8 +172,14 @@ export class GenericHandler implements RestateHandler {
130172 return await this . _handle ( request , context ) ;
131173 } catch ( e ) {
132174 const error = ensureError ( e ) ;
133- this . endpoint . rlog . error (
134- "Error while handling invocation: " + ( error . stack ?? error . message )
175+ (
176+ tryCreateContextualLogger (
177+ this . endpoint . loggerTransport ,
178+ request . url ,
179+ request . headers
180+ ) ?? this . endpoint . rlog
181+ ) . error (
182+ "Error while handling request: " + ( error . stack ?? error . message )
135183 ) ;
136184 return this . toErrorResponse (
137185 error instanceof RestateError ? error . code : 500 ,
@@ -285,7 +333,14 @@ export class GenericHandler implements RestateHandler {
285333 createLogger (
286334 this . endpoint . loggerTransport ,
287335 LogSource . JOURNAL ,
288- undefined
336+ new LoggerContext (
337+ invocationIdFromHeaders ( headers ) ,
338+ service . name ( ) ,
339+ handler . name ( ) ,
340+ undefined ,
341+ undefined ,
342+ additionalContext
343+ )
289344 )
290345 ) ;
291346
0 commit comments