import { Context } from '@temporalio/activity' ; import { ActivityInboundCallsInterceptor , ActivityExecuteInput , Next } from '@temporalio/worker' ; import { Logger } from 'winston' ; /** An Activity Context with an attached logger */ export interface ContextWithLogger extends Context { logger : Logger ; } /** Get the current Activity context with an attached logger */ export function getContext ( ) { return Context . current ( ) as ContextWithLogger ; } /** Logs Activity executions and their duration */ export class ActivityInboundLogInterceptor implements ActivityInboundCallsInterceptor { public readonly logger : Logger ; constructor ( ctx , logger ) { this . logger = logger . child ( { activity : ctx . info , } ) ; ( ctx as ContextWithLogger ) . logger = logger ; } async execute ( input , next ) { let error = undefined ; const startTime = process . hrtime . bigint ( ) ; try { return await next ( input ) ; } catch ( err ) { error = err ; throw err ; } finally { const durationNanos = process . hrtime . bigint ( ) - startTime ; const durationMs = Number ( durationNanos / 1000000n ) ; if ( error ) { this . logger . error ( 'activity failed' , { error , durationMs } ) ; } else { this . logger . debug ( 'activity completed' , { durationMs } ) ; } } } }