Skip to content

Commit 0ecd384

Browse files
Merge pull request #33 from DataSeer/add_duration_http_logs
feat: add durations (ms) in HTTP logs, for grafana charts
2 parents f17a4a3 + 5cc660c commit 0ecd384

File tree

4 files changed

+29
-6
lines changed

4 files changed

+29
-6
lines changed

Diff for: package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"jsonwebtoken": "^9.0.2",
3333
"morgan": "^1.10.0",
3434
"multer": "^1.4.4-lts.1",
35+
"on-headers": "^1.0.2",
3536
"readline": "^1.3.0",
3637
"semver": "^7.6.3",
3738
"uuid": "^8.3.2",

Diff for: src/server.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const morgan = require('morgan');
44
const routes = require('./routes');
55
const { authenticateToken } = require('./middleware/auth');
66
const { checkPermissions } = require('./middleware/permissions');
7-
const { httpLogger } = require('./utils/logger');
7+
const { httpLogger, trackDuration } = require('./utils/logger');
88
const config = require('./config');
99

1010
const app = express();
@@ -13,6 +13,7 @@ app.use(express.json());
1313
app.use(morgan('combined'));
1414

1515
// Use the HTTP logger middleware
16+
app.use(trackDuration);
1617
app.use(httpLogger);
1718

1819
// Apply authentication to all routes

Diff for: src/utils/logger.js

+25-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// File: src/utils/logger.js
22
const winston = require('winston');
33
const morgan = require('morgan');
4+
const onHeaders = require('on-headers');
45

56
// Create a Winston logger
67
const logger = winston.createLogger({
@@ -35,8 +36,26 @@ morgan.token('success', (req, res) => {
3536
return res.statusCode < 400 ? 'true' : 'false';
3637
});
3738

38-
// Create a custom logging format
39-
const morganFormat = ':remote-addr - :user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :success';
39+
// Create a custom token for request duration
40+
morgan.token('duration', (req, res) => {
41+
return res.locals.duration ? `${res.locals.duration}ms` : '0ms';
42+
});
43+
44+
// Create a custom logging format with duration
45+
const morganFormat = ':remote-addr - :user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :success :duration';
46+
47+
// Middleware to track request duration
48+
const trackDuration = (req, res, next) => {
49+
const startTime = process.hrtime();
50+
51+
onHeaders(res, () => {
52+
const diff = process.hrtime(startTime);
53+
// Convert to milliseconds (1 second = 1e9 nanoseconds)
54+
res.locals.duration = Math.round((diff[0] * 1e9 + diff[1]) / 1e6);
55+
});
56+
57+
next();
58+
};
4059

4160
// Create the Morgan middleware with custom logging logic
4261
const httpLogger = morgan(morganFormat, {
@@ -54,8 +73,9 @@ const httpLogger = morgan(morganFormat, {
5473
logObject.status = parseInt(parts[8]);
5574
logObject.responseSize = parts[9];
5675
logObject.referrer = parts[10] + ' ' + parts[11];
57-
logObject.userAgent = parts.slice(12, -1).join(' ');
58-
logObject.success = parts[parts.length - 1].trim() === 'true';
76+
logObject.userAgent = parts.slice(12, -2).join(' ');
77+
logObject.success = parts[parts.length - 2].trim() === 'true';
78+
logObject.duration = parts[parts.length - 1].trim();
5979

6080
// Log all requests, including unauthorized ones
6181
logger.info('HTTP Request', logObject);
@@ -65,4 +85,4 @@ const httpLogger = morgan(morganFormat, {
6585
skip: () => false
6686
});
6787

68-
module.exports = { logger, httpLogger };
88+
module.exports = { logger, httpLogger, trackDuration };

0 commit comments

Comments
 (0)