diff --git a/apps/webapp/app/presenters/v3/RunPresenter.server.ts b/apps/webapp/app/presenters/v3/RunPresenter.server.ts index b235dacded7..d3ea2099245 100644 --- a/apps/webapp/app/presenters/v3/RunPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/RunPresenter.server.ts @@ -32,6 +32,7 @@ export class RunPresenter { environmentSlug, runFriendlyId, showDeletedLogs, + showDebug, }: { userId: string; projectSlug: string; @@ -39,6 +40,7 @@ export class RunPresenter { environmentSlug: string; runFriendlyId: string; showDeletedLogs: boolean; + showDebug: boolean; }) { const run = await this.#prismaClient.taskRun.findFirstOrThrow({ select: { @@ -131,7 +133,8 @@ export class RunPresenter { getTaskEventStoreTableForRun(run), run.traceId, run.rootTaskRun?.createdAt ?? run.createdAt, - run.completedAt ?? undefined + run.completedAt ?? undefined, + { includeDebugLogs: showDebug } ); if (!traceSummary) { return { diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index a733a2b9b5f..9e9145be9a9 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -95,6 +95,7 @@ import { } from "~/utils/pathBuilder"; import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; import { SpanView } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route"; +import { useSearchParams } from "~/hooks/useSearchParam"; const resizableSettings = { parent: { @@ -133,6 +134,9 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { const impersonationId = await getImpersonationId(request); const { projectParam, organizationSlug, envParam, runParam } = v3RunParamsSchema.parse(params); + const url = new URL(request.url); + const showDebug = url.searchParams.get("showDebug") === "true"; + const presenter = new RunPresenter(); const [error, result] = await tryCatch( presenter.call({ @@ -142,6 +146,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { projectSlug: projectParam, runFriendlyId: runParam, environmentSlug: envParam, + showDebug, }) ); @@ -505,15 +510,18 @@ function TasksTreeView({ const isAdmin = useHasAdminAccess(); const [filterText, setFilterText] = useState(""); const [errorsOnly, setErrorsOnly] = useState(false); - const [showDebug, setShowDebug] = useState(false); const [showDurations, setShowDurations] = useState(true); const [showQueueTime, setShowQueueTime] = useState(false); const [scale, setScale] = useState(0); const parentRef = useRef(null); const treeScrollRef = useRef(null); const timelineScrollRef = useRef(null); + const { value, replace } = useSearchParams(); + + const searchValue = value("showDebug"); + const showDebug = searchValue !== undefined ? searchValue === "true" : false; - const displayEvents = showDebug ? events : events.filter((event) => !event.data.isDebug); + const displayEvents = events; const queuedTime = showQueueTime ? undefined : queuedDuration; const { @@ -560,7 +568,11 @@ function TasksTreeView({ label="Debug" shortcut={{ modifiers: ["shift"], key: "D" }} checked={showDebug} - onCheckedChange={(e) => setShowDebug(e.valueOf())} + onCheckedChange={(checked) => { + replace({ + showDebug: checked ? "true" : "false", + }); + }} /> )} { return await startActiveSpan("getTraceSummary", async (span) => { const events = await this.taskEventStore.findTraceEvents( storeTable, traceId, startCreatedAt, - endCreatedAt + endCreatedAt, + { includeDebugLogs: options?.includeDebugLogs } ); let preparedEvents: Array = []; diff --git a/apps/webapp/app/v3/taskEventStore.server.ts b/apps/webapp/app/v3/taskEventStore.server.ts index 3426f984634..0b486d4a87d 100644 --- a/apps/webapp/app/v3/taskEventStore.server.ts +++ b/apps/webapp/app/v3/taskEventStore.server.ts @@ -1,5 +1,5 @@ // TaskEventStore.ts -import type { Prisma, TaskEvent } from "@trigger.dev/database"; +import { Prisma, TaskEvent } from "@trigger.dev/database"; import type { PrismaClient, PrismaReplicaClient } from "~/db.server"; import { env } from "~/env.server"; @@ -101,14 +101,24 @@ export class TaskEventStore { if (table === "taskEventPartitioned") { return (await this.readReplica.taskEventPartitioned.findMany({ - where: finalWhere as Prisma.TaskEventPartitionedWhereInput, + where: { + ...(finalWhere as Prisma.TaskEventPartitionedWhereInput), + kind: { + not: "LOG", + }, + }, select, orderBy, })) as Prisma.TaskEventGetPayload<{ select: TSelect }>[]; } else { // When partitioning is not enabled, we ignore the createdAt range. return (await this.readReplica.taskEvent.findMany({ - where, + where: { + ...(finalWhere as Prisma.TaskEventWhereInput), + kind: { + not: "LOG", + }, + }, select, orderBy, })) as Prisma.TaskEventGetPayload<{ select: TSelect }>[]; @@ -119,8 +129,12 @@ export class TaskEventStore { table: TaskEventStoreTable, traceId: string, startCreatedAt: Date, - endCreatedAt?: Date + endCreatedAt?: Date, + options?: { includeDebugLogs?: boolean } ) { + const filterDebug = + options?.includeDebugLogs === false || options?.includeDebugLogs === undefined; + if (table === "taskEventPartitioned") { return await this.readReplica.$queryRaw` SELECT @@ -147,6 +161,11 @@ export class TaskEventStore { ? new Date(endCreatedAt.getTime() + env.TASK_EVENT_PARTITIONED_WINDOW_IN_SECONDS * 1000) : new Date() ).toISOString()}::timestamp + ${ + filterDebug + ? Prisma.sql`AND \"kind\" <> CAST('LOG'::text AS "public"."TaskEventKind")` + : Prisma.empty + } ORDER BY "startTime" ASC LIMIT ${env.MAXIMUM_TRACE_SUMMARY_VIEW_COUNT} `; @@ -171,6 +190,11 @@ export class TaskEventStore { "kind" FROM "TaskEvent" WHERE "traceId" = ${traceId} + ${ + filterDebug + ? Prisma.sql`AND \"kind\" <> CAST('LOG'::text AS "public"."TaskEventKind")` + : Prisma.empty + } ORDER BY "startTime" ASC LIMIT ${env.MAXIMUM_TRACE_SUMMARY_VIEW_COUNT} `;