Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions apps/webapp/app/components/LogLevelTooltipInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BookOpenIcon } from "@heroicons/react/20/solid";
import { LinkButton } from "./primitives/Buttons";
import { Header3 } from "./primitives/Headers";
import { Paragraph } from "./primitives/Paragraph";

export function LogLevelTooltipInfo() {
return (
<div className="flex max-w-xs flex-col gap-4 p-1 pb-2">
<div>
<Header3>Log Levels</Header3>
<Paragraph variant="small" className="text-text-dimmed">
Structured logging helps you debug and monitor your tasks.
</Paragraph>
</div>
<div>
<div className="mb-0.5">
<Header3 className="text-blue-400">Info</Header3>
</div>
<Paragraph variant="small" className="text-text-dimmed">
General informational messages about task execution.
</Paragraph>
</div>
<div>
<div className="mb-0.5">
<Header3 className="text-warning">Warn</Header3>
</div>
<Paragraph variant="small" className="text-text-dimmed">
Warning messages indicating potential issues that don't prevent execution.
</Paragraph>
</div>
<div>
<div className="mb-0.5">
<Header3 className="text-error">Error</Header3>
</div>
<Paragraph variant="small" className="text-text-dimmed">
Error messages for failures and exceptions during task execution.
</Paragraph>
</div>
<div>
<div className="mb-0.5">
<Header3 className="text-charcoal-400">Debug</Header3>
</div>
<Paragraph variant="small" className="text-text-dimmed">
Detailed diagnostic information for development and debugging.
</Paragraph>
</div>
<div className="border-t border-charcoal-700 pt-4">
<Header3>Tracing & Spans</Header3>
<Paragraph variant="small" className="text-text-dimmed">
Automatically track the flow of your code through task triggers, attempts, and HTTP
requests. Create custom traces to monitor specific operations.
</Paragraph>
</div>
<LinkButton
to="https://trigger.dev/docs/logging#tracing-and-spans"
variant="docs/small"
LeadingIcon={BookOpenIcon}
>
Read docs
</LinkButton>
</div>
);
}
31 changes: 31 additions & 0 deletions apps/webapp/app/components/Shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,37 @@ function ShortcutContent() {
<ShortcutKey shortcut={{ key: "p" }} variant="medium/bright" />
</Shortcut>
</div>
<div className="space-y-3">
<Header3>Logs page</Header3>
<Shortcut name="Filter by task">
<ShortcutKey shortcut={{ key: "t" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Filter by run ID">
<ShortcutKey shortcut={{ key: "i" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Filter by level">
<ShortcutKey shortcut={{ key: "l" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Select log level">
<ShortcutKey shortcut={{ key: "1" }} variant="medium/bright" />
<Paragraph variant="small" className="ml-1.5">
to
</Paragraph>
<ShortcutKey shortcut={{ key: "4" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Close detail panel">
<ShortcutKey shortcut={{ key: "esc" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Details tab">
<ShortcutKey shortcut={{ key: "d" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="Run tab">
<ShortcutKey shortcut={{ key: "r" }} variant="medium/bright" />
</Shortcut>
<Shortcut name="View full run">
<ShortcutKey shortcut={{ key: "v" }} variant="medium/bright" />
</Shortcut>
</div>
<div className="space-y-3">
<Header3>Schedules page</Header3>
<Shortcut name="New schedule">
Expand Down
64 changes: 32 additions & 32 deletions apps/webapp/app/components/logs/LogDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useEnvironment } from "~/hooks/useEnvironment";
import { useOrganization } from "~/hooks/useOrganizations";
import { useProject } from "~/hooks/useProject";
import type { LogEntry } from "~/presenters/v3/LogsListPresenter.server";
import { getLevelColor, getKindColor, getKindLabel } from "~/utils/logUtils";
import { getLevelColor } from "~/utils/logUtils";
import { v3RunSpanPath, v3RunsPath, v3DeploymentVersionPath } from "~/utils/pathBuilder";
import type { loader as logDetailLoader } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.logs.$logId";
import { TaskRunStatusCombo, descriptionForTaskRunStatus } from "~/components/runs/v3/TaskRunStatus";
Expand Down Expand Up @@ -94,16 +94,34 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet
const isLoading = fetcher.state === "loading";
const log = fetcher.data ?? initialLog;

// Handle Escape key to close panel
const runPath = v3RunSpanPath(
organization,
project,
environment,
{ friendlyId: log?.runId ?? "" },
{ spanId: log?.spanId ?? "" }
);

// Handle keyboard shortcuts
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
const target = e.target as HTMLElement;
if (target && (
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA" ||
target.tagName === "SELECT" ||
target.contentEditable === "true"
)) {
return;
}

if (e.key === "Escape") {
onClose();
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [onClose]);
}, [onClose, log, runPath, isLoading]);

if (isLoading && !log) {
return (
Expand All @@ -129,36 +147,18 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet
);
}

const runPath = v3RunSpanPath(
organization,
project,
environment,
{ friendlyId: log.runId },
{ spanId: log.spanId }
);

return (
<div className="flex h-full flex-col overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between border-b border-grid-dimmed px-4 py-3">
<div className="flex items-center gap-2">
<span
className={cn(
"inline-flex items-center rounded border px-1.5 py-0.5 text-xs font-medium",
getKindColor(log.kind)
)}
>
{getKindLabel(log.kind)}
</span>
<span
className={cn(
"inline-flex items-center rounded border px-1.5 py-0.5 text-xs font-medium uppercase",
getLevelColor(log.level)
)}
>
{log.level}
</span>
</div>
<div className="flex items-center justify-between border-b border-grid-dimmed px-2 py-2">
<span
className={cn(
"inline-flex items-center rounded border px-1.5 py-0.5 text-xs font-medium uppercase tracking-wider",
getLevelColor(log.level)
)}
>
{log.level}
</span>
<Button variant="minimal/small" onClick={onClose} shortcut={{ key: "esc" }}>
<XMarkIcon className="size-5" />
</Button>
Expand All @@ -185,8 +185,8 @@ export function LogDetailView({ logId, initialLog, onClose, searchTerm }: LogDet
</TabButton>
</TabContainer>
<Link to={runPath} target="_blank" rel="noopener noreferrer">
<Button variant="secondary/small" LeadingIcon={ArrowTopRightOnSquareIcon}>
View Full Run
<Button variant="minimal/small" LeadingIcon={ArrowTopRightOnSquareIcon} shortcut={{ key: "v" }}>
View full run
</Button>
</Link>
</div>
Expand Down
Loading