Quiet the logs and capture the errors that were missing
- Activity page: "Delete all" empties the open tab (api/admin/logs/clear-logs, super admin only, logged under system) - Stop logging every WebSocket connect - Log unexpected API errors (safeErrorMessage -> logUnexpectedError), every failed bot job attempt and every job the queue lost - Drop the cron jobs' console output; a failed model sync goes to the logs Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import fetchApi from "@moduletrace/twui/utils/fetch/fetchApi";
|
||||
import type { APIResponseObject } from "@moduletrace/bunext/types";
|
||||
import type { ClearLogsRequest } from "@/src/schemas/log-schema";
|
||||
|
||||
type Params = {
|
||||
category?: ClearLogsRequest["category"];
|
||||
/**
|
||||
* The tab's name, for the confirmation.
|
||||
*/
|
||||
title: string;
|
||||
count?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes every log in the open tab, after asking.
|
||||
*/
|
||||
export default async function clearLogs({ category, title, count }: Params) {
|
||||
const amount = typeof count == "number" ? `${count} ` : "";
|
||||
const confirm_msg = category
|
||||
? `Delete all ${amount}${title} logs? This cannot be undone.`
|
||||
: `Delete all ${amount}logs? This cannot be undone.`;
|
||||
|
||||
if (!window.confirm(confirm_msg)) {
|
||||
return { success: false, cancelled: true };
|
||||
}
|
||||
|
||||
const res = await fetchApi<ClearLogsRequest, APIResponseObject<{ deleted: number }>>(
|
||||
`/api/admin/logs/clear-logs`,
|
||||
{ method: "POST", body: { category } },
|
||||
);
|
||||
|
||||
return {
|
||||
success: Boolean(res?.success),
|
||||
msg: res?.success ? undefined : res?.msg || `Couldn't delete logs`,
|
||||
};
|
||||
}
|
||||
@@ -78,6 +78,20 @@ export default function useLogsListInit(_props?: Props) {
|
||||
setRes(undefined);
|
||||
};
|
||||
|
||||
/**
|
||||
* The tab was emptied: back to its first page, reloaded.
|
||||
*/
|
||||
const afterClear = () => {
|
||||
setSelectedIds([]);
|
||||
|
||||
if (page > 1) {
|
||||
setPage(1);
|
||||
return;
|
||||
}
|
||||
|
||||
setRes(undefined);
|
||||
};
|
||||
|
||||
const all_selected =
|
||||
Boolean(logs?.[0]) && selected_ids.length == logs?.length;
|
||||
|
||||
@@ -100,6 +114,7 @@ export default function useLogsListInit(_props?: Props) {
|
||||
toggleSelectAll,
|
||||
all_selected,
|
||||
afterDelete,
|
||||
afterClear,
|
||||
active_log,
|
||||
openLog,
|
||||
log_modal_open,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Trash2 } from "lucide-react";
|
||||
import Button from "@moduletrace/twui/layout/Button";
|
||||
import Tag from "@moduletrace/twui/elements/Tag";
|
||||
import Row from "@moduletrace/twui/layout/Row";
|
||||
import Span from "@moduletrace/twui/layout/Span";
|
||||
import useStatus from "@moduletrace/twui/hooks/useStatus";
|
||||
import { LogCategoryFilters } from "../(data)/log-category-filters";
|
||||
import type { LogCategoryValue } from "../(data)/log-category-styles";
|
||||
import clearLogs from "../(functions)/clear-logs";
|
||||
|
||||
type Props = {
|
||||
category?: LogCategoryValue;
|
||||
count?: number;
|
||||
afterClear: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes every log in the open tab ("All" deletes every log).
|
||||
*/
|
||||
export default function ClearLogsButton({ category, count, afterClear }: Props) {
|
||||
const { loading, setLoading, status, setStatus } = useStatus();
|
||||
|
||||
const title = LogCategoryFilters.find((filter) => filter.value == category)?.title || "All";
|
||||
|
||||
const clear_logs = async () => {
|
||||
setStatus(undefined);
|
||||
setLoading(true);
|
||||
|
||||
const res = await clearLogs({ category, title, count });
|
||||
|
||||
setLoading(false);
|
||||
|
||||
if (res.success) {
|
||||
afterClear();
|
||||
} else if (res.msg) {
|
||||
setStatus({ error: true, msg: res.msg });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Row className="gap-2! flex-nowrap">
|
||||
{status?.error && <Tag color="error">{status.msg}</Tag>}
|
||||
<Button
|
||||
title={category ? `Delete all ${title} logs` : "Delete all logs"}
|
||||
variant="ghost"
|
||||
color="error"
|
||||
size="small"
|
||||
loading={loading}
|
||||
disabled={!count}
|
||||
onClick={() => {
|
||||
clear_logs();
|
||||
}}
|
||||
>
|
||||
<Row className="gap-2! flex-nowrap">
|
||||
<Trash2 size={15} />
|
||||
<Span>{category ? `Delete all ${title}` : "Delete all"}</Span>
|
||||
</Row>
|
||||
</Button>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import Row from "@moduletrace/twui/layout/Row";
|
||||
import Span from "@moduletrace/twui/layout/Span";
|
||||
import Stack from "@moduletrace/twui/layout/Stack";
|
||||
import type useLogsListInit from "../(hooks)/use-logs-list-init";
|
||||
import ClearLogsButton from "./clear-logs-button";
|
||||
import DeleteLogsButton from "./delete-logs-button";
|
||||
import LogCategoryFilter from "./log-category-filter";
|
||||
|
||||
@@ -18,6 +19,7 @@ export default function LogsToolbar({ init }: Props) {
|
||||
selectCategory,
|
||||
selected_ids,
|
||||
afterDelete,
|
||||
afterClear,
|
||||
} = init;
|
||||
|
||||
return (
|
||||
@@ -33,20 +35,27 @@ export default function LogsToolbar({ init }: Props) {
|
||||
? `${count} log${count == 1 ? "" : "s"}`
|
||||
: "--"}
|
||||
</Span>
|
||||
{selected_ids[0] ? (
|
||||
<DeleteLogsButton
|
||||
ids={selected_ids}
|
||||
afterDelete={afterDelete}
|
||||
title="Delete Selected Logs"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
>
|
||||
<Row className="gap-2! flex-nowrap">
|
||||
<Trash2 size={15} />
|
||||
<Span>Delete selected ({selected_ids.length})</Span>
|
||||
</Row>
|
||||
</DeleteLogsButton>
|
||||
) : null}
|
||||
<Row className="gap-2! flex-nowrap">
|
||||
{selected_ids[0] ? (
|
||||
<DeleteLogsButton
|
||||
ids={selected_ids}
|
||||
afterDelete={afterDelete}
|
||||
title="Delete Selected Logs"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
>
|
||||
<Row className="gap-2! flex-nowrap">
|
||||
<Trash2 size={15} />
|
||||
<Span>Delete selected ({selected_ids.length})</Span>
|
||||
</Row>
|
||||
</DeleteLogsButton>
|
||||
) : null}
|
||||
<ClearLogsButton
|
||||
category={category}
|
||||
count={count}
|
||||
afterClear={afterClear}
|
||||
/>
|
||||
</Row>
|
||||
</Row>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
Reference in New Issue
Block a user