Skip to content

Commit 9e2729c

Browse files
committed
runtime manager debug logs
1 parent 3cb44a1 commit 9e2729c

File tree

6 files changed

+99
-10
lines changed

6 files changed

+99
-10
lines changed

packages/cli-v3/src/entryPoints/managed/execution.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ export class RunExecution {
144144
}
145145
});
146146

147+
taskRunProcess.onSendDebugLog.attach(async (debugLog) => {
148+
this.sendRuntimeDebugLog(debugLog.message, debugLog.properties);
149+
});
150+
147151
return taskRunProcess;
148152
}
149153

@@ -951,6 +955,26 @@ export class RunExecution {
951955
});
952956
}
953957

958+
private sendRuntimeDebugLog(
959+
message: string,
960+
properties?: SendDebugLogOptions["properties"],
961+
runIdOverride?: string
962+
) {
963+
this.logger.sendDebugLog({
964+
runId: runIdOverride ?? this.runFriendlyId,
965+
message: `[runtime] ${message}`,
966+
print: false,
967+
properties: {
968+
...properties,
969+
runId: this.runFriendlyId,
970+
snapshotId: this.currentSnapshotId,
971+
executionId: this.id,
972+
executionRestoreCount: this.restoreCount,
973+
lastHeartbeat: this.lastHeartbeat?.toISOString(),
974+
},
975+
});
976+
}
977+
954978
// Ensure we can only set this once
955979
private set runFriendlyId(id: string) {
956980
if (this._runFriendlyId) {

packages/cli-v3/src/entryPoints/managed/logger.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type SendDebugLogOptions = {
99
message: string;
1010
date?: Date;
1111
properties?: WorkloadDebugLogRequestBody["properties"];
12+
print?: boolean;
1213
};
1314

1415
export type RunLoggerOptions = {
@@ -25,7 +26,7 @@ export class RunLogger {
2526
this.env = opts.env;
2627
}
2728

28-
sendDebugLog({ runId, message, date, properties }: SendDebugLogOptions) {
29+
sendDebugLog({ runId, message, date, properties, print = true }: SendDebugLogOptions) {
2930
if (!runId) {
3031
runId = this.env.TRIGGER_RUN_ID;
3132
}
@@ -41,7 +42,9 @@ export class RunLogger {
4142
workerName: this.env.TRIGGER_WORKER_INSTANCE_NAME,
4243
};
4344

44-
console.log(message, mergedProperties);
45+
if (print) {
46+
console.log(message, mergedProperties);
47+
}
4548

4649
this.httpClient.sendDebugLog(runId, {
4750
message,

packages/cli-v3/src/executions/taskRunProcess.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ import {
3333
SuspendedProcessError,
3434
} from "@trigger.dev/core/v3/errors";
3535

36+
export type OnSendDebugLogMessage = InferSocketMessageSchema<
37+
typeof ExecutorToWorkerMessageCatalog,
38+
"SEND_DEBUG_LOG"
39+
>;
40+
3641
export type TaskRunProcessOptions = {
3742
workerManifest: WorkerManifest;
3843
serverWorker: ServerBackgroundWorker;
@@ -68,6 +73,7 @@ export class TaskRunProcess {
6873
public onExit: Evt<{ code: number | null; signal: NodeJS.Signals | null; pid?: number }> =
6974
new Evt();
7075
public onIsBeingKilled: Evt<TaskRunProcess> = new Evt();
76+
public onSendDebugLog: Evt<OnSendDebugLogMessage> = new Evt();
7177

7278
private _isPreparedForNextRun: boolean = false;
7379
private _isPreparedForNextAttempt: boolean = false;
@@ -178,6 +184,9 @@ export class TaskRunProcess {
178184
UNCAUGHT_EXCEPTION: async (message) => {
179185
logger.debug("uncaught exception in task run process", { ...message });
180186
},
187+
SEND_DEBUG_LOG: async (message) => {
188+
this.onSendDebugLog.post(message);
189+
},
181190
},
182191
});
183192

packages/core/src/v3/runEngineWorker/supervisor/schemas.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export type WorkerApiDequeueFromVersionResponseBody = z.infer<
126126
typeof WorkerApiDequeueFromVersionResponseBody
127127
>;
128128

129-
const AttributeValue = z.union([
129+
export const DebugLogPropertiesValue = z.union([
130130
z.string(),
131131
z.number(),
132132
z.boolean(),
@@ -135,12 +135,13 @@ const AttributeValue = z.union([
135135
z.array(z.boolean().nullable()),
136136
]);
137137

138-
const Attributes = z.record(z.string(), AttributeValue.optional());
138+
export const DebugLogProperties = z.record(z.string(), DebugLogPropertiesValue.optional());
139+
export type DebugLogProperties = z.infer<typeof DebugLogProperties>;
139140

140141
export const WorkerApiDebugLogBody = z.object({
141142
time: z.coerce.date(),
142143
message: z.string(),
143-
properties: Attributes.optional(),
144+
properties: DebugLogProperties.optional(),
144145
});
145146
export type WorkerApiDebugLogBody = z.infer<typeof WorkerApiDebugLogBody>;
146147

packages/core/src/v3/runtime/sharedRuntimeManager.ts

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { assertExhaustive } from "../../utils.js";
22
import { clock } from "../clock-api.js";
33
import { lifecycleHooks } from "../lifecycle-hooks-api.js";
4+
import { DebugLogProperties } from "../runEngineWorker/index.js";
45
import {
56
BatchTaskRunExecutionResult,
67
CompletedWaitpoint,
@@ -176,7 +177,10 @@ export class SharedRuntimeManager implements RuntimeManager {
176177
switch (waitpoint.type) {
177178
case "RUN": {
178179
if (!waitpoint.completedByTaskRun) {
179-
this.log("No completedByTaskRun for RUN waitpoint", waitpoint);
180+
this.debugLog(
181+
"No completedByTaskRun for RUN waitpoint",
182+
this.waitpointForDebugLog(waitpoint)
183+
);
180184
return null;
181185
}
182186

@@ -192,7 +196,10 @@ export class SharedRuntimeManager implements RuntimeManager {
192196
}
193197
case "BATCH": {
194198
if (!waitpoint.completedByBatch) {
195-
this.log("No completedByBatch for BATCH waitpoint", waitpoint);
199+
this.debugLog(
200+
"No completedByBatch for BATCH waitpoint",
201+
this.waitpointForDebugLog(waitpoint)
202+
);
196203
return null;
197204
}
198205

@@ -213,18 +220,19 @@ export class SharedRuntimeManager implements RuntimeManager {
213220
}
214221

215222
private resolveWaitpoint(waitpoint: CompletedWaitpoint, resolverId?: ResolverId | null): void {
223+
// This is spammy, don't make this a debug log
216224
this.log("resolveWaitpoint", waitpoint);
217225

218226
if (waitpoint.type === "BATCH") {
219227
// We currently ignore these, they're not required to resume after a batch completes
220-
this.log("Ignoring BATCH waitpoint", waitpoint);
228+
this.debugLog("Ignoring BATCH waitpoint", this.waitpointForDebugLog(waitpoint));
221229
return;
222230
}
223231

224232
resolverId = resolverId ?? this.resolverIdFromWaitpoint(waitpoint);
225233

226234
if (!resolverId) {
227-
this.log("No resolverId for waitpoint", { ...this.status, ...waitpoint });
235+
this.debugLog("No resolverId for waitpoint", this.waitpointForDebugLog(waitpoint));
228236

229237
// No need to store the waitpoint, we'll never be able to resolve it
230238
return;
@@ -233,7 +241,7 @@ export class SharedRuntimeManager implements RuntimeManager {
233241
const resolve = this.resolversById.get(resolverId);
234242

235243
if (!resolve) {
236-
this.log("No resolver found for resolverId", { ...this.status, resolverId });
244+
this.debugLog("No resolver found for resolverId", { ...this.status, resolverId });
237245

238246
// Store the waitpoint for later if we can't find a resolver
239247
this.waitpointsByResolverId.set(resolverId, waitpoint);
@@ -280,6 +288,42 @@ export class SharedRuntimeManager implements RuntimeManager {
280288
}
281289
}
282290

291+
private waitpointForDebugLog(waitpoint: CompletedWaitpoint): DebugLogProperties {
292+
const {
293+
completedByTaskRun,
294+
completedByBatch,
295+
completedAfter,
296+
completedAt,
297+
output,
298+
id,
299+
...rest
300+
} = waitpoint;
301+
302+
return {
303+
...rest,
304+
waitpointId: id,
305+
output: output?.slice(0, 100),
306+
completedByTaskRunId: completedByTaskRun?.id,
307+
completedByTaskRunBatchId: completedByTaskRun?.batch?.id,
308+
completedByBatchId: completedByBatch?.id,
309+
completedAfter: completedAfter?.toISOString(),
310+
completedAt: completedAt?.toISOString(),
311+
};
312+
}
313+
314+
private debugLog(message: string, properties?: DebugLogProperties) {
315+
const status = this.status;
316+
317+
if (this.showLogs) {
318+
console.log(`[${new Date().toISOString()}] ${message}`, { ...status, ...properties });
319+
}
320+
321+
this.ipc.send("SEND_DEBUG_LOG", {
322+
message,
323+
properties: { ...status, ...properties },
324+
});
325+
}
326+
283327
private log(message: string, ...args: any[]) {
284328
if (!this.showLogs) return;
285329
console.log(`[${new Date().toISOString()}] ${message}`, args);

packages/core/src/v3/schemas/messages.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
WaitReason,
1919
} from "./schemas.js";
2020
import { CompletedWaitpoint } from "./runEngine.js";
21+
import { DebugLogProperties } from "../runEngineWorker/index.js";
2122

2223
export const AckCallbackResult = z.discriminatedUnion("success", [
2324
z.object({
@@ -174,6 +175,13 @@ export const ExecutorToWorkerMessageCatalog = {
174175
UNCAUGHT_EXCEPTION: {
175176
message: UncaughtExceptionMessage,
176177
},
178+
SEND_DEBUG_LOG: {
179+
message: z.object({
180+
version: z.literal("v1").default("v1"),
181+
message: z.string(),
182+
properties: DebugLogProperties.optional(),
183+
}),
184+
},
177185
};
178186

179187
export const WorkerToExecutorMessageCatalog = {

0 commit comments

Comments
 (0)