@hyperwatch/hyperwatch 4.0.0 → 4.2.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/package.json +19 -19
- package/src/lib/formatter.js +2 -2
- package/src/modules/identity.js +29 -0
- package/src/input/vercel.js +0 -81
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperwatch/hyperwatch",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Open Source HTTP Traffic Manager",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "François Hodierne <francois@hodierne.net>",
|
|
@@ -20,47 +20,47 @@
|
|
|
20
20
|
"depcheck": "depcheck",
|
|
21
21
|
"lint": "eslint '**/*.js'",
|
|
22
22
|
"lint:fix": "eslint '**/*.js' --fix",
|
|
23
|
-
"start": "node start",
|
|
24
|
-
"test": "mocha --recursive",
|
|
25
23
|
"prettier": "prettier \"**/*.@(js|json|md|yml)\"",
|
|
26
24
|
"prettier:check": "npm run prettier -- --list-different",
|
|
27
|
-
"prettier:write": "npm run prettier -- --write"
|
|
25
|
+
"prettier:write": "npm run prettier -- --write",
|
|
26
|
+
"start": "node start",
|
|
27
|
+
"test": "mocha --recursive"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@hyperwatch/useragent": "^3.9.
|
|
30
|
+
"@hyperwatch/useragent": "^3.9.3",
|
|
31
31
|
"accept-language-parser": "^1.5.0",
|
|
32
|
-
"ajv": "^8.
|
|
32
|
+
"ajv": "^8.12.0",
|
|
33
33
|
"ajv-formats": "^2.1.1",
|
|
34
34
|
"chalk": "^4.1.0",
|
|
35
35
|
"country-code-emoji": "^2.3.0",
|
|
36
36
|
"debug": "^4.3.4",
|
|
37
|
-
"dnsbl": "^4.0.
|
|
37
|
+
"dnsbl": "^4.0.1",
|
|
38
38
|
"express": "^4.18.2",
|
|
39
39
|
"express-ws": "^5.0.2",
|
|
40
|
-
"geoip-lite": "^1.4.
|
|
41
|
-
"immutable": "^4.
|
|
42
|
-
"ip-cidr": "^3.0
|
|
40
|
+
"geoip-lite": "^1.4.8",
|
|
41
|
+
"immutable": "^4.3.4",
|
|
42
|
+
"ip-cidr": "^3.1.0",
|
|
43
43
|
"lodash": "^4.17.21",
|
|
44
44
|
"lru-cache": "^10.0.1",
|
|
45
45
|
"micro-strptime": "^0.2.3",
|
|
46
46
|
"proxy-addr": "^2.0.7",
|
|
47
47
|
"rc": "^1.2.8",
|
|
48
48
|
"syslog-parse": "^1.3.1",
|
|
49
|
-
"tail": "^2.2.
|
|
50
|
-
"uuid": "^9.0.
|
|
51
|
-
"ws": "^8.
|
|
49
|
+
"tail": "^2.2.6",
|
|
50
|
+
"uuid": "^9.0.1",
|
|
51
|
+
"ws": "^8.14.2"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"depcheck": "^1.4.
|
|
55
|
-
"eslint": "^8.
|
|
56
|
-
"eslint-plugin-import": "^2.
|
|
54
|
+
"depcheck": "^1.4.7",
|
|
55
|
+
"eslint": "^8.53.0",
|
|
56
|
+
"eslint-plugin-import": "^2.29.0",
|
|
57
57
|
"eslint-plugin-node": "^11.1.0",
|
|
58
58
|
"husky": "^4.3.5",
|
|
59
59
|
"lint-staged": "^10.5.3",
|
|
60
|
-
"mocha": "^10.
|
|
60
|
+
"mocha": "^10.2.0",
|
|
61
61
|
"node-fetch": "^2.0.0",
|
|
62
|
-
"prettier": "^3.
|
|
63
|
-
"prettier-package-json": "^2.
|
|
62
|
+
"prettier": "^3.3.3",
|
|
63
|
+
"prettier-package-json": "^2.8.0"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=14.0"
|
package/src/lib/formatter.js
CHANGED
|
@@ -34,8 +34,8 @@ const executionTime = (log, output) => {
|
|
|
34
34
|
return log.get('executionTime') <= 100
|
|
35
35
|
? colorize('green', `${log.get('executionTime')}ms`, output)
|
|
36
36
|
: log.get('executionTime') >= 1000
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
? colorize('red', `${log.get('executionTime')}ms`, output)
|
|
38
|
+
: colorize('yellow', `${log.get('executionTime')}ms`, output);
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
const identity = (log) => log.getIn(['identity'], '');
|
package/src/modules/identity.js
CHANGED
|
@@ -229,6 +229,28 @@ function augment(log) {
|
|
|
229
229
|
return address && new IPCIDR('203.133.160.0/19').contains(address)
|
|
230
230
|
? log.set('identity', family)
|
|
231
231
|
: log;
|
|
232
|
+
case 'OAI-SearchBot':
|
|
233
|
+
// https://openai.com/searchbot.json
|
|
234
|
+
return address &&
|
|
235
|
+
(new IPCIDR('20.42.10.176/28').contains(address) ||
|
|
236
|
+
new IPCIDR('172.203.190.128/28').contains(address) ||
|
|
237
|
+
new IPCIDR('51.8.102.0/24').contains(address))
|
|
238
|
+
? log.set('identity', 'OpenAI SearchBot')
|
|
239
|
+
: log;
|
|
240
|
+
case 'GPTBot':
|
|
241
|
+
// https://openai.com/gptbot.json
|
|
242
|
+
return address &&
|
|
243
|
+
(new IPCIDR('52.230.152.0/24').contains(address) ||
|
|
244
|
+
new IPCIDR('52.233.106.0/24').contains(address) ||
|
|
245
|
+
new IPCIDR('20.171.206.0/24').contains(address) ||
|
|
246
|
+
new IPCIDR('20.171.207.0/24').contains(address) ||
|
|
247
|
+
new IPCIDR('4.227.36.0/25').contains(address))
|
|
248
|
+
? log.set('identity', 'OpenAI GPTBot')
|
|
249
|
+
: log;
|
|
250
|
+
case 'meta-externalagent':
|
|
251
|
+
return address && new IPCIDR('2a03:2880:f800::/48').contains(address)
|
|
252
|
+
? log.set('identity', 'Meta External Agent')
|
|
253
|
+
: log;
|
|
232
254
|
|
|
233
255
|
// EC2
|
|
234
256
|
case 'Raven':
|
|
@@ -266,6 +288,10 @@ function augment(log) {
|
|
|
266
288
|
hostname.endsWith('.eu-central-1.compute.amazonaws.com')
|
|
267
289
|
? log.set('identity', 'Wise')
|
|
268
290
|
: log;
|
|
291
|
+
case 'ClaudeBot':
|
|
292
|
+
return hostname && hostname.endsWith('.us-east-2.compute.amazonaws.com')
|
|
293
|
+
? log.set('identity', 'Claude')
|
|
294
|
+
: log;
|
|
269
295
|
|
|
270
296
|
// GCE
|
|
271
297
|
case 'VelenPublicWebCrawler':
|
|
@@ -308,6 +334,9 @@ function augment(log) {
|
|
|
308
334
|
if (hostname.endsWith('.us.archive.org')) {
|
|
309
335
|
return log.set('identity', 'Archive.org');
|
|
310
336
|
}
|
|
337
|
+
if (hostname.endsWith('.qwant.com')) {
|
|
338
|
+
return log.set('identity', 'Qwant');
|
|
339
|
+
}
|
|
311
340
|
}
|
|
312
341
|
|
|
313
342
|
// Signature
|
package/src/input/vercel.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
const crypto = require('crypto');
|
|
2
|
-
|
|
3
|
-
const { fromJS } = require('immutable');
|
|
4
|
-
|
|
5
|
-
const app = require('../app/api');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Create a log from Vercel JSON log drain format
|
|
9
|
-
*/
|
|
10
|
-
function parseVercel(request) {
|
|
11
|
-
return fromJS({
|
|
12
|
-
request: {
|
|
13
|
-
time: new Date(request.proxy.timestamp).toISOString(),
|
|
14
|
-
address: request.proxy.clientIp,
|
|
15
|
-
scheme: request.proxy.scheme,
|
|
16
|
-
method: request.proxy.method,
|
|
17
|
-
url: request.proxy.path,
|
|
18
|
-
headers: {
|
|
19
|
-
host: request.proxy.host,
|
|
20
|
-
'user-agent': request.proxy.userAgent[0],
|
|
21
|
-
},
|
|
22
|
-
captured_headers: ['host', 'user-agent'],
|
|
23
|
-
},
|
|
24
|
-
response: {
|
|
25
|
-
status: request.proxy.statusCode,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function verifySignature(req, secret) {
|
|
31
|
-
if (!req.headers['x-vercel-signature'] || !secret) {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
req.headers['x-vercel-signature'] ===
|
|
37
|
-
crypto.createHmac('sha1', secret).update(req.rawBody).digest('hex')
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function create({
|
|
42
|
-
name = 'HTTP input (Vercel JSON log drain format)',
|
|
43
|
-
path = '/input/vercel',
|
|
44
|
-
parse = parseVercel,
|
|
45
|
-
verify,
|
|
46
|
-
secret,
|
|
47
|
-
}) {
|
|
48
|
-
return {
|
|
49
|
-
name: name,
|
|
50
|
-
start: ({ success, reject, status }) => {
|
|
51
|
-
app.post(path, (req, res) => {
|
|
52
|
-
// Send back verify header (only needed to setup the drain)
|
|
53
|
-
if (verify) {
|
|
54
|
-
res.set('x-vercel-verify', verify);
|
|
55
|
-
}
|
|
56
|
-
// Verify signature
|
|
57
|
-
if (!verifySignature(req, secret)) {
|
|
58
|
-
res.statusCode = 403;
|
|
59
|
-
res.send("Signature didn't match");
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
// No extra validation before sending the response to the client
|
|
63
|
-
res.send('Ok');
|
|
64
|
-
// Processing the message(s)
|
|
65
|
-
const messages = Array.isArray(req.body) ? req.body : [req.body];
|
|
66
|
-
messages.forEach((message) => {
|
|
67
|
-
try {
|
|
68
|
-
success(parse(message));
|
|
69
|
-
} catch (err) {
|
|
70
|
-
reject(err);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
status(null, `Listening on http://__HOST__${path}`);
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
module.exports = {
|
|
80
|
-
create: create,
|
|
81
|
-
};
|