Optionally disable run debug logs (#2116)
* disable run debug logs by default * lightweight webapp health check * disable debug logs for dev runs * disable run debug logs for supervisor client * add changeset
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@trigger.dev/core": patch
|
||||
---
|
||||
|
||||
Add supervisor http client option to disable debug logs
|
||||
@@ -87,6 +87,7 @@ const Env = z.object({
|
||||
|
||||
// Debug
|
||||
DEBUG: BoolEnv.default(false),
|
||||
SEND_RUN_DEBUG_LOGS: BoolEnv.default(false),
|
||||
});
|
||||
|
||||
export const env = Env.parse(stdEnv);
|
||||
|
||||
@@ -130,6 +130,7 @@ class ManagedSupervisor {
|
||||
maxConsumerCount: env.TRIGGER_DEQUEUE_MAX_CONSUMER_COUNT,
|
||||
runNotificationsEnabled: env.TRIGGER_WORKLOAD_API_ENABLED,
|
||||
heartbeatIntervalSeconds: env.TRIGGER_WORKER_HEARTBEAT_INTERVAL_SECONDS,
|
||||
sendRunDebugLogs: env.SEND_RUN_DEBUG_LOGS,
|
||||
preDequeue: async () => {
|
||||
if (!env.RESOURCE_MONITOR_ENABLED) {
|
||||
return {};
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import { HttpServer, type CheckpointClient } from "@trigger.dev/core/v3/serverOnly";
|
||||
import { type IncomingMessage } from "node:http";
|
||||
import { register } from "../metrics.js";
|
||||
import { env } from "../env.js";
|
||||
|
||||
// Use the official export when upgrading to socket.io@4.8.0
|
||||
interface DefaultEventsMap {
|
||||
@@ -374,6 +375,10 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
handler: async ({ req, reply, params, body }) => {
|
||||
reply.empty(204);
|
||||
|
||||
if (!env.SEND_RUN_DEBUG_LOGS) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.workerClient.sendDebugLog(
|
||||
params.runFriendlyId,
|
||||
body,
|
||||
|
||||
@@ -11,64 +11,69 @@ import { logger } from "~/services/logger.server";
|
||||
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
|
||||
import { recordRunDebugLog } from "~/v3/eventRepository.server";
|
||||
|
||||
const { action } = createActionApiRoute(
|
||||
{
|
||||
params: z.object({
|
||||
runFriendlyId: z.string(),
|
||||
}),
|
||||
body: WorkerApiDebugLogBody,
|
||||
method: "POST",
|
||||
},
|
||||
async ({
|
||||
authentication,
|
||||
body,
|
||||
params,
|
||||
}): Promise<TypedResponse<WorkerApiRunAttemptStartResponseBody>> => {
|
||||
const { runFriendlyId } = params;
|
||||
// const { action } = createActionApiRoute(
|
||||
// {
|
||||
// params: z.object({
|
||||
// runFriendlyId: z.string(),
|
||||
// }),
|
||||
// body: WorkerApiDebugLogBody,
|
||||
// method: "POST",
|
||||
// },
|
||||
// async ({
|
||||
// authentication,
|
||||
// body,
|
||||
// params,
|
||||
// }): Promise<TypedResponse<WorkerApiRunAttemptStartResponseBody>> => {
|
||||
// const { runFriendlyId } = params;
|
||||
|
||||
try {
|
||||
const run = await prisma.taskRun.findFirst({
|
||||
where: {
|
||||
friendlyId: params.runFriendlyId,
|
||||
runtimeEnvironmentId: authentication.environment.id,
|
||||
},
|
||||
});
|
||||
// try {
|
||||
// const run = await prisma.taskRun.findFirst({
|
||||
// where: {
|
||||
// friendlyId: params.runFriendlyId,
|
||||
// runtimeEnvironmentId: authentication.environment.id,
|
||||
// },
|
||||
// });
|
||||
|
||||
if (!run) {
|
||||
throw new Response("You don't have permissions for this run", { status: 401 });
|
||||
}
|
||||
// if (!run) {
|
||||
// throw new Response("You don't have permissions for this run", { status: 401 });
|
||||
// }
|
||||
|
||||
const eventResult = await recordRunDebugLog(
|
||||
RunId.fromFriendlyId(runFriendlyId),
|
||||
body.message,
|
||||
{
|
||||
attributes: {
|
||||
properties: body.properties,
|
||||
},
|
||||
startTime: body.time,
|
||||
}
|
||||
);
|
||||
// const eventResult = await recordRunDebugLog(
|
||||
// RunId.fromFriendlyId(runFriendlyId),
|
||||
// body.message,
|
||||
// {
|
||||
// attributes: {
|
||||
// properties: body.properties,
|
||||
// },
|
||||
// startTime: body.time,
|
||||
// }
|
||||
// );
|
||||
|
||||
if (eventResult.success) {
|
||||
return new Response(null, { status: 204 });
|
||||
}
|
||||
// if (eventResult.success) {
|
||||
// return new Response(null, { status: 204 });
|
||||
// }
|
||||
|
||||
switch (eventResult.code) {
|
||||
case "FAILED_TO_RECORD_EVENT":
|
||||
return new Response(null, { status: 400 }); // send a 400 to prevent retries
|
||||
case "RUN_NOT_FOUND":
|
||||
return new Response(null, { status: 404 });
|
||||
default:
|
||||
return assertExhaustive(eventResult.code);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to record dev log", {
|
||||
environmentId: authentication.environment.id,
|
||||
error,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
);
|
||||
// switch (eventResult.code) {
|
||||
// case "FAILED_TO_RECORD_EVENT":
|
||||
// return new Response(null, { status: 400 }); // send a 400 to prevent retries
|
||||
// case "RUN_NOT_FOUND":
|
||||
// return new Response(null, { status: 404 });
|
||||
// default:
|
||||
// return assertExhaustive(eventResult.code);
|
||||
// }
|
||||
// } catch (error) {
|
||||
// logger.error("Failed to record dev log", {
|
||||
// environmentId: authentication.environment.id,
|
||||
// error,
|
||||
// });
|
||||
// throw error;
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
export { action };
|
||||
// export { action };
|
||||
|
||||
// Create a generic JSON action in remix
|
||||
export function action() {
|
||||
return new Response(null, { status: 204 });
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { LoaderFunction } from "@remix-run/node";
|
||||
|
||||
export const loader: LoaderFunction = async ({ request }) => {
|
||||
try {
|
||||
await prisma.user.count();
|
||||
await prisma.$queryRaw`SELECT 1`;
|
||||
return new Response("OK");
|
||||
} catch (error: unknown) {
|
||||
console.log("healthcheck ❌", { error });
|
||||
|
||||
@@ -33,6 +33,7 @@ export class SupervisorHttpClient {
|
||||
private readonly workerToken: string;
|
||||
private readonly instanceName: string;
|
||||
private readonly defaultHeaders: Record<string, string>;
|
||||
private readonly sendRunDebugLogs: boolean;
|
||||
|
||||
private readonly logger = new SimpleStructuredLogger("supervisor-http-client");
|
||||
|
||||
@@ -41,6 +42,7 @@ export class SupervisorHttpClient {
|
||||
this.workerToken = opts.workerToken;
|
||||
this.instanceName = opts.instanceName;
|
||||
this.defaultHeaders = getDefaultWorkerHeaders(opts);
|
||||
this.sendRunDebugLogs = opts.sendRunDebugLogs ?? false;
|
||||
|
||||
if (!this.apiUrl) {
|
||||
throw new Error("apiURL is required and needs to be a non-empty string");
|
||||
@@ -204,6 +206,10 @@ export class SupervisorHttpClient {
|
||||
}
|
||||
|
||||
async sendDebugLog(runId: string, body: WorkerApiDebugLogBody, runnerId?: string): Promise<void> {
|
||||
if (!this.sendRunDebugLogs) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await wrapZodFetch(
|
||||
z.unknown(),
|
||||
|
||||
@@ -21,6 +21,7 @@ type SupervisorSessionOptions = SupervisorClientCommonOptions & {
|
||||
preSkip?: PreSkipFn;
|
||||
maxRunCount?: number;
|
||||
maxConsumerCount?: number;
|
||||
sendRunDebugLogs?: boolean;
|
||||
};
|
||||
|
||||
export class SupervisorSession extends EventEmitter<WorkerEvents> {
|
||||
|
||||
@@ -6,6 +6,7 @@ export type SupervisorClientCommonOptions = {
|
||||
instanceName: string;
|
||||
deploymentId?: string;
|
||||
managedWorkerSecret?: string;
|
||||
sendRunDebugLogs?: boolean;
|
||||
};
|
||||
|
||||
export type PreDequeueFn = () => Promise<{
|
||||
|
||||
Reference in New Issue
Block a user