Skip to content

Commit 4b265ec

Browse files
authored
chore: Deprecate WorkflowLogInterceptor (#1290)
1 parent caeb916 commit 4b265ec

16 files changed

+175
-132
lines changed

packages/test/src/integration-tests.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
import { msToNumber, tsToMs } from '@temporalio/common/lib/time';
3737
import { decode, decodeFromPayloadsAtIndex } from '@temporalio/common/lib/internal-non-workflow';
3838
import * as iface from '@temporalio/proto';
39-
import { appendDefaultInterceptors, DefaultLogger, makeTelemetryFilterString, Runtime } from '@temporalio/worker';
39+
import { DefaultLogger, makeTelemetryFilterString, Runtime } from '@temporalio/worker';
4040
import pkg from '@temporalio/worker/lib/pkg';
4141
import { UnsafeWorkflowInfo } from '@temporalio/workflow/src/interfaces';
4242
import * as activities from './activities';
@@ -95,9 +95,9 @@ export function runIntegrationTests(codec?: PayloadCodec): void {
9595
activities,
9696
taskQueue: 'test',
9797
dataConverter,
98-
interceptors: appendDefaultInterceptors({
98+
interceptors: {
9999
activity: [() => ({ inbound: new ConnectionInjectorInterceptor(connection, loadedDataConverter) })],
100-
}),
100+
},
101101
showStackTraceSources: true,
102102
});
103103

packages/test/src/test-integration-workflows.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { firstValueFrom, Subject } from 'rxjs';
44
import { WorkflowFailedError, WorkflowHandle, WorkflowStartOptions } from '@temporalio/client';
55
import { TestWorkflowEnvironment, workflowInterceptorModules } from '@temporalio/testing';
66
import {
7-
appendDefaultInterceptors,
87
bundleWorkflowCode,
98
DefaultLogger,
109
LogLevel,
@@ -53,9 +52,9 @@ function helpers(t: ExecutionContext<Context>): Helpers {
5352
connection: t.context.env.nativeConnection,
5453
workflowBundle: t.context.workflowBundle,
5554
taskQueue,
56-
interceptors: appendDefaultInterceptors({
55+
interceptors: {
5756
activity: [() => ({ inbound: new ConnectionInjectorInterceptor(t.context.env.connection) })],
58-
}),
57+
},
5958
showStackTraceSources: true,
6059
...opts,
6160
});

packages/test/src/test-local-activities.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { msToNumber } from '@temporalio/common/lib/time';
1414
import { temporal } from '@temporalio/proto';
1515
import { TestWorkflowEnvironment, workflowInterceptorModules } from '@temporalio/testing';
1616
import {
17-
appendDefaultInterceptors,
1817
bundleWorkflowCode,
1918
DefaultLogger,
2019
LogLevel,
@@ -61,11 +60,11 @@ function helpers(t: ExecutionContext<Context>): Helpers {
6160
connection: t.context.env.nativeConnection,
6261
workflowBundle: t.context.workflowBundle,
6362
taskQueue,
64-
interceptors: appendDefaultInterceptors({
63+
interceptors: {
6564
activity: interceptors?.activity ?? [
6665
() => ({ inbound: new ConnectionInjectorInterceptor(t.context.env.connection) }),
6766
],
68-
}),
67+
},
6968
showStackTraceSources: true,
7069
...rest,
7170
});

packages/test/src/test-workflow-log-interceptor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async function withWorker(
6262
return logs as [LogEntry, LogEntry];
6363
}
6464

65-
test('WorkflowInboundLogInterceptor logs when workflow completes', async (t) => {
65+
test('Workflow Worker logs when workflow completes', async (t) => {
6666
const { client } = t.context.testEnv;
6767
const workflowId = uuid4();
6868
const [startLog, endLog] = await withWorker(
@@ -81,7 +81,7 @@ test('WorkflowInboundLogInterceptor logs when workflow completes', async (t) =>
8181
t.is(endLog.message, 'Workflow completed');
8282
});
8383

84-
test('WorkflowInboundLogInterceptor logs when workflow continues as new', async (t) => {
84+
test('Workflow Worker logs when workflow continues as new', async (t) => {
8585
const { client } = t.context.testEnv;
8686
const workflowId = uuid4();
8787
const [_, endLog] = await withWorker(
@@ -100,7 +100,7 @@ test('WorkflowInboundLogInterceptor logs when workflow continues as new', async
100100
t.is(endLog.message, 'Workflow continued as new');
101101
});
102102

103-
test('WorkflowInboundLogInterceptor logs warning when workflow fails', async (t) => {
103+
test('Workflow Worker logs warning when workflow fails', async (t) => {
104104
const { client } = t.context.testEnv;
105105
const workflowId = uuid4();
106106
const [_, endLog] = await withWorker(

packages/worker/src/index.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export {
3737
WorkerStatus,
3838
} from './worker';
3939
export {
40-
appendDefaultInterceptors,
4140
CompiledWorkerOptions,
4241
ReplayWorkerOptions,
4342
WorkerOptions,
@@ -46,17 +45,7 @@ export {
4645
WorkflowBundlePath,
4746
} from './worker-options';
4847
export { ReplayError, ReplayHistoriesIterable, ReplayResult } from './replay';
49-
export {
50-
WorkflowInboundLogInterceptor, // eslint-disable-line deprecation/deprecation
51-
WorkflowLogInterceptor,
52-
workflowLogAttributes,
53-
} from './workflow-log-interceptor';
54-
export {
55-
BundleOptions,
56-
bundleWorkflowCode,
57-
defaultWorkflowInterceptorModules,
58-
WorkflowBundleWithSourceMap,
59-
} from './workflow/bundler';
48+
export { BundleOptions, bundleWorkflowCode, WorkflowBundleWithSourceMap } from './workflow/bundler';
6049

6150
// Anything below this line is deprecated
6251

@@ -76,6 +65,11 @@ export {
7665
activityLogAttributes,
7766
} from './activity';
7867
export {
68+
/**
69+
* @deprecated Including `appendDefaultInterceptors()` in the worker options is no longer required. To configure a
70+
* custom logger, set the {@see Runtime.logger} property instead.
71+
*/
72+
appendDefaultInterceptors, // eslint-disable-line deprecation/deprecation
7973
/**
8074
* @deprecated Including `defaultSinks()` in the worker options is no longer required. To configure
8175
* a custom logger, set the {@link Runtime.logger} property instead.
@@ -93,3 +87,27 @@ export {
9387
*/
9488
LoggerSinks, // eslint-disable-line deprecation/deprecation
9589
} from '@temporalio/workflow';
90+
export {
91+
/**
92+
* @deprecated `WorkflowInboundLogInterceptor` is deprecated. Workflow lifecycle events are now automatically logged
93+
* by the SDK. To customize workflow log attributes, simply register a custom `WorkflowInterceptors` that
94+
* intercepts the `outbound.getLogAttributes()` method.
95+
*/
96+
WorkflowInboundLogInterceptor, // eslint-disable-line deprecation/deprecation
97+
/**
98+
* @deprecated `WorkflowLogInterceptor` is deprecated. Workflow lifecycle events are now automatically logged
99+
* by the SDK. To customize workflow log attributes, simply register a custom `WorkflowInterceptors` that
100+
* intercepts the `outbound.getLogAttributes()` method.
101+
*/
102+
WorkflowLogInterceptor, // eslint-disable-line deprecation/deprecation
103+
} from './workflow-log-interceptor';
104+
export {
105+
/**
106+
* @deprecated This function is meant for internal usage. Don't use it.
107+
*/
108+
workflowLogAttributes,
109+
} from '@temporalio/workflow/lib/logs';
110+
/**
111+
* @deprecated Including `defaultWorkflowInterceptorModules` in BundlerOptions.workflowInterceptorModules is no longer required.
112+
*/
113+
export const defaultWorkflowInterceptorModules = [];

packages/worker/src/worker-options.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { initLoggerSink } from './workflow/logger';
1414
import { Runtime } from './runtime';
1515
import { InjectedSinks } from './sinks';
1616
import { MiB } from './utils';
17-
import { defaultWorkflowInterceptorModules, WorkflowBundleWithSourceMap } from './workflow/bundler';
17+
import { WorkflowBundleWithSourceMap } from './workflow/bundler';
1818

1919
export type { WebpackConfiguration };
2020

@@ -417,6 +417,9 @@ export interface WorkerOptions {
417417
418418
* When using {@link workflowBundle}, these Workflow interceptors (`WorkerInterceptors.workflowModules`) are not used.
419419
* Instead, provide them via {@link BundleOptions.workflowInterceptorModules} when calling {@link bundleWorkflowCode}.
420+
*
421+
* Before v1.9.0, calling `appendDefaultInterceptors()` was required when registering custom interceptors in order to
422+
* preserve SDK's logging interceptors. This is no longer the case.
420423
*/
421424
interceptors?: WorkerInterceptors;
422425

@@ -622,27 +625,25 @@ export function defaultSinks(logger?: Logger): InjectedSinks<LoggerSinks> {
622625
* Appends the default Worker logging interceptors to given interceptor arrays.
623626
*
624627
* @param logger a {@link Logger} - defaults to the {@link Runtime} singleton logger.
628+
*
629+
* @deprecated Calling `appendDefaultInterceptors()` is no longer required. To configure a custom logger, set the
630+
* {@see Runtime.logger} property instead.
625631
*/
626632
export function appendDefaultInterceptors(
627633
interceptors: WorkerInterceptors,
628634
logger?: Logger | undefined
629-
): Required<WorkerInterceptors> {
630-
// FIXME: Don't worry for this function being unclean, this code will be optimized in the next PR.
635+
): WorkerInterceptors {
636+
if (!logger || logger === Runtime.instance().logger) return interceptors;
631637

632-
// eslint-disable-next-line deprecation/deprecation
633-
let activityInbound = interceptors.activityInbound ?? [];
634-
if (logger && logger !== Runtime.instance().logger) {
635-
activityInbound = [
638+
return {
639+
activityInbound: [
636640
// eslint-disable-next-line deprecation/deprecation
637641
(ctx) => new ActivityInboundLogInterceptor(ctx, logger),
638-
...activityInbound,
639-
];
640-
}
641-
642-
return {
643-
activityInbound,
644-
activity: interceptors.activity ?? [],
645-
workflowModules: [...(interceptors.workflowModules ?? []), ...defaultWorkflowInterceptorModules],
642+
// eslint-disable-next-line deprecation/deprecation
643+
...(interceptors.activityInbound ?? []),
644+
],
645+
activity: interceptors.activity,
646+
workflowModules: interceptors.workflowModules,
646647
};
647648
}
648649

@@ -703,7 +704,12 @@ export function addDefaultWorkerOptions(options: WorkerOptions): WorkerOptionsWi
703704
showStackTraceSources: showStackTraceSources ?? false,
704705
reuseV8Context: reuseV8Context ?? false,
705706
debugMode: debugMode ?? false,
706-
interceptors: appendDefaultInterceptors(interceptors ?? {}),
707+
interceptors: {
708+
activity: interceptors?.activity ?? [],
709+
// eslint-disable-next-line deprecation/deprecation
710+
activityInbound: interceptors?.activityInbound ?? [],
711+
workflowModules: interceptors?.workflowModules ?? [],
712+
},
707713
nonStickyToStickyPollRatio: nonStickyToStickyPollRatio ?? 0.2,
708714
sinks: {
709715
...initLoggerSink(Runtime.instance().logger),

packages/worker/src/worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
import { historyFromJSON } from '@temporalio/common/lib/proto-utils';
4343
import { optionalTsToDate, optionalTsToMs, tsToDate, tsToMs } from '@temporalio/common/lib/time';
4444
import { errorMessage, isError, SymbolBasedInstanceOfError } from '@temporalio/common/lib/type-helpers';
45+
import { workflowLogAttributes } from '@temporalio/workflow/lib/logs';
4546
import * as native from '@temporalio/core-bridge';
4647
import { ShutdownError, UnexpectedError } from '@temporalio/core-bridge';
4748
import { coresdk, temporal } from '@temporalio/proto';
@@ -72,7 +73,6 @@ import {
7273
WorkflowBundle,
7374
} from './worker-options';
7475
import { WorkflowCodecRunner } from './workflow-codec-runner';
75-
import { workflowLogAttributes } from './workflow-log-interceptor';
7676
import { defaultWorkflowInterceptorModules, WorkflowCodeBundler } from './workflow/bundler';
7777
import { Workflow, WorkflowCreator } from './workflow/interface';
7878
import { ReusableVMWorkflowCreator } from './workflow/reusable-vm';
Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,46 @@
11
import {
2-
isCancellation,
32
Next,
43
WorkflowExecuteInput,
54
WorkflowInboundCallsInterceptor,
65
WorkflowOutboundCallsInterceptor,
7-
workflowInfo,
8-
WorkflowInfo,
96
WorkflowInterceptorsFactory,
10-
log,
11-
ContinueAsNew,
127
GetLogAttributesInput,
138
} from '@temporalio/workflow';
14-
import { untrackPromise } from '@temporalio/workflow/lib/stack-helpers';
159

1610
/**
17-
* Returns a map of attributes to be set on log messages for a given Workflow
11+
* This interceptor used to be meant to log Workflow execution starts and completions, and attaches log attributes to
12+
* `workflow.log` calls. It is now deprecated and behaves as a noop in all cases. It is only kept arround to avoid
13+
* breaking code out there that was previously refering to it.
14+
*
15+
* @deprecated `WorkflowLogInterceptor` is deprecated. Workflow lifecycle events are now automatically logged
16+
* by the SDK. To customize workflow log attributes, simply register a custom `WorkflowInterceptors` that
17+
* intercepts the `outbound.getLogAttributes()` method.
1818
*/
19-
export function workflowLogAttributes(info: WorkflowInfo): Record<string, unknown> {
20-
return {
21-
namespace: info.namespace,
22-
taskQueue: info.taskQueue,
23-
workflowId: info.workflowId,
24-
runId: info.runId,
25-
workflowType: info.workflowType,
26-
};
27-
}
28-
29-
/** Logs workflow execution starts and completions, attaches log attributes to `workflow.log` calls */
3019
export class WorkflowLogInterceptor implements WorkflowInboundCallsInterceptor, WorkflowOutboundCallsInterceptor {
3120
getLogAttributes(
3221
input: GetLogAttributesInput,
3322
next: Next<WorkflowOutboundCallsInterceptor, 'getLogAttributes'>
3423
): Record<string, unknown> {
35-
return next({ ...input, ...workflowLogAttributes(workflowInfo()) });
24+
return next(input);
3625
}
3726

3827
execute(input: WorkflowExecuteInput, next: Next<WorkflowInboundCallsInterceptor, 'execute'>): Promise<unknown> {
39-
log.debug('Workflow started');
40-
const p = next(input).then(
41-
(res) => {
42-
log.debug('Workflow completed');
43-
return res;
44-
},
45-
(error) => {
46-
// Avoid using instanceof checks in case the modules they're defined in loaded more than once,
47-
// e.g. by jest or when multiple versions are installed.
48-
if (typeof error === 'object' && error != null) {
49-
if (isCancellation(error)) {
50-
log.debug('Workflow completed as cancelled');
51-
throw error;
52-
} else if (error instanceof ContinueAsNew) {
53-
log.debug('Workflow continued as new');
54-
throw error;
55-
}
56-
}
57-
log.warn('Workflow failed', { error });
58-
throw error;
59-
}
60-
);
61-
// Avoid showing this interceptor in stack trace query
62-
untrackPromise(p);
63-
return p;
28+
// Logging of workflow's lifecycle events is now handled in `workflow/src/logs.ts`
29+
return next(input);
6430
}
6531
}
6632

67-
/** @deprecated use {@link WorkflowLogInterceptor} instead */
33+
/**
34+
* @deprecated `WorkflowInboundLogInterceptor` is deprecated. Workflow lifecycle events are now automatically logged
35+
* by the SDK. To customize workflow log attributes, simply register a custom `WorkflowInterceptors` that
36+
* intercepts the `outbound.getLogAttributes()` method.
37+
*/
38+
// eslint-disable-next-line deprecation/deprecation
6839
export const WorkflowInboundLogInterceptor = WorkflowLogInterceptor;
6940

7041
// ts-prune-ignore-next
7142
export const interceptors: WorkflowInterceptorsFactory = () => {
43+
// eslint-disable-next-line deprecation/deprecation
7244
const interceptor = new WorkflowLogInterceptor();
7345
return { inbound: [interceptor], outbound: [interceptor] };
7446
};

packages/worker/src/workflow/bundler.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class WorkflowCodeBundler {
6767
this.workflowsPath = workflowsPath;
6868
this.payloadConverterPath = payloadConverterPath;
6969
this.failureConverterPath = failureConverterPath;
70-
this.workflowInterceptorModules = workflowInterceptorModules ?? defaultWorkflowInterceptorModules;
70+
this.workflowInterceptorModules = workflowInterceptorModules ?? [];
7171
this.ignoreModules = ignoreModules ?? [];
7272
this.webpackConfigHook = webpackConfigHook ?? ((config) => config);
7373
}
@@ -317,9 +317,6 @@ export interface BundleOptions {
317317
* List of modules to import Workflow interceptors from.
318318
*
319319
* Modules should export an `interceptors` variable of type {@link WorkflowInterceptorsFactory}.
320-
*
321-
* By default, {@link WorkflowInboundLogInterceptor} is installed. If you wish to customize the interceptors while
322-
* keeping the defaults, add {@link defaultWorkflowInterceptorModules} to the provided array.
323320
*/
324321
workflowInterceptorModules?: string[];
325322
/**

packages/workflow/src/errors.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ActivityFailure, CancelledFailure, ChildWorkflowFailure } from '@temporalio/common';
22
import { SymbolBasedInstanceOfError } from '@temporalio/common/lib/type-helpers';
3+
import { coresdk } from '@temporalio/proto';
34

45
/**
56
* Base class for all workflow errors
@@ -13,6 +14,16 @@ export class WorkflowError extends Error {}
1314
@SymbolBasedInstanceOfError('DeterminismViolationError')
1415
export class DeterminismViolationError extends WorkflowError {}
1516

17+
/**
18+
* A class that acts as a marker for this special result type
19+
*/
20+
@SymbolBasedInstanceOfError('LocalActivityDoBackoff')
21+
export class LocalActivityDoBackoff extends Error {
22+
constructor(public readonly backoff: coresdk.activity_result.IDoBackoff) {
23+
super();
24+
}
25+
}
26+
1627
/**
1728
* Returns whether provided `err` is caused by cancellation
1829
*/

0 commit comments

Comments
 (0)