@certik/skynet 0.8.13 → 0.8.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/app.js +8 -16
- package/monitor.js +39 -120
- package/opsgenie.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.16
|
|
4
|
+
|
|
5
|
+
- Changed monitor exit behavior
|
|
6
|
+
- Improved OpsGenie message for service checks
|
|
7
|
+
|
|
8
|
+
## 0.8.15
|
|
9
|
+
|
|
10
|
+
- Fixed OpsGenie message bug
|
|
11
|
+
|
|
12
|
+
## 0.8.14
|
|
13
|
+
|
|
14
|
+
- Switched monitor to send to opsgenie only
|
|
15
|
+
|
|
3
16
|
## 0.8.13
|
|
4
17
|
|
|
5
18
|
- Added `inline.error` function to `log` library
|
package/app.js
CHANGED
|
@@ -202,8 +202,7 @@ function indexer({ name, selector, build, check, env = {}, region = "us-east-1"
|
|
|
202
202
|
bin: `${bin} check`,
|
|
203
203
|
schedule: check.schedule,
|
|
204
204
|
cpu: check.cpu || 100,
|
|
205
|
-
mem: check.mem || 100
|
|
206
|
-
hasSlack: check.slackChannel,
|
|
205
|
+
mem: check.mem || 100
|
|
207
206
|
},
|
|
208
207
|
});
|
|
209
208
|
|
|
@@ -216,8 +215,7 @@ function indexer({ name, selector, build, check, env = {}, region = "us-east-1"
|
|
|
216
215
|
type: "stateless",
|
|
217
216
|
selector,
|
|
218
217
|
check: check.func,
|
|
219
|
-
maxRetry: check.maxRetry
|
|
220
|
-
slackChannel: check.slackChannel,
|
|
218
|
+
maxRetry: check.maxRetry
|
|
221
219
|
});
|
|
222
220
|
|
|
223
221
|
monitor();
|
|
@@ -317,8 +315,7 @@ function modeIndexer({ name, selector, state, build, validate, check, env = {},
|
|
|
317
315
|
bin: `${bin} check`,
|
|
318
316
|
schedule: check.schedule,
|
|
319
317
|
cpu: check.cpu || 100,
|
|
320
|
-
mem: check.mem || 100
|
|
321
|
-
hasSlack: check.slackChannel,
|
|
318
|
+
mem: check.mem || 100
|
|
322
319
|
},
|
|
323
320
|
});
|
|
324
321
|
|
|
@@ -332,8 +329,7 @@ function modeIndexer({ name, selector, state, build, validate, check, env = {},
|
|
|
332
329
|
selector,
|
|
333
330
|
mode: true,
|
|
334
331
|
check: check.func,
|
|
335
|
-
maxRetry: check.maxRetry
|
|
336
|
-
slackChannel: check.slackChannel,
|
|
332
|
+
maxRetry: check.maxRetry
|
|
337
333
|
});
|
|
338
334
|
|
|
339
335
|
monitor();
|
|
@@ -421,8 +417,7 @@ function producer({ name, selector, produce, check, state, env = {}, region = "u
|
|
|
421
417
|
bin: `${bin} check`,
|
|
422
418
|
schedule: check.schedule,
|
|
423
419
|
cpu: check.cpu || 100,
|
|
424
|
-
mem: check.mem || 100
|
|
425
|
-
hasSlack: check.slackChannel,
|
|
420
|
+
mem: check.mem || 100
|
|
426
421
|
},
|
|
427
422
|
});
|
|
428
423
|
|
|
@@ -435,8 +430,7 @@ function producer({ name, selector, produce, check, state, env = {}, region = "u
|
|
|
435
430
|
type: "stateful",
|
|
436
431
|
selector,
|
|
437
432
|
check: check.func,
|
|
438
|
-
maxRetry: check.maxRetry
|
|
439
|
-
slackChannel: check.slackChannel,
|
|
433
|
+
maxRetry: check.maxRetry
|
|
440
434
|
});
|
|
441
435
|
|
|
442
436
|
monitor();
|
|
@@ -515,8 +509,7 @@ function consumer({ name, selector, consume, check, env = {}, region = "us-east-
|
|
|
515
509
|
bin: `${bin} check`,
|
|
516
510
|
schedule: check.schedule,
|
|
517
511
|
cpu: check.cpu || 100,
|
|
518
|
-
mem: check.mem || 100
|
|
519
|
-
hasSlack: check.slackChannel,
|
|
512
|
+
mem: check.mem || 100
|
|
520
513
|
},
|
|
521
514
|
});
|
|
522
515
|
|
|
@@ -529,8 +522,7 @@ function consumer({ name, selector, consume, check, env = {}, region = "us-east-
|
|
|
529
522
|
type: "stateless",
|
|
530
523
|
selector,
|
|
531
524
|
check: check.func,
|
|
532
|
-
maxRetry: check.maxRetry
|
|
533
|
-
slackChannel: check.slackChannel,
|
|
525
|
+
maxRetry: check.maxRetry
|
|
534
526
|
});
|
|
535
527
|
|
|
536
528
|
monitor();
|
package/monitor.js
CHANGED
|
@@ -4,9 +4,8 @@ const { getSelectorFlags, getSelectorDesc, toSelectorString } = require("./selec
|
|
|
4
4
|
const { getBinaryName } = require("./cli");
|
|
5
5
|
const { exponentialRetry } = require("./availability");
|
|
6
6
|
const { getIndexerLatestId, getIndexerValidatedId, getIndexerState } = require("./indexer");
|
|
7
|
-
const { postMessage } = require("./slack");
|
|
8
7
|
const { postGenieMessage } = require("./opsgenie");
|
|
9
|
-
const { getJobName
|
|
8
|
+
const { getJobName } = require("./deploy");
|
|
10
9
|
|
|
11
10
|
const ERROR_LEVEL = {
|
|
12
11
|
INFO: "Info",
|
|
@@ -31,70 +30,44 @@ function sortErrors(errors) {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
async function getMostRecentJobLaunch(name) {
|
|
34
|
-
|
|
33
|
+
try {
|
|
34
|
+
const jobsRes = await fetch(`http://localhost:4646/v1/jobs?prefix=${name}`);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
if (!jobsRes.ok) {
|
|
37
|
+
console.log(`[MONITOR] request local nomad API failed`);
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const jobs = await jobsRes.json();
|
|
43
|
-
|
|
44
|
-
if (jobs.length === 0) {
|
|
45
|
-
console.log(`[MONITOR] did not see any jobs prefixed with ${name}`);
|
|
46
|
-
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
49
41
|
|
|
50
|
-
|
|
51
|
-
// filter out monitor job
|
|
52
|
-
return job.ID.indexOf("-monitor") === -1 && job.Status === "dead";
|
|
53
|
-
});
|
|
42
|
+
const jobs = await jobsRes.json();
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
if (jobs.length === 0) {
|
|
45
|
+
console.log(`[MONITOR] did not see any jobs prefixed with ${name}`);
|
|
57
46
|
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
60
49
|
|
|
61
|
-
|
|
50
|
+
const recentFinishedJob = jobs.reverse().find((job) => {
|
|
51
|
+
// filter out monitor job
|
|
52
|
+
return job.ID.indexOf("-monitor") === -1 && job.Status === "dead";
|
|
53
|
+
});
|
|
62
54
|
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
if (!recentFinishedJob) {
|
|
56
|
+
console.log(`[MONITOR] did not see any dead jobs`);
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return [];
|
|
69
|
-
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
const groups = Object.keys(summary);
|
|
61
|
+
console.log("[MONITOR]", "most recent job info", recentFinishedJob.ID, recentFinishedJob.JobSummary.Summary);
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
type: ERROR_LEVEL.CRITICAL,
|
|
79
|
-
message: `The most recent launch returned non-zero exit value, please investigate`,
|
|
80
|
-
},
|
|
81
|
-
];
|
|
82
|
-
}
|
|
63
|
+
return recentFinishedJob;
|
|
64
|
+
} catch (getJobError) {
|
|
65
|
+
console.log("[MONITOR]", "cannot get most recent job", getJobError.message);
|
|
66
|
+
return null;
|
|
83
67
|
}
|
|
84
|
-
|
|
85
|
-
return [];
|
|
86
68
|
}
|
|
87
69
|
|
|
88
|
-
function createMonitor({
|
|
89
|
-
binaryName,
|
|
90
|
-
name,
|
|
91
|
-
type = "stateless",
|
|
92
|
-
mode = false,
|
|
93
|
-
slackChannel,
|
|
94
|
-
selector = {},
|
|
95
|
-
check,
|
|
96
|
-
maxRetry = 2,
|
|
97
|
-
}) {
|
|
70
|
+
function createMonitor({ binaryName, name, type = "stateless", mode = false, selector = {}, check, maxRetry = 2 }) {
|
|
98
71
|
function monitor() {
|
|
99
72
|
if (!binaryName) {
|
|
100
73
|
binaryName = getBinaryName();
|
|
@@ -171,80 +144,26 @@ ${
|
|
|
171
144
|
|
|
172
145
|
const jobName = getJobName(name, selectorFlags, mode);
|
|
173
146
|
const mostRecentJob = await getMostRecentJobLaunch(jobName);
|
|
174
|
-
const recentJobFailures = checkMostRecentJobFailures(mostRecentJob);
|
|
175
|
-
|
|
176
|
-
result = result.concat(recentJobFailures);
|
|
177
147
|
|
|
178
148
|
if (result.length > 0) {
|
|
179
149
|
console.log("Found Errors", result);
|
|
180
150
|
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
await postMessage(
|
|
184
|
-
slackChannel,
|
|
185
|
-
{
|
|
186
|
-
text: `${jobName} Monitor Errors: ${result.map((m) => m.message || m).join("\n")}`,
|
|
187
|
-
blocks: [
|
|
188
|
-
{
|
|
189
|
-
type: "header",
|
|
190
|
-
text: {
|
|
191
|
-
type: "plain_text",
|
|
192
|
-
text: `${jobName} Monitor Errors`,
|
|
193
|
-
emoji: true,
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
type: "divider",
|
|
198
|
-
},
|
|
199
|
-
...sortErrors(result)
|
|
200
|
-
.map((m) => {
|
|
201
|
-
return [
|
|
202
|
-
{
|
|
203
|
-
type: "context",
|
|
204
|
-
elements: [
|
|
205
|
-
{
|
|
206
|
-
type: "plain_text",
|
|
207
|
-
text: `${LEVEL_EMOJI[m.type || ERROR_LEVEL.CRITICAL]} ${m.type || ERROR_LEVEL.CRITICAL}`,
|
|
208
|
-
},
|
|
209
|
-
],
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
type: "section",
|
|
213
|
-
text: {
|
|
214
|
-
type: "mrkdwn",
|
|
215
|
-
text: m.message || m,
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
];
|
|
219
|
-
})
|
|
220
|
-
.flat(),
|
|
221
|
-
{
|
|
222
|
-
type: "actions",
|
|
223
|
-
elements: [
|
|
224
|
-
{
|
|
225
|
-
type: "button",
|
|
226
|
-
text: {
|
|
227
|
-
type: "plain_text",
|
|
228
|
-
text: "View Details",
|
|
229
|
-
},
|
|
230
|
-
value: "view_details",
|
|
231
|
-
url: `${await getNomadAddr(production)}/ui/jobs/${jobName}`,
|
|
232
|
-
},
|
|
233
|
-
],
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
},
|
|
237
|
-
verbose
|
|
238
|
-
);
|
|
151
|
+
if (production) {
|
|
152
|
+
const nomadAddr = process.env.SKYNET_NOMAD_PRODUCTION_ADDR;
|
|
239
153
|
|
|
240
|
-
//
|
|
154
|
+
// alert on opsgenie
|
|
241
155
|
await postGenieMessage(
|
|
242
|
-
|
|
243
|
-
|
|
156
|
+
`Failed Service Check: ${jobName}`,
|
|
157
|
+
`<p><b>Service:</b><a href="${nomadAddr}/ui/jobs/${jobName}" target="_blank">${jobName}</a></p><p><b>Issues</b></p><ul>${sortErrors(
|
|
158
|
+
result
|
|
159
|
+
)
|
|
160
|
+
.map((m) => `<li><b>${m.type}:</b> ${m.message}</li>`)
|
|
161
|
+
.join("")}</ul>`,
|
|
162
|
+
verbose
|
|
244
163
|
);
|
|
164
|
+
} else {
|
|
165
|
+
console.log("skip sending messages to opsgenie in dev env");
|
|
245
166
|
}
|
|
246
|
-
|
|
247
|
-
throw new Error(`failed due to critical errors`);
|
|
248
167
|
}
|
|
249
168
|
|
|
250
169
|
console.log(`[MONITOR] check successfully in ${Date.now() - startTime}ms`);
|
|
@@ -270,4 +189,4 @@ ${
|
|
|
270
189
|
return { monitor };
|
|
271
190
|
}
|
|
272
191
|
|
|
273
|
-
module.exports = { createMonitor, ERROR_LEVEL };
|
|
192
|
+
module.exports = { createMonitor, ERROR_LEVEL, LEVEL_EMOJI };
|
package/opsgenie.js
CHANGED