mirror of
https://github.com/smartyellow/status.git
synced 2025-01-18 21:47:58 +00:00
Basic cluster functionality
Signed-off-by: Romein van Buren <romein@vburen.nl>
This commit is contained in:
parent
aace2dd2de
commit
b626f23792
@ -9,7 +9,7 @@ const { default: resolve } = require('@rollup/plugin-node-resolve');
|
|||||||
const svelte = require('rollup-plugin-svelte');
|
const svelte = require('rollup-plugin-svelte');
|
||||||
const { terser } = require('rollup-plugin-terser');
|
const { terser } = require('rollup-plugin-terser');
|
||||||
|
|
||||||
async function build(server) {
|
async function build({ server, settings }) {
|
||||||
const serverDomain = server.settings.domain || 'localhost';
|
const serverDomain = server.settings.domain || 'localhost';
|
||||||
const serverPort = server.settings.port || 80;
|
const serverPort = server.settings.port || 80;
|
||||||
const serverBase = `${serverDomain}:${serverPort}`;
|
const serverBase = `${serverDomain}:${serverPort}`;
|
||||||
@ -49,6 +49,7 @@ async function build(server) {
|
|||||||
preventAssignment: false,
|
preventAssignment: false,
|
||||||
values: {
|
values: {
|
||||||
'__SERVER__': serverBase,
|
'__SERVER__': serverBase,
|
||||||
|
'__CLUSTERS__': JSON.stringify(settings.clusters),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -62,6 +63,7 @@ async function build(server) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
map: output[0].map.toUrl(),
|
||||||
code: output[0].code,
|
code: output[0].code,
|
||||||
css: cssOutput.css,
|
css: cssOutput.css,
|
||||||
};
|
};
|
||||||
|
@ -10,10 +10,15 @@ async function createDashboardSocket(server) {
|
|||||||
route: '/statusdashboard/socket',
|
route: '/statusdashboard/socket',
|
||||||
onOpen: async ws => {
|
onOpen: async ws => {
|
||||||
function sendTime() {
|
function sendTime() {
|
||||||
ws.send(JSON.stringify({
|
try {
|
||||||
cmd: 'time',
|
ws.send(JSON.stringify({
|
||||||
time: new Date().getTime(),
|
cmd: 'time',
|
||||||
}));
|
time: new Date().getTime(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTime();
|
sendTime();
|
||||||
@ -36,13 +41,19 @@ async function createDashboardSocket(server) {
|
|||||||
mappedServices[s.id] = {
|
mappedServices[s.id] = {
|
||||||
name: s.name,
|
name: s.name,
|
||||||
lastBeat: lastBeat || {},
|
lastBeat: lastBeat || {},
|
||||||
|
cluster: s.cluster,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
try {
|
||||||
cmd: 'data',
|
ws.send(JSON.stringify({
|
||||||
data: mappedServices,
|
cmd: 'data',
|
||||||
}));
|
data: mappedServices,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendStatuses();
|
sendStatuses();
|
||||||
@ -51,7 +62,6 @@ async function createDashboardSocket(server) {
|
|||||||
onUpgrade: async () => ({ id: makeId(10) }),
|
onUpgrade: async () => ({ id: makeId(10) }),
|
||||||
onMessage: async (ws, msg) => {
|
onMessage: async (ws, msg) => {
|
||||||
msg = JSON.parse(decoder.decode(msg));
|
msg = JSON.parse(decoder.decode(msg));
|
||||||
console.log('msg', msg);
|
|
||||||
|
|
||||||
if (!msg || !msg.command) {
|
if (!msg || !msg.command) {
|
||||||
return;
|
return;
|
||||||
|
@ -24,6 +24,7 @@ module.exports = {
|
|||||||
'name',
|
'name',
|
||||||
'state',
|
'state',
|
||||||
'public',
|
'public',
|
||||||
|
'cluster',
|
||||||
'tags',
|
'tags',
|
||||||
'channels',
|
'channels',
|
||||||
],
|
],
|
||||||
@ -95,6 +96,18 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cluster: {
|
||||||
|
label: 'cluster',
|
||||||
|
fields: [
|
||||||
|
{ key: 'cluster',
|
||||||
|
editor: 'select',
|
||||||
|
placeholder: 'select a cluster for this service...',
|
||||||
|
visible: !!(settings.clusters && Object.keys(settings.clusters).length),
|
||||||
|
options: settings.clusters,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
tags: {
|
tags: {
|
||||||
label: 'tags',
|
label: 'tags',
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -10,7 +10,13 @@
|
|||||||
let servicesUp = {};
|
let servicesUp = {};
|
||||||
let servicesDown = {};
|
let servicesDown = {};
|
||||||
let servicesUnknown = {};
|
let servicesUnknown = {};
|
||||||
|
let servicesInCluster = {};
|
||||||
|
let servicesInClusterUnknown = {};
|
||||||
|
const clusters = JSON.parse('__CLUSTERS__');
|
||||||
|
const clusterKeys = clusters ? Object.keys(clusters) : false;
|
||||||
|
let currentClusterIndex = -1;
|
||||||
let loading = true;
|
let loading = true;
|
||||||
|
let lock = false;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const ws = new WebSocket('ws://__SERVER__/statusdashboard/socket');
|
const ws = new WebSocket('ws://__SERVER__/statusdashboard/socket');
|
||||||
@ -27,6 +33,8 @@
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'data':
|
case 'data':
|
||||||
|
while (lock) {}
|
||||||
|
|
||||||
services = data.data;
|
services = data.data;
|
||||||
const ids = Object.keys(services);
|
const ids = Object.keys(services);
|
||||||
|
|
||||||
@ -60,6 +68,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$: if (clusterKeys?.length && !loading) {
|
||||||
|
function nextCluster() {
|
||||||
|
lock = true;
|
||||||
|
currentClusterIndex++;
|
||||||
|
|
||||||
|
if (currentClusterIndex >= clusterKeys.length) {
|
||||||
|
currentClusterIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inClusterTemp = {};
|
||||||
|
const inClusterTempUnknown = {};
|
||||||
|
const currentClusterKey = clusterKeys[currentClusterIndex];
|
||||||
|
|
||||||
|
for (const [ id, s ] of Object.entries(services)) {
|
||||||
|
if (s.cluster === currentClusterKey) {
|
||||||
|
if (!s.lastBeat || !s.lastBeat.date) {
|
||||||
|
inClusterTempUnknown[id] = s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inClusterTemp[id] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
servicesInCluster = inClusterTemp;
|
||||||
|
servicesInClusterUnknown = inClusterTempUnknown;
|
||||||
|
lock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCluster();
|
||||||
|
setInterval(() => nextCluster, 10_000);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Settings />
|
<Settings />
|
||||||
@ -71,8 +112,14 @@
|
|||||||
|
|
||||||
{#if !loading}
|
{#if !loading}
|
||||||
<Tiles services={servicesDown} color="red" value="down" />
|
<Tiles services={servicesDown} color="red" value="down" />
|
||||||
<Tiles services={servicesUp} color="green" value="up" />
|
|
||||||
<Tiles services={servicesUnknown} color="grey" value="no data" />
|
{#if !clusterKeys?.length}
|
||||||
|
<Tiles services={servicesUp} color="green" value="up" />
|
||||||
|
<Tiles services={servicesUnknown} color="grey" value="no data" />
|
||||||
|
{:else}
|
||||||
|
<Tiles services={servicesInCluster} color="green" value="up" />
|
||||||
|
<Tiles services={servicesInClusterUnknown} color="grey" value="no data" />
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
loading
|
loading
|
||||||
{/if}
|
{/if}
|
||||||
|
45
index.js
45
index.js
@ -85,17 +85,11 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
settings: {
|
settings: {
|
||||||
emailSender: {
|
clusters: {
|
||||||
type: 'string',
|
type: 'keys',
|
||||||
label: 'notification sender',
|
label: 'clusters',
|
||||||
description: 'Sender of notifications about service statuses. Format: Name <email@example.com>',
|
description: 'Clusters can be used to catogorise web services into groups.',
|
||||||
default: '',
|
default: {},
|
||||||
},
|
|
||||||
emailRecipient: {
|
|
||||||
type: 'array',
|
|
||||||
label: 'notification recipients',
|
|
||||||
description: 'Recipients of notifications about service statuses. Format: Name <email@example.com>',
|
|
||||||
default: [],
|
|
||||||
},
|
},
|
||||||
serviceTags: {
|
serviceTags: {
|
||||||
type: 'keys',
|
type: 'keys',
|
||||||
@ -109,10 +103,22 @@ module.exports = {
|
|||||||
description: 'Tags that can be assigned to outage messages to categorise them.',
|
description: 'Tags that can be assigned to outage messages to categorise them.',
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
|
emailSender: {
|
||||||
|
type: 'string',
|
||||||
|
label: 'notification sender',
|
||||||
|
description: 'Sender of notifications about service statuses. Format: Name <email@example.com>',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
emailRecipient: {
|
||||||
|
type: 'array',
|
||||||
|
label: 'notification recipients',
|
||||||
|
description: 'Recipients of notifications about service statuses. Format: Name <email@example.com>',
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
draftOutageEntries: {
|
draftOutageEntries: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
label: 'draft outage entries',
|
label: 'draft outage entries',
|
||||||
description: 'Automatically draft outage entry when a service is down.',
|
description: 'Automatically draft an outage entry when a service is down?',
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -200,10 +206,8 @@ module.exports = {
|
|||||||
{ id: 'startDashboardSocket',
|
{ id: 'startDashboardSocket',
|
||||||
event: 'boot',
|
event: 'boot',
|
||||||
order: 100,
|
order: 100,
|
||||||
purpose: 'Start the websocket for the dashboard after server has booted',
|
purpose: 'Start the websocket for the dashboard after boot',
|
||||||
handler: async ({ server }) => {
|
handler: () => createDashboardSocket(server),
|
||||||
createDashboardSocket(server);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{ id: 'autotestOnSave',
|
{ id: 'autotestOnSave',
|
||||||
@ -232,7 +236,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
routes: ({ server }) => [
|
routes: ({ server, settings }) => [
|
||||||
|
|
||||||
// Get all services
|
// Get all services
|
||||||
{ route: '/webservices',
|
{ route: '/webservices',
|
||||||
@ -533,7 +537,7 @@ module.exports = {
|
|||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
try {
|
try {
|
||||||
if (!renderedDashboard) {
|
if (!renderedDashboard) {
|
||||||
renderedDashboard = await buildDashboard(server);
|
renderedDashboard = await buildDashboard({ server, settings });
|
||||||
renderedDashboard.globalCss = await readFile(
|
renderedDashboard.globalCss = await readFile(
|
||||||
__dirname + '/gui/dashboard/app.css'
|
__dirname + '/gui/dashboard/app.css'
|
||||||
);
|
);
|
||||||
@ -550,7 +554,10 @@ module.exports = {
|
|||||||
<style>${renderedDashboard.css || ''}</style>
|
<style>${renderedDashboard.css || ''}</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>${renderedDashboard.code || ''}</script>
|
<script>
|
||||||
|
${renderedDashboard.code || ''}
|
||||||
|
//# sourceMappingURL=${renderedDashboard.map || ''}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`);
|
`);
|
||||||
|
Loading…
Reference in New Issue
Block a user