Skip to content

Commit

Permalink
feat: download logs (#1015)
Browse files Browse the repository at this point in the history
  • Loading branch information
RonenMars authored Feb 18, 2025
1 parent e571987 commit 32f112b
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/assets/image/icons/Download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/assets/image/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export { default as DeploymentsIcon } from "@assets/image/icons/Deployments.svg?
// Taken from: https://www.svgrepo.com/svg/450093/discord
export { default as DiscordNoColorIcon } from "@assets/image/icons/DiscordNoColor.svg?react";
export { default as DownloadDownArrowIcon } from "@assets/image/icons/DownloadDownArrow.svg?react";
// Taken from: https://fontawesome.com/icons/download?s=solid
export { default as DownloadIcon } from "@assets/image/icons/Download.svg?react";
export { default as EditIcon } from "@assets/image/icons/Edit.svg?react";
// Taken from: https://www.figma.com/design/klCZL68fUd6pw0DEu0Sj7f/Autokitteh%3A-Look-%26-Feel-design-versions?node-id=3744-126275&t=RHAsCZWKowRf5e4d-4
export { default as EventsFlag } from "@assets/image/icons/EventsFlag.svg?react";
Expand Down
99 changes: 82 additions & 17 deletions src/components/organisms/deployments/sessions/viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ReactTimeAgo from "react-time-ago";
import {
dateTimeFormat,
defaultSessionTab,
maxInt32ValueInGo,
namespaces,
sessionLogRowHeight,
sessionTabs,
Expand All @@ -26,7 +27,7 @@ import { Frame, IconSvg, Loader, LogoCatLarge, Tab } from "@components/atoms";
import { Accordion, IdCopyButton, RefreshButton } from "@components/molecules";
import { SessionsTableState } from "@components/organisms/deployments";

import { ArrowRightIcon, CircleMinusIcon, CirclePlusIcon } from "@assets/image/icons";
import { DownloadIcon, ArrowRightIcon, CircleMinusIcon, CirclePlusIcon } from "@assets/image/icons";

export const SessionViewer = () => {
const { deploymentId, projectId, sessionId } = useParams<{
Expand All @@ -48,6 +49,54 @@ export const SessionViewer = () => {
const { loading: loadingOutputs, loadLogs: loadOutputs } = useOutputsCacheStore();
const { loading: loadingActivities, loadLogs: loadActivities } = useActivitiesCacheStore();

const downloadSessionLogs = useCallback(async () => {
if (!sessionId || !sessionInfo) return;

try {
const { data: sessionLogsData } = await SessionsService.getOutputsBySessionId(
sessionId,
"",
maxInt32ValueInGo
);

if (!sessionLogsData?.logs?.length) {
addToast({
message: t("noLogsToDownload"),
type: "error",
});
return;
}

const logContent = sessionLogsData.logs
.reverse()
.map((log) => `[${log.time}]: ${log.print}`)
.join("\n");

const blob = new Blob([logContent], { type: "text/plain" });
const url = URL.createObjectURL(blob);

const dateTime = moment().local().format(dateTimeFormat);

const fileName = `${sessionInfo.sourceType?.toLowerCase() || "session"}-${dateTime}.log`;

const link = Object.assign(document.createElement("a"), {
href: url,
download: fileName,
});

document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
} catch (error) {
LoggerService.error(namespaces.ui.sessionsViewer, t("errorDownloadingLogsExtended", { error }));
addToast({
message: t("errorDownloadingLogs"),
type: "error",
});
}
}, [sessionId, sessionInfo, addToast, t]);

const closeEditor = useCallback(() => {
if (deploymentId) {
navigate(`/projects/${projectId}/deployments/${deploymentId}/sessions`);
Expand All @@ -74,6 +123,7 @@ export const SessionViewer = () => {
return;
}
setSessionInfo(sessionInfoResponse);

if (isInitialLoad) {
setIsInitialLoad(false);
}
Expand Down Expand Up @@ -155,7 +205,7 @@ export const SessionViewer = () => {
<Loader size="xl" />
) : (
<Frame className="overflow-y-auto overflow-x-hidden rounded-l-none pb-3 font-fira-code">
<div className="flex items-center justify-end border-b border-gray-950 pb-3.5">
<div className="flex items-center justify-end gap-2 border-b border-gray-950 pb-3.5">
<RefreshButton disabled={!isRefreshButtonDisabled} isLoading={isLoading} onRefresh={fetchSessions} />
</div>

Expand Down Expand Up @@ -223,23 +273,38 @@ export const SessionViewer = () => {
</div>
</div>

{sessionInfo.inputs ? (
<div className="mt-3 border-b border-gray-950 pb-3.5">
<Accordion
classChildren="border-none pt-3 pb-0"
classIcon="fill-none group-hover:fill-none group-hover:stroke-green-800 stroke-white size-5 mb-0.5"
closeIcon={CircleMinusIcon}
openIcon={CirclePlusIcon}
title="Inputs"
<div className="flex items-start justify-between border-b border-gray-950">
<div className="flex-1">
{sessionInfo.inputs ? (
<div className="mt-3 max-w-[80%] pb-3.5">
<Accordion
classChildren="border-none pt-3 pb-0"
classIcon="fill-none group-hover:fill-none group-hover:stroke-green-800 stroke-white size-5 mb-0.5"
closeIcon={CircleMinusIcon}
openIcon={CirclePlusIcon}
title="Inputs"
>
<JsonView
className="scrollbar max-h-72 overflow-auto"
style={githubDarkTheme}
value={sessionInfo.inputs}
/>
</Accordion>
</div>
) : null}
</div>

<div className="mt-3 ">
<button
className="group flex items-center gap-2.5 px-4 py-2 text-white disabled:cursor-not-allowed disabled:opacity-50"
disabled={isLoading}
onClick={downloadSessionLogs}
>
<JsonView
className="scrollbar max-h-72 overflow-auto"
style={githubDarkTheme}
value={sessionInfo.inputs}
/>
</Accordion>
<IconSvg className="fill-white group-hover:fill-green-800" size="md" src={DownloadIcon} />
{t("downloadLogs")}
</button>
</div>
) : null}
</div>

<div className="flex items-center justify-between">
<div className="scrollbar my-5 flex items-center gap-2 overflow-x-auto overflow-y-hidden whitespace-nowrap uppercase xl:gap-4 2xl:gap-6">
Expand Down
1 change: 1 addition & 0 deletions src/constants/global.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export const supportedProgrammingLanguages = [".py", ".star"];
export const allowedManualRunExtensions = ["python", "starlark"];
export const AKRoutes = isProduction ? Sentry.withSentryReactRouterV7Routing(Routes) : Routes;
export const sentryDsn = import.meta.env.SENTRY_DSN;
export const maxInt32ValueInGo = 2147483647;
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export {
hubSpotId,
hubSpotFormId,
sentryDsn,
maxInt32ValueInGo,
} from "@constants/global.constants";
export { integrationToEditComponent } from "@constants/connections/editComponentsMapping.constants";
export { formsPerIntegrationsMapping } from "@constants/connections/formsPerIntegrationsMapping.constants";
Expand Down
4 changes: 4 additions & 0 deletions src/locales/en/deployments/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@
"buttons":{
"ariaCloseEditor": "Close session log viewer"
},
"downloadLogs": "Logs",
"errorDownloadingLogs": "Error downloading logs",
"errorDownloadingLogsExtended": "Error downloading logs, error: {{error}}",
"noLogsToDownload": "No logs to download",
"trigger": "Trigger",
"source": "Source",
"sourceType": "Source Type",
Expand Down

0 comments on commit 32f112b

Please sign in to comment.