CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

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