Skip to content

Commit

Permalink
Monitor ws endpoints with script execution (#191)
Browse files Browse the repository at this point in the history
* xcm ws endpoints monitor script

* add workflow

* fix workflow

* add build step

* fix build misplacement

* remove include test chains param
  • Loading branch information
mmaurello authored Jan 23, 2024
1 parent 9257ddb commit fc7505e
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 8 deletions.
25 changes: 23 additions & 2 deletions .github/workflows/xcm-wss-endpoints-monitor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,32 @@ name: XCM WS endpoints monitor

on:
workflow_dispatch:
schedule:
# Runs every 30 minutes
- cron: '*/30 * * * *'

jobs:
run_script:
runs-on: ubuntu-latest

steps:
- name: hello world
run: echo "Hello World!"
- name: 🤘 checkout
uses: actions/checkout@v3

- name: ⚙️ Setup Node.js environment
uses: actions/[email protected]
with:
node-version: 18.x
cache: 'npm'

- name: Update npm
run: npm i -g npm@9

- name: ⬇️ install
run: npm ci --ignore-scripts

- name: 🛠️ Build
run: npm run build

- name: 💻 Run script
run: npx bun ./scripts/check-websockets.ts --slack-wh=${{ secrets.SLACK_WEBHOOK_URL }}
84 changes: 78 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"devDependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.2",
"@slack/webhook": "^7.0.2",
"@types/jest": "^29.5.3",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
Expand Down
100 changes: 100 additions & 0 deletions scripts/check-websockets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-console */
import { chainsList } from '@moonbeam-network/xcm-config';
import { IncomingWebhook } from '@slack/webhook';
import WebSocket from 'ws';

function procesArgs() {
const args = process.argv;
const incudeTestChains = args.some((arg) => arg === '--include-test-chains');
const slackWebhookArg = args.find((arg) => arg.startsWith('--slack-wh='));
const webhookUrl = slackWebhookArg ? slackWebhookArg.split('=')[1] : '';
return { incudeTestChains, webhookUrl };
}

async function checkWebSocketEndpoints(
endpoints: ChainEndpoint[],
): Promise<{ endpoint: ChainEndpoint; isAlive: boolean }[]> {
async function checkIsWebSocketAlive({
chainKey,
ws: endpoint,
}: ChainEndpoint): Promise<boolean> {
return new Promise((resolve) => {
const ws = new WebSocket(endpoint);

let isAlive = false;

ws.on('error', (error) => {
console.error(
`WebSocket ${chainKey} connection to ${endpoint} failed. Error: ${error.message}`,
);
resolve(false);
});

ws.on('open', () => {
console.log(
`WebSocket ${chainKey} connection to ${endpoint} successful.`,
);
isAlive = true;
ws.terminate();
});

ws.on('close', () => {
resolve(isAlive);
});
});
}

return Promise.all(
endpoints.map(async (endpoint) => {
const isAlive = await checkIsWebSocketAlive(endpoint);

return { endpoint, isAlive };
}),
);
}

const { incudeTestChains, webhookUrl } = procesArgs();

const webhook = new IncomingWebhook(webhookUrl);

interface ChainEndpoint {
chainKey: string;
ws: string;
}

const filteredChainList = incudeTestChains
? chainsList
: chainsList.filter((chain) => !chain.isTestChain);

const websocketEndpoints = filteredChainList.map(({ key, ws }) => ({
chainKey: key,
ws,
}));

if (incudeTestChains) {
console.log('Checking the endpoints of all chains, including test chains...');
}

checkWebSocketEndpoints(websocketEndpoints).then(async (results) => {
let output = '';

results.forEach(({ isAlive, endpoint: { chainKey, ws } }) => {
if (!isAlive) {
output += `\n${chainKey}: \`${ws}\`,`;
}
});

if (output) {
const text = `The following websocket endpoints from the XCM integrations in the dapp are not working, please review them: ${output}`;

console.log(text);
if (webhookUrl) {
await webhook.send({
text,
});
} else {
console.warn('Slack webhook not detected, notification not sent');
}
}
});

0 comments on commit fc7505e

Please sign in to comment.