@nocville/npc 0.2.2 → 0.3.0
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/README.md +55 -17
- package/dist/cjs/cli.js +94 -39
- package/dist/cjs/core/base-npc.js +15 -0
- package/dist/cjs/core/config.js +19 -2
- package/dist/cjs/core/errors.js +23 -0
- package/dist/cjs/core/http.js +121 -0
- package/dist/cjs/core/pixel-art.js +110 -0
- package/dist/cjs/core/polling-npc.js +99 -14
- package/dist/cjs/core/text.js +13 -0
- package/dist/cjs/core/thresholds.js +29 -0
- package/dist/cjs/index.js +21 -2
- package/dist/cjs/npcs/agent-common/session.js +1 -0
- package/dist/cjs/npcs/agent-common/shim.js +8 -2
- package/dist/cjs/npcs/github-watcher/defaults.js +7 -1
- package/dist/cjs/npcs/github-watcher/github-api.js +82 -45
- package/dist/cjs/npcs/github-watcher/index.js +82 -36
- package/dist/cjs/npcs/internet-connectivity/checks.js +70 -67
- package/dist/cjs/npcs/internet-connectivity/defaults.js +5 -2
- package/dist/cjs/npcs/internet-connectivity/index.js +134 -131
- package/dist/cjs/npcs/log-watcher/buffer.js +61 -0
- package/dist/cjs/npcs/log-watcher/index.js +109 -103
- package/dist/cjs/npcs/log-watcher/tail.js +100 -53
- package/dist/cjs/npcs/office-characters/index.js +92 -0
- package/dist/cjs/npcs/process-watcher/index.js +60 -51
- package/dist/cjs/npcs/process-watcher/process-scanner.js +100 -68
- package/dist/cjs/npcs/receptionist/defaults.js +4 -0
- package/dist/cjs/npcs/receptionist/index.js +6 -93
- package/dist/cjs/npcs/receptionist/weather.js +42 -47
- package/dist/cjs/npcs/security/index.js +26 -0
- package/dist/cjs/npcs/system-monitor/collectors.js +66 -17
- package/dist/cjs/npcs/system-monitor/index.js +52 -28
- package/dist/cjs/npcs/web-page-watcher/basic-mode.js +30 -14
- package/dist/cjs/npcs/web-page-watcher/capture.js +23 -1
- package/dist/cjs/npcs/web-page-watcher/defaults.js +44 -2
- package/dist/cjs/npcs/web-page-watcher/index.js +119 -68
- package/dist/cjs/npcs/web-page-watcher/pixelate.js +2 -1
- package/dist/cli.js +95 -40
- package/dist/core/base-npc.d.ts +5 -0
- package/dist/core/base-npc.js +15 -0
- package/dist/core/config.d.ts +5 -0
- package/dist/core/config.js +18 -2
- package/dist/core/errors.d.ts +11 -0
- package/dist/core/errors.js +18 -0
- package/dist/core/http.d.ts +52 -0
- package/dist/core/http.js +111 -0
- package/dist/core/pixel-art.d.ts +38 -0
- package/dist/core/pixel-art.js +105 -0
- package/dist/core/polling-npc.d.ts +22 -1
- package/dist/core/polling-npc.js +98 -13
- package/dist/core/text.d.ts +6 -0
- package/dist/core/text.js +12 -0
- package/dist/core/thresholds.d.ts +9 -1
- package/dist/core/thresholds.js +27 -0
- package/dist/core/types.d.ts +5 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +6 -2
- package/dist/npcs/agent-common/session.js +1 -0
- package/dist/npcs/agent-common/shim.js +8 -2
- package/dist/npcs/github-watcher/defaults.d.ts +6 -0
- package/dist/npcs/github-watcher/defaults.js +7 -1
- package/dist/npcs/github-watcher/github-api.d.ts +21 -7
- package/dist/npcs/github-watcher/github-api.js +80 -45
- package/dist/npcs/github-watcher/index.d.ts +6 -0
- package/dist/npcs/github-watcher/index.js +83 -37
- package/dist/npcs/internet-connectivity/checks.d.ts +15 -18
- package/dist/npcs/internet-connectivity/checks.js +70 -67
- package/dist/npcs/internet-connectivity/defaults.d.ts +3 -0
- package/dist/npcs/internet-connectivity/defaults.js +5 -2
- package/dist/npcs/internet-connectivity/index.d.ts +19 -6
- package/dist/npcs/internet-connectivity/index.js +135 -133
- package/dist/npcs/log-watcher/buffer.d.ts +22 -0
- package/dist/npcs/log-watcher/buffer.js +58 -0
- package/dist/npcs/log-watcher/index.d.ts +22 -21
- package/dist/npcs/log-watcher/index.js +112 -106
- package/dist/npcs/log-watcher/tail.d.ts +23 -3
- package/dist/npcs/log-watcher/tail.js +101 -54
- package/dist/npcs/office-characters/index.d.ts +50 -0
- package/dist/npcs/office-characters/index.js +82 -0
- package/dist/npcs/process-watcher/index.d.ts +1 -1
- package/dist/npcs/process-watcher/index.js +61 -52
- package/dist/npcs/process-watcher/process-scanner.d.ts +31 -1
- package/dist/npcs/process-watcher/process-scanner.js +97 -70
- package/dist/npcs/receptionist/defaults.d.ts +4 -0
- package/dist/npcs/receptionist/defaults.js +4 -0
- package/dist/npcs/receptionist/index.d.ts +3 -12
- package/dist/npcs/receptionist/index.js +6 -93
- package/dist/npcs/receptionist/weather.d.ts +8 -6
- package/dist/npcs/receptionist/weather.js +39 -45
- package/dist/npcs/security/index.d.ts +12 -0
- package/dist/npcs/security/index.js +22 -0
- package/dist/npcs/system-monitor/collectors.d.ts +15 -3
- package/dist/npcs/system-monitor/collectors.js +64 -17
- package/dist/npcs/system-monitor/defaults.d.ts +1 -1
- package/dist/npcs/system-monitor/index.d.ts +2 -1
- package/dist/npcs/system-monitor/index.js +54 -30
- package/dist/npcs/web-page-watcher/basic-mode.d.ts +2 -2
- package/dist/npcs/web-page-watcher/basic-mode.js +30 -14
- package/dist/npcs/web-page-watcher/capture.d.ts +18 -0
- package/dist/npcs/web-page-watcher/capture.js +21 -1
- package/dist/npcs/web-page-watcher/defaults.d.ts +23 -0
- package/dist/npcs/web-page-watcher/defaults.js +41 -1
- package/dist/npcs/web-page-watcher/index.d.ts +18 -1
- package/dist/npcs/web-page-watcher/index.js +121 -70
- package/dist/npcs/web-page-watcher/pixelate.js +2 -1
- package/package.json +2 -2
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GitHubWatcherNPC = void 0;
|
|
4
4
|
const polling_npc_js_1 = require("../../core/polling-npc.js");
|
|
5
5
|
const text_js_1 = require("../../core/text.js");
|
|
6
|
+
const thresholds_js_1 = require("../../core/thresholds.js");
|
|
7
|
+
const errors_js_1 = require("../../core/errors.js");
|
|
6
8
|
const defaults_js_1 = require("./defaults.js");
|
|
7
9
|
const github_api_js_1 = require("./github-api.js");
|
|
8
10
|
const format_js_1 = require("./format.js");
|
|
@@ -15,12 +17,24 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
15
17
|
lastSeenSha = null;
|
|
16
18
|
commits = [];
|
|
17
19
|
rateRemaining = null;
|
|
20
|
+
/** While rate-limited, don't call GitHub again before this time (epoch ms). */
|
|
21
|
+
rateLimitedUntil = 0;
|
|
22
|
+
consecutiveFailures = 0;
|
|
18
23
|
newCommitPollsLeft = 0;
|
|
19
24
|
constructor(config) {
|
|
20
|
-
super({
|
|
25
|
+
super({
|
|
26
|
+
...config,
|
|
27
|
+
// Unauthenticated requests get 60/hour and 304s still count against
|
|
28
|
+
// them, so a 60s poll (plus the branch lookup) would hit the limit.
|
|
29
|
+
pollInterval: config.pollInterval ??
|
|
30
|
+
(config.token ? defaults_js_1.DEFAULTS.pollInterval : defaults_js_1.DEFAULTS.unauthenticatedPollInterval),
|
|
31
|
+
});
|
|
32
|
+
if (!(0, github_api_js_1.isValidRepo)(config.repo)) {
|
|
33
|
+
throw new errors_js_1.NpcConfigError(`--repo must look like owner/name (got "${(0, text_js_1.truncate)(config.repo, 80)}")`);
|
|
34
|
+
}
|
|
21
35
|
this.repo = config.repo;
|
|
22
|
-
this.token = config.token;
|
|
23
|
-
this.branch = config.branch;
|
|
36
|
+
this.token = config.token || undefined;
|
|
37
|
+
this.branch = config.branch?.trim() || undefined;
|
|
24
38
|
this.fetchFn = config.fetchFn;
|
|
25
39
|
}
|
|
26
40
|
get name() {
|
|
@@ -42,7 +56,8 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
42
56
|
};
|
|
43
57
|
}
|
|
44
58
|
async onStart() {
|
|
45
|
-
// Resolve the default branch once if the user didn't pin one
|
|
59
|
+
// Resolve the default branch once if the user didn't pin one (it only
|
|
60
|
+
// labels the board; the commits API already defaults to that branch).
|
|
46
61
|
if (!this.branch) {
|
|
47
62
|
const def = await (0, github_api_js_1.fetchDefaultBranch)(this.repo, {
|
|
48
63
|
token: this.token,
|
|
@@ -57,6 +72,8 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
57
72
|
await super.onStart();
|
|
58
73
|
}
|
|
59
74
|
async collect() {
|
|
75
|
+
if (Date.now() < this.rateLimitedUntil)
|
|
76
|
+
return this.rateLimited();
|
|
60
77
|
const result = await (0, github_api_js_1.fetchCommits)(this.repo, {
|
|
61
78
|
token: this.token,
|
|
62
79
|
etag: this.etag,
|
|
@@ -67,39 +84,68 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
67
84
|
});
|
|
68
85
|
if (result.rateRemaining !== null)
|
|
69
86
|
this.rateRemaining = result.rateRemaining;
|
|
70
|
-
|
|
71
|
-
|
|
87
|
+
const failure = this.classifyFailure(result);
|
|
88
|
+
if (failure)
|
|
89
|
+
return failure;
|
|
90
|
+
this.consecutiveFailures = 0;
|
|
91
|
+
if (result.notModified)
|
|
92
|
+
return this.reportIdle();
|
|
93
|
+
if (result.status === 409)
|
|
94
|
+
return this.report('healthy', 'Repository is empty');
|
|
95
|
+
this.etag = result.etag ?? this.etag;
|
|
96
|
+
if (result.commits.length === 0)
|
|
97
|
+
return this.reportIdle();
|
|
98
|
+
const fresh = (0, github_api_js_1.newCommitsSince)(result.commits, this.lastSeenSha);
|
|
99
|
+
this.commits = result.commits;
|
|
100
|
+
const seeded = this.lastSeenSha !== null;
|
|
101
|
+
this.lastSeenSha = result.commits[0].sha;
|
|
102
|
+
if (!seeded || fresh.length === 0)
|
|
103
|
+
return this.reportIdle();
|
|
104
|
+
this.newCommitPollsLeft = defaults_js_1.DEFAULTS.newCommitPolls;
|
|
105
|
+
return this.reportNewCommits(fresh);
|
|
106
|
+
}
|
|
107
|
+
/** Map an error response to a report, or null when the fetch succeeded. */
|
|
108
|
+
classifyFailure(result) {
|
|
109
|
+
const { status } = result;
|
|
110
|
+
if (status === 304 || status === 409 || (status >= 200 && status < 300))
|
|
111
|
+
return null;
|
|
112
|
+
if (status === 429 || (status === 403 && result.rateRemaining === 0)) {
|
|
113
|
+
this.rateLimitedUntil = result.rateResetAt ?? Date.now() + 15 * 60_000;
|
|
114
|
+
if (!this.token) {
|
|
115
|
+
this.logger.warn('GitHub rate limit reached; set GITHUB_TOKEN for a higher limit');
|
|
116
|
+
}
|
|
117
|
+
return this.rateLimited();
|
|
72
118
|
}
|
|
73
|
-
if (
|
|
74
|
-
return this.report('warning', '
|
|
119
|
+
if (status === 401) {
|
|
120
|
+
return this.report('warning', 'GitHub token rejected (401)', 'auth-failed');
|
|
75
121
|
}
|
|
76
|
-
if (
|
|
77
|
-
return this.report('warning',
|
|
122
|
+
if (status === 403) {
|
|
123
|
+
return this.report('warning', `Access to ${this.repo} denied (403)`, 'forbidden');
|
|
78
124
|
}
|
|
79
|
-
if (
|
|
80
|
-
|
|
125
|
+
if (status === 404) {
|
|
126
|
+
const hint = this.token ? '' : ' (private repos need GITHUB_TOKEN)';
|
|
127
|
+
return this.report('warning', `Repo not found: ${this.repo}${hint}`, 'not-found');
|
|
81
128
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (this.lastSeenSha === null) {
|
|
87
|
-
this.lastSeenSha = result.commits[0].sha;
|
|
88
|
-
return this.reportIdle();
|
|
89
|
-
}
|
|
90
|
-
if (fresh.length > 0) {
|
|
91
|
-
this.lastSeenSha = result.commits[0].sha;
|
|
92
|
-
this.newCommitPollsLeft = defaults_js_1.DEFAULTS.newCommitPolls;
|
|
93
|
-
return this.reportNewCommits(fresh);
|
|
94
|
-
}
|
|
129
|
+
// Network error, timeout or 5xx: ride out blips while there's a board to show.
|
|
130
|
+
this.consecutiveFailures++;
|
|
131
|
+
if (this.commits.length > 0 && this.consecutiveFailures < defaults_js_1.DEFAULTS.failuresBeforeWarning) {
|
|
132
|
+
return this.reportIdle();
|
|
95
133
|
}
|
|
96
|
-
|
|
134
|
+
const what = status === 0 ? 'unreachable' : `error (HTTP ${status})`;
|
|
135
|
+
return this.report('warning', `GitHub API ${what}`, 'unreachable');
|
|
136
|
+
}
|
|
137
|
+
rateLimited() {
|
|
138
|
+
const resumes = new Date(this.rateLimitedUntil).toLocaleTimeString([], {
|
|
139
|
+
hour: '2-digit',
|
|
140
|
+
minute: '2-digit',
|
|
141
|
+
});
|
|
142
|
+
return this.report('warning', `GitHub API rate-limited until ${resumes}`, 'rate-limited');
|
|
97
143
|
}
|
|
98
144
|
reportNewCommits(fresh) {
|
|
99
145
|
const newest = fresh[0];
|
|
100
146
|
const latest = `${newest.author}: ${(0, text_js_1.truncate)(newest.message, 120)} (${newest.sha.slice(0, 7)})`;
|
|
101
147
|
const message = fresh.length > 1 ? `${fresh.length} new commits — latest: ${latest}` : latest;
|
|
102
|
-
return this.report('healthy',
|
|
148
|
+
return this.report('healthy', message, 'new-commit');
|
|
103
149
|
}
|
|
104
150
|
reportIdle() {
|
|
105
151
|
if (this.newCommitPollsLeft > 0)
|
|
@@ -109,16 +155,16 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
109
155
|
const message = newest
|
|
110
156
|
? `Last: ${(0, text_js_1.truncate)(newest.message, 80)} (${(0, format_js_1.relativeTime)(newest.date)})`
|
|
111
157
|
: `Watching ${this.repo}`;
|
|
112
|
-
return this.report('healthy',
|
|
158
|
+
return this.report('healthy', message, subStatus);
|
|
113
159
|
}
|
|
114
|
-
report(status,
|
|
115
|
-
const
|
|
116
|
-
const secondsSinceLast =
|
|
117
|
-
? Math.max(0, Math.round((Date.now() -
|
|
160
|
+
report(status, message, subStatus) {
|
|
161
|
+
const newestAt = Date.parse(this.commits[0]?.date ?? '');
|
|
162
|
+
const secondsSinceLast = Number.isFinite(newestAt)
|
|
163
|
+
? Math.max(0, Math.round((Date.now() - newestAt) / 1000))
|
|
118
164
|
: 0;
|
|
119
165
|
return {
|
|
120
166
|
status,
|
|
121
|
-
mood,
|
|
167
|
+
mood: (0, thresholds_js_1.moodForStatus)(status),
|
|
122
168
|
message,
|
|
123
169
|
subStatus,
|
|
124
170
|
screenData: this.buildBoard(),
|
|
@@ -132,9 +178,9 @@ class GitHubWatcherNPC extends polling_npc_js_1.PollingNPC {
|
|
|
132
178
|
buildBoard() {
|
|
133
179
|
const now = Date.now();
|
|
134
180
|
const header = this.branch ? `${this.repo}@${this.branch}` : this.repo;
|
|
135
|
-
const values = [{ label: 'repo', value: header }];
|
|
136
|
-
for (const c of this.commits.slice(0,
|
|
137
|
-
const recent =
|
|
181
|
+
const values = [{ label: 'repo', value: (0, text_js_1.truncate)(header, 60) }];
|
|
182
|
+
for (const c of this.commits.slice(0, defaults_js_1.DEFAULTS.boardRows)) {
|
|
183
|
+
const recent = now - Date.parse(c.date) < 3600_000;
|
|
138
184
|
values.push({
|
|
139
185
|
label: c.sha.slice(0, 7),
|
|
140
186
|
value: (0, text_js_1.truncate)(`${c.author}: ${c.message}`, 60),
|
|
@@ -8,85 +8,88 @@ exports.checkHttp = checkHttp;
|
|
|
8
8
|
exports.checkLatency = checkLatency;
|
|
9
9
|
const node_dns_1 = require("node:dns");
|
|
10
10
|
const node_net_1 = __importDefault(require("node:net"));
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const http_js_1 = require("../../core/http.js");
|
|
12
|
+
function errorText(err) {
|
|
13
|
+
return err instanceof Error ? err.message : String(err);
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async function checkHttp(urls, timeout) {
|
|
30
|
-
return Promise.all(urls.map((url) => fetchSingleUrl(url, timeout)));
|
|
31
|
-
}
|
|
32
|
-
async function fetchSingleUrl(url, timeout) {
|
|
33
|
-
const controller = new AbortController();
|
|
34
|
-
const timer = setTimeout(() => controller.abort(), timeout);
|
|
35
|
-
const start = performance.now();
|
|
15
|
+
// ---------- DNS ----------
|
|
16
|
+
/**
|
|
17
|
+
* Resolve each host's A records through a dedicated resolver with a bounded
|
|
18
|
+
* timeout (the default resolver retries for tens of seconds when DNS is down).
|
|
19
|
+
*/
|
|
20
|
+
async function checkDns(hosts, timeoutMs) {
|
|
21
|
+
const resolver = new node_dns_1.promises.Resolver({
|
|
22
|
+
timeout: Math.max(250, Math.floor(timeoutMs / 2)),
|
|
23
|
+
tries: 2,
|
|
24
|
+
});
|
|
25
|
+
let timer;
|
|
26
|
+
const deadline = new Promise((resolve) => {
|
|
27
|
+
timer = setTimeout(() => resolve('timeout'), timeoutMs);
|
|
28
|
+
});
|
|
36
29
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
url,
|
|
50
|
-
ok: false,
|
|
51
|
-
timeMs: performance.now() - start,
|
|
52
|
-
error: err instanceof Error ? err.message : String(err),
|
|
53
|
-
};
|
|
30
|
+
return await Promise.all(hosts.map(async (host) => {
|
|
31
|
+
const start = performance.now();
|
|
32
|
+
try {
|
|
33
|
+
const outcome = await Promise.race([resolver.resolve4(host), deadline]);
|
|
34
|
+
if (outcome === 'timeout')
|
|
35
|
+
return { target: host, ok: false, timeMs: 0, error: 'timeout' };
|
|
36
|
+
return { target: host, ok: true, timeMs: performance.now() - start };
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
return { target: host, ok: false, timeMs: 0, error: errorText(err) };
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
54
42
|
}
|
|
55
43
|
finally {
|
|
56
44
|
clearTimeout(timer);
|
|
45
|
+
resolver.cancel();
|
|
57
46
|
}
|
|
58
47
|
}
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
// ---------- HTTP ----------
|
|
49
|
+
/**
|
|
50
|
+
* Time to response headers for each URL. The body is discarded unread, so a
|
|
51
|
+
* large or endless response costs nothing. Only 2xx counts as reachable.
|
|
52
|
+
*/
|
|
53
|
+
async function checkHttp(urls, timeoutMs) {
|
|
54
|
+
return Promise.all(urls.map(async (url) => {
|
|
55
|
+
const target = (0, http_js_1.displayUrl)(url); // never echo credentials or query tokens
|
|
56
|
+
const start = performance.now();
|
|
57
|
+
try {
|
|
58
|
+
const res = await fetch(url, {
|
|
59
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
60
|
+
headers: { 'User-Agent': http_js_1.NPC_USER_AGENT },
|
|
61
|
+
});
|
|
62
|
+
const timeMs = performance.now() - start;
|
|
63
|
+
await (0, http_js_1.discardBody)(res);
|
|
64
|
+
return res.ok
|
|
65
|
+
? { target, ok: true, timeMs }
|
|
66
|
+
: { target, ok: false, timeMs: 0, error: `HTTP ${res.status}` };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
return { target, ok: false, timeMs: 0, error: errorText(err) };
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
// ---------- Latency (TCP connect) ----------
|
|
74
|
+
/** Time to establish a TCP connection to each host:port. */
|
|
75
|
+
async function checkLatency(hosts, timeoutMs) {
|
|
76
|
+
return Promise.all(hosts.map((h) => measureTcpConnect(h, timeoutMs)));
|
|
61
77
|
}
|
|
62
|
-
function measureTcpConnect(target) {
|
|
78
|
+
function measureTcpConnect(target, timeoutMs) {
|
|
79
|
+
const label = target.host.includes(':')
|
|
80
|
+
? `[${target.host}]:${target.port}`
|
|
81
|
+
: `${target.host}:${target.port}`;
|
|
63
82
|
return new Promise((resolve) => {
|
|
64
83
|
const start = performance.now();
|
|
65
84
|
const socket = node_net_1.default.connect({ host: target.host, port: target.port });
|
|
66
|
-
const
|
|
85
|
+
const finish = (result) => {
|
|
86
|
+
clearTimeout(timer);
|
|
67
87
|
socket.destroy();
|
|
68
|
-
resolve(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
}, 5000);
|
|
75
|
-
socket.on('connect', () => {
|
|
76
|
-
clearTimeout(timeout);
|
|
77
|
-
const timeMs = performance.now() - start;
|
|
78
|
-
socket.destroy();
|
|
79
|
-
resolve({ host: target.host, ok: true, timeMs });
|
|
80
|
-
});
|
|
81
|
-
socket.on('error', (err) => {
|
|
82
|
-
clearTimeout(timeout);
|
|
83
|
-
resolve({
|
|
84
|
-
host: target.host,
|
|
85
|
-
ok: false,
|
|
86
|
-
timeMs: performance.now() - start,
|
|
87
|
-
error: err.message,
|
|
88
|
-
});
|
|
89
|
-
});
|
|
88
|
+
resolve(result);
|
|
89
|
+
};
|
|
90
|
+
const timer = setTimeout(() => finish({ target: label, ok: false, timeMs: 0, error: 'Connection timed out' }), timeoutMs);
|
|
91
|
+
socket.once('connect', () => finish({ target: label, ok: true, timeMs: performance.now() - start }));
|
|
92
|
+
socket.once('error', (err) => finish({ target: label, ok: false, timeMs: 0, error: err.message }));
|
|
90
93
|
});
|
|
91
94
|
}
|
|
92
95
|
//# sourceMappingURL=checks.js.map
|
|
@@ -7,10 +7,13 @@ exports.DEFAULTS = {
|
|
|
7
7
|
// gstatic generate_204 is a stable, low-latency 204 endpoint used by many
|
|
8
8
|
// OSes for connectivity checks (replaces the flaky httpbin.org default).
|
|
9
9
|
httpUrls: ['https://1.1.1.1/cdn-cgi/trace', 'https://www.gstatic.com/generate_204'],
|
|
10
|
+
// 443, not 80: Google's 8.8.8.8 doesn't listen on port 80, so that default
|
|
11
|
+
// timed out on every poll and pinned the NPC at warning.
|
|
10
12
|
latencyHosts: [
|
|
11
|
-
{ host: '8.8.8.8', port:
|
|
12
|
-
{ host: '1.1.1.1', port:
|
|
13
|
+
{ host: '8.8.8.8', port: 443 },
|
|
14
|
+
{ host: '1.1.1.1', port: 443 },
|
|
13
15
|
],
|
|
16
|
+
latencyPort: 80,
|
|
14
17
|
slowThreshold: 1000, // ms
|
|
15
18
|
httpTimeout: 5000, // ms
|
|
16
19
|
thresholds: {
|