Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/src/packages/frontend/compute/log-entry.tsx
Views: 923
import { useTypedRedux } from "@cocalc/frontend/app-framework";1import { Icon, isIconName } from "@cocalc/frontend/components";2import ComputeServerTag from "@cocalc/frontend/compute/server-tag";3import type { ComputeServerEvent } from "@cocalc/util/compute/log";4import {5STATE_INFO,6spendLimitPeriod,7} from "@cocalc/util/db-schema/compute-servers";8import { capitalize, currency, plural } from "@cocalc/util/misc";910export default function LogEntry({11project_id,12event,13hideTitle,14}: {15project_id: string;16event: ComputeServerEvent;17hideTitle?: boolean;18}) {19const computeServers = useTypedRedux({ project_id }, "compute_servers");20const title = computeServers?.getIn([`${event.server_id}`, "title"]);21if (title == null) {22return null;23}24const cs = hideTitle ? <></> : <>Compute Server "{title}" - </>;25const tag = (26<ComputeServerTag27id={event.server_id}28style={{ float: "right", maxWidth: "125px" }}29/>30);3132switch (event.action) {33case "error":34return (35<>36{cs} <Error error={event.error} />37{tag}38</>39);40case "state":41if (!STATE_INFO[event.state]) {42return null;43}44const { color, icon } = STATE_INFO[event.state];45return (46<>47<span style={{ color }}>48{isIconName(icon) && <Icon name={icon} />} {capitalize(event.state)}49</span>{" "}50{cs}51{tag}52</>53);54case "configuration":55return (56<>57{cs} Configuration{" "}58{plural(Object.keys(event.changes).length, "change")} -{" "}59{changeString(event.changes)}60{tag}61</>62);63case "automatic-shutdown":64// DEPRECATED: for backward compatibility only...65return (66<>67{cs} - Automatic{" "}68{capitalize(event.automatic_shutdown?.action ?? "Stop")} {tag}69</>70);7172case "health-check-failure":73return (74<>75{cs} - Health check failure{" "}76{capitalize(event.healthCheck?.action ?? "Stop")} {tag}77</>78);7980case "idle-timeout":81return (82<>83{cs} - Idle Timeout Shutdown (inactive for at least{" "}84{event.idle_timeout} {plural(event.idle_timeout, "minute")}) {tag}85</>86);8788case "shutdown-time":89return (90<>91{cs} - Schedule Shutdown -- shutting down due to a prescheduled daily92shutdown time {tag}93</>94);95case "spend-limit":96return (97<>98{cs} - Spend Limit Shutdown (total spend during the last{" "}99{spendLimitPeriod(event.spendLimit?.hours)} hit{" "}100{currency(event.total)} which exceeded limit of{" "}101{currency(event.spendLimit?.dollars)}) {tag}102</>103);104default:105return (106<>107{cs} {JSON.stringify(event)}108{tag}109</>110);111}112}113114function changeString(changes) {115let v: string[] = [];116for (const key in changes) {117const { from, to } = changes[key];118v.push(`${key}: ${JSON.stringify(from)} → ${JSON.stringify(to)}`);119}120if (v.length == 0) {121return "(no change)";122}123return v.join("; ");124}125126export function Error({ error, style }: { error; style? }) {127return (128<div129style={{130border: "0px 5px",131display: "inline-block",132color: "white",133background: "darkred",134padding: "1px 5px",135borderRadius: "3px",136...style,137}}138>139{error}140</div>141);142}143144145