-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbase-middleware.ts
89 lines (76 loc) · 3.34 KB
/
base-middleware.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import {Express} from 'express';
import {v4 as uuidv4} from 'uuid';
import {AppContext} from '@gravity-ui/nodekit';
import {DEFAULT_REQUEST_ID_HEADER} from './constants';
export function setupBaseMiddleware(ctx: AppContext, expressApp: Express) {
expressApp.use((req, res, next) => {
try {
req.id = (req.headers[DEFAULT_REQUEST_ID_HEADER] || uuidv4()) as string;
res.setHeader(DEFAULT_REQUEST_ID_HEADER, req.id);
res.setHeader('Surrogate-Control', 'no-store');
res.setHeader(
'Cache-Control',
'no-store, max-age=0, must-revalidate, proxy-revalidate',
);
req.routeInfo = {};
const startTime = Date.now();
const userAgent = req.get('user-agent');
const parentSpanContext = ctx.extractSpanContext(req.headers);
req.originalContext = req.ctx = ctx.create(`Express ${req.method}`, {
parentSpanContext,
loggerPostfix: `[${req.id}]`,
});
req.ctx.set('requestId', req.id);
req.ctx.setTag('http.hostname', req.hostname);
req.ctx.setTag('http.method', req.method);
req.ctx.setTag('http.url', req.url);
req.ctx.setTag('path', req.path);
req.ctx.setTag('referer', req.get('referer'));
req.ctx.setTag('remote_ip', req.ip);
req.ctx.setTag('request_id', req.id);
req.ctx.setTag('user_agent', userAgent);
const requestStartedExtra = ctx.config.appDevMode
? {url: req.url}
: {
id: req.id,
method: req.method,
url: req.url,
headers: ctx.utils.redactSensitiveKeys(req.headers),
remoteAddress: req.connection && req.connection.remoteAddress,
remotePort: req.connection && req.connection.remotePort,
};
req.ctx.log('Request started', requestStartedExtra);
res.on('finish', () => {
const statusCode = String(res.statusCode);
const responseTime = Date.now() - startTime;
const responseExtra = ctx.config.appDevMode
? {responseTime, statusCode}
: {
responseTime,
statusCode,
headers: ctx.utils.redactSensitiveKeys(res.getHeaders()),
};
if (statusCode.startsWith('5')) {
req.originalContext.logError('Request failed', null, responseExtra);
} else {
req.originalContext.log('Request completed', responseExtra);
}
req.originalContext.setTag('http.status_code', statusCode);
req.originalContext.end();
});
const traceId = req.ctx.getTraceId();
if (traceId) {
res.setHeader('x-trace-id', traceId);
}
next();
return;
} catch (error) {
ctx.logError('Error during server setup', error);
if (req.ctx) {
req.ctx.setTag('error', true);
req.ctx.end();
}
res.status(500).send('Internal server error');
}
});
}