Skip to content

Commit 496b42d

Browse files
committed
Allow multiple healthchecks
1 parent 0c0b98b commit 496b42d

File tree

5 files changed

+64
-41
lines changed

5 files changed

+64
-41
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,20 @@ all channels. The `BOT_TARGET_CHANNEL_IDS` is a comma-seperated list of channel
5656

5757
The bot will always watch and reply in individual DMs.
5858

59+
See the `env.default` file for reference.
60+
5961
### Health Check
6062

6163
You can configure the bot to periodically send HTTP requests to a "health check" endpoint of your choice.
6264
You can configure the HTTP Method, URL, and provide a Bearer Token for authorization if needed.
6365
In order for the healthcheck to be enabled you MUST provide a valid URL.
6466
The method should be known by `axios`, if it is not provided, it will use the `axios` defaults.
65-
If the bearer token is not provided, it will be ignored. See the `env.default` file for reference.
67+
If the bearer token is not provided, it will be ignored.
68+
69+
The variables for `BOT_HEALTHCHECK_URLS`, `BOT_HEALTHCHECK_METHODS`, and `BOT_HEALTHCHECK_BEARER_TOKENS` are
70+
comma-seperated lists. The lists must ALL be the same length.
71+
72+
See the `env.default` file for reference.
6673

6774
# License
6875

env.default

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ BOT_PREFIX=$
44

55
BOT_TARGET_CHANNEL_IDS=
66

7-
BOT_HEALTHCHECK_URL=YOUR_OPTIONAL_HEALTHCHECK_URL_HERE
8-
BOT_HEALTHCHECK_METHOD=get
9-
BOT_HEALTHCHECK_BEARER_TOKEN=YOUR_OPTIONAL__BEARER_TOKEN_HERE
7+
BOT_HEALTHCHECK_URLS=YOUR_OPTIONAL_HEALTHCHECK_URL_HERE_1,YOUR_OPTIONAL_HEALTHCHECK_URL_HERE_2
8+
BOT_HEALTHCHECK_METHODS=get,post
9+
BOT_HEALTHCHECK_BEARER_TOKENS=YOUR_OPTIONAL_BEARER_TOKEN_HERE_1,YOUR_OPTIONAL_BEARER_TOKEN_HERE_2

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "stonk-bot",
3-
"version": "2.3.2",
3+
"version": "2.3.3",
44
"main": "index.js",
55
"license": "Apache-2.0",
66
"scripts": {

src/config.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@ export interface BotConfig {
3131
targetedChannels: ReadonlyArray<string>;
3232

3333
// Health check
34-
healthCheckUrl: string;
35-
healthCheckMethod: Method | undefined
36-
healthCheckBearerToken: string | undefined,
34+
healthCheckUrls: ReadonlyArray<string>;
35+
healthCheckMethods: ReadonlyArray<Method>;
36+
healthCheckBearerTokens: ReadonlyArray<string>;
3737
}
3838

3939
export const sourceConfig = function (): BotConfig {
4040
env.config();
4141
const rawSpecificChannel = process.env.BOT_TARGET_CHANNEL_IDS || "";
42+
const rawHealthcheckUrl = process.env.BOT_HEALTHCHECK_URLS || "";
43+
const rawHealthcheckMethod = process.env.BOT_HEALTHCHECK_METHODS || "";
44+
const rawHealthcheckBearerToken =
45+
process.env.BOT_HEALTHCHECK_BEARER_TOKENS || "";
4246
const config: BotConfig = Object.freeze({
4347
prefix: process.env.BOT_PREFIX || "$",
4448

@@ -49,9 +53,14 @@ export const sourceConfig = function (): BotConfig {
4953
.map((s) => s.trim())
5054
.filter((s) => s),
5155

52-
healthCheckUrl: process.env.BOT_HEALTHCHECK_URL || "",
53-
healthCheckMethod: process.env.BOT_HEALTHCHECK_METHOD as Method,
54-
healthCheckBearerToken: process.env.BOT_HEALTHCHECK_BEARER_TOKEN,
56+
healthCheckUrls: rawHealthcheckUrl.split(",").map((s) => s.trim()),
57+
healthCheckMethods: rawHealthcheckMethod
58+
.split(",")
59+
.map((s) => s.trim())
60+
.map((s) => s as Method),
61+
healthCheckBearerTokens: rawHealthcheckBearerToken
62+
.split(",")
63+
.map((s) => s.trim()),
5564
});
5665
logger.log("Bot Config: ", config);
5766
return config;

src/health.ts

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ const logger = newLogger("HealthCheck");
2323

2424
const fireHealthCheck = function (
2525
config: BotConfig,
26-
url: string,
27-
method: Method | undefined,
28-
bearerToken: string | undefined,
26+
urls: ReadonlyArray<string>,
27+
methods: ReadonlyArray<Method>,
28+
bearerTokens: ReadonlyArray<string>,
2929
) {
3030
// Check that AAPL returns some data.
3131
// If it does, we are live and working
@@ -42,15 +42,13 @@ const fireHealthCheck = function (
4242
oldCommand: undefined,
4343
});
4444

45-
try {
46-
let success: boolean;
47-
if (check && !check.error) {
48-
logger.log(`AAPL success, attempt healthcheck: ${url}`);
49-
success = true;
50-
} else {
51-
logger.log(`AAPL failure, attempt healthcheck: ${url}`);
52-
success = false;
53-
}
45+
const success = !!(check && !check.error);
46+
47+
const work: Promise<unknown>[] = [];
48+
for (let i = 0; i < urls.length; ++i) {
49+
const url = urls[i];
50+
const method = methods[i];
51+
const bearerToken = bearerTokens[i];
5452

5553
let headers: RawAxiosRequestHeaders | undefined = undefined;
5654
if (bearerToken) {
@@ -59,40 +57,49 @@ const fireHealthCheck = function (
5957
};
6058
}
6159

62-
await axios({
63-
// If undefined, will be axios default "get"
64-
method,
65-
headers,
66-
url: `${url}?success=${success}`,
67-
});
68-
} catch (e) {
69-
// Health check error, try again later
70-
// Maybe network is offline?
71-
logger.error(`Healthcheck failed!`, e);
60+
work.push(
61+
Promise.resolve().then(async () => {
62+
try {
63+
await axios({
64+
// If undefined, will be axios default "get"
65+
method,
66+
headers,
67+
url: `${url}?success=${success}`,
68+
});
69+
} catch (e) {
70+
// Health check error, try again later
71+
// Maybe network is offline?
72+
logger.error(`Healthcheck report failed!`, url, success, e);
73+
}
74+
}),
75+
);
7276
}
77+
78+
await Promise.all(work);
7379
});
7480
};
7581

7682
export const registerPeriodicHealthCheck = function (config: BotConfig) {
7783
let timer: NodeJS.Timeout | undefined = undefined;
7884

79-
const { healthCheckMethod, healthCheckUrl, healthCheckBearerToken } = config;
85+
const { healthCheckUrls, healthCheckMethods, healthCheckBearerTokens } =
86+
config;
8087

81-
if (healthCheckUrl) {
88+
if (healthCheckUrls.length > 0) {
8289
timer = setInterval(() => {
8390
fireHealthCheck(
8491
config,
85-
healthCheckUrl,
86-
healthCheckMethod,
87-
healthCheckBearerToken,
92+
healthCheckUrls,
93+
healthCheckMethods,
94+
healthCheckBearerTokens,
8895
);
8996
}, 60 * 1000);
9097

9198
fireHealthCheck(
9299
config,
93-
healthCheckUrl,
94-
healthCheckMethod,
95-
healthCheckBearerToken,
100+
healthCheckUrls,
101+
healthCheckMethods,
102+
healthCheckBearerTokens,
96103
);
97104
}
98105

0 commit comments

Comments
 (0)