mirror of
https://github.com/moghtech/komodo.git
synced 2026-05-23 06:38:40 -05:00
customize alert thresholds
This commit is contained in:
@@ -2,6 +2,7 @@ import { Server } from "@monitor/types";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import fp from "fastify-plugin";
|
||||
import { Schema } from "mongoose";
|
||||
import { CPU_USAGE_NOTIFY_LIMIT, DISK_USAGE_NOTIFY_LIMIT, MEM_USAGE_NOTIFY_LIMIT } from "../../config";
|
||||
import model from "../../util/model";
|
||||
|
||||
const servers = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
@@ -11,6 +12,9 @@ const servers = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
enabled: { type: Boolean, default: true },
|
||||
isCore: Boolean,
|
||||
owners: { type: [String], default: [] },
|
||||
cpuAlert: { type: Number, default: CPU_USAGE_NOTIFY_LIMIT },
|
||||
memAlert: { type: Number, default: MEM_USAGE_NOTIFY_LIMIT },
|
||||
diskAlert: { type: Number, default: DISK_USAGE_NOTIFY_LIMIT },
|
||||
});
|
||||
|
||||
app.decorate("servers", model(app, "Server", schema));
|
||||
|
||||
@@ -46,19 +46,25 @@ const slackNotifier = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
servers.forEach((server) => {
|
||||
// check for out of bounds stats
|
||||
const stats = server.stats!;
|
||||
if (stats.cpu > CPU_USAGE_NOTIFY_LIMIT) {
|
||||
if (stats.cpu > (server.cpuAlert || CPU_USAGE_NOTIFY_LIMIT)) {
|
||||
// high cpu usage
|
||||
notifySlack(
|
||||
`WARNING | ${server.name} has high CPU usage.\n\nusage: ${stats.cpu}%`
|
||||
);
|
||||
}
|
||||
if (stats.mem.usedMemPercentage > MEM_USAGE_NOTIFY_LIMIT) {
|
||||
if (
|
||||
stats.mem.usedMemPercentage >
|
||||
(server.memAlert || MEM_USAGE_NOTIFY_LIMIT)
|
||||
) {
|
||||
// high memory usage
|
||||
notifySlack(
|
||||
`WARNING | ${server.name} has high memory usage.\n\nusing ${stats.mem.usedMemMb} MB of ${stats.mem.totalMemMb} MB (${stats.mem.usedMemPercentage}%)`
|
||||
);
|
||||
}
|
||||
if (stats.disk.usedPercentage > DISK_USAGE_NOTIFY_LIMIT) {
|
||||
if (
|
||||
stats.disk.usedPercentage >
|
||||
(server.diskAlert || DISK_USAGE_NOTIFY_LIMIT)
|
||||
) {
|
||||
// high disk usage
|
||||
notifySlack(
|
||||
`WARNING | ${server.name} has high disk usage.\n\nusing ${stats.disk.usedGb} GB of ${stats.disk.totalGb} GB (${stats.disk.usedPercentage}%)`
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
|
||||
<g id="cog_2_">
|
||||
<g>
|
||||
<path fill="#fceade" fill-rule="evenodd" clip-rule="evenodd" d="M19,8h-2.31c-0.14-0.46-0.33-0.89-0.56-1.3l1.7-1.7c0.39-0.39,0.39-1.02,0-1.41
|
||||
l-1.41-1.41c-0.39-0.39-1.02-0.39-1.41,0l-1.7,1.7c-0.41-0.22-0.84-0.41-1.3-0.55V1c0-0.55-0.45-1-1-1H9C8.45,0,8,0.45,8,1v2.33
|
||||
C7.52,3.47,7.06,3.67,6.63,3.91L5,2.28c-0.37-0.37-0.98-0.37-1.36,0L2.28,3.64C1.91,4.02,1.91,4.63,2.28,5l1.62,1.62
|
||||
C3.66,7.06,3.46,7.51,3.31,8H1C0.45,8,0,8.45,0,9v2c0,0.55,0.45,1,1,1h2.31c0.14,0.46,0.33,0.89,0.56,1.3L2.17,15
|
||||
c-0.39,0.39-0.39,1.02,0,1.41l1.41,1.41c0.39,0.39,1.02,0.39,1.41,0l1.7-1.7c0.41,0.22,0.84,0.41,1.3,0.55V19c0,0.55,0.45,1,1,1h2
|
||||
c0.55,0,1-0.45,1-1v-2.33c0.48-0.14,0.94-0.35,1.37-0.59L15,17.72c0.37,0.37,0.98,0.37,1.36,0l1.36-1.36
|
||||
c0.37-0.37,0.37-0.98,0-1.36l-1.62-1.62c0.24-0.43,0.45-0.89,0.6-1.38H19c0.55,0,1-0.45,1-1V9C20,8.45,19.55,8,19,8z M10,14
|
||||
c-2.21,0-4-1.79-4-4c0-2.21,1.79-4,4-4s4,1.79,4,4C14,12.21,12.21,14,10,14z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,79 @@
|
||||
import { Component } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { useTheme } from "../../../../state/ThemeProvider";
|
||||
import { combineClasses, validatePercentage } from "../../../../util/helpers";
|
||||
import Input from "../../../util/Input";
|
||||
import Flex from "../../../util/layout/Flex";
|
||||
import Grid from "../../../util/layout/Grid";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const Alerts: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { themeClass } = useTheme();
|
||||
const [alerts, setAlerts] = createStore({
|
||||
cpu: server.cpuAlert?.toString(),
|
||||
mem: server.memAlert?.toString(),
|
||||
disk: server.diskAlert?.toString(),
|
||||
});
|
||||
return (
|
||||
<Grid class={combineClasses("config-item shadow", themeClass())}>
|
||||
<h1>alerts</h1>
|
||||
<Flex justifyContent="space-between">
|
||||
<div>cpu</div>
|
||||
<Flex alignItems="center">
|
||||
<Input
|
||||
placeholder="%"
|
||||
value={alerts.cpu || server.cpuAlert?.toString()}
|
||||
onEdit={(val) => setAlerts("cpu", val)}
|
||||
onConfirm={(val) => {
|
||||
if (validatePercentage(val)) {
|
||||
setServer("cpuAlert", Number(val));
|
||||
} else {
|
||||
setAlerts("cpu", server.cpuAlert?.toString());
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex justifyContent="space-between">
|
||||
<div>mem</div>
|
||||
<Flex alignItems="center">
|
||||
<Input
|
||||
placeholder="%"
|
||||
value={alerts.mem || server.memAlert?.toString()}
|
||||
onEdit={(val) => setAlerts("mem", val)}
|
||||
onConfirm={(val) => {
|
||||
if (validatePercentage(val)) {
|
||||
setServer("memAlert", Number(val));
|
||||
} else {
|
||||
setAlerts("mem", server.memAlert?.toString());
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex justifyContent="space-between">
|
||||
<div>disk</div>
|
||||
<Flex alignItems="center">
|
||||
<Input
|
||||
placeholder="%"
|
||||
value={alerts.disk || server.diskAlert?.toString()}
|
||||
onEdit={(val) => setAlerts("disk", val)}
|
||||
onConfirm={(val) => {
|
||||
if (validatePercentage(val)) {
|
||||
setServer("diskAlert", Number(val));
|
||||
} else {
|
||||
setAlerts("disk", server.diskAlert?.toString());
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Alerts;
|
||||
@@ -4,6 +4,7 @@ import Icon from "../../../util/Icon";
|
||||
import Flex from "../../../util/layout/Flex";
|
||||
import Grid from "../../../util/layout/Grid";
|
||||
import Address from "./Address";
|
||||
import Alerts from "./Alerts";
|
||||
import Enabled from "./Enabled";
|
||||
import Networks from "./Networks";
|
||||
import { useConfig } from "./Provider";
|
||||
@@ -19,6 +20,7 @@ const Config: Component<{}> = (p) => {
|
||||
<Enabled />
|
||||
</Show>
|
||||
<Networks />
|
||||
<Alerts />
|
||||
</Grid>
|
||||
<Show when={server.updated}>
|
||||
<Flex style={{ "place-self": "center", padding: "1rem" }}>
|
||||
|
||||
@@ -40,7 +40,8 @@ export type IconType =
|
||||
| "clipboard"
|
||||
| "check"
|
||||
| "caret-right"
|
||||
| "search";
|
||||
| "search"
|
||||
| "cog";
|
||||
|
||||
const Icon: Component<{
|
||||
type: IconType;
|
||||
|
||||
@@ -99,7 +99,7 @@ export function copyToClipboard(text: string) {
|
||||
export function applyDarkTheme(element: Element) {
|
||||
element.classList.add("dark");
|
||||
for (let i = 0; i < element.children.length; i++) {
|
||||
applyDarkTheme(element.children[i])
|
||||
applyDarkTheme(element.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,4 +108,10 @@ export function removeDarkTheme(element: Element) {
|
||||
for (let i = 0; i < element.children.length; i++) {
|
||||
removeDarkTheme(element.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function validatePercentage(perc: string) {
|
||||
// validates that a string represents a percentage
|
||||
const percNum = Number(perc);
|
||||
return !isNaN(percNum) && percNum > 0 && percNum < 100;
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -51,6 +51,10 @@ export type Server = {
|
||||
enabled: boolean;
|
||||
isCore?: boolean;
|
||||
owners: string[];
|
||||
// usage stats threshold
|
||||
cpuAlert?: number; // 0 - 100
|
||||
memAlert?: number; // 0 - 100
|
||||
diskAlert?: number; // 0 - 100
|
||||
};
|
||||
|
||||
export type DockerBuildArgs = {
|
||||
|
||||
Reference in New Issue
Block a user