Skip to content

Commit b2a9375

Browse files
committed
CLDSRV-750: format server access logs to s.ms
1 parent e2ba608 commit b2a9375

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

lib/utilities/serverAccessLogger.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ function calculateElapsedMS(startTime, onCloseEndTime) {
358358
return Number(onCloseEndTime - startTime) / 1_000_000;
359359
}
360360

361+
function timestampToDateTime643(unixMS) {
362+
if (unixMS === undefined || unixMS === null) {
363+
return null;
364+
}
365+
366+
// clickhouse DateTime64(3) expects "seconds.milliseconds" (string type).
367+
return (unixMS / 1000).toFixed(3);
368+
}
369+
361370
function logServerAccess(req, res) {
362371
if (!req.serverAccessLog || !res.serverAccessLog || !serverAccessLogger) {
363372
return;
@@ -372,7 +381,8 @@ function logServerAccess(req, res) {
372381

373382
serverAccessLogger.write(`${JSON.stringify({
374383
// Werelog fields
375-
time: Date.now(),
384+
// logs.access_logs_ingest.timestamp in Clickhouse is of type DateTime so it expects seconds as an integer.
385+
time: Math.floor(Date.now() / 1000),
376386
hostname,
377387
pid: process.pid,
378388
@@ -392,7 +402,7 @@ function logServerAccess(req, res) {
392402
httpURL: req.url || null,
393403
394404
// AWS access server logs fields https://docs.aws.amazon.com/AmazonS3/latest/userguide/LogFormat.html
395-
startTime: params.startTimeUnixMS || null, // AWS "Time" field
405+
startTime: timestampToDateTime643(params.startTimeUnixMS), // AWS "Time" field
396406
requester: getRequester(authInfo),
397407
operation: getOperation(req),
398408
requestURI: getURI(req),
@@ -446,4 +456,5 @@ module.exports = {
446456
getBytesSent,
447457
calculateTotalTime,
448458
calculateTurnAroundTime,
459+
timestampToDateTime643,
449460
};

tests/unit/utils/serverAccessLogger.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {
1111
getBytesSent,
1212
calculateTotalTime,
1313
calculateTurnAroundTime,
14+
timestampToDateTime643,
1415
} = require('../../../lib/utilities/serverAccessLogger');
1516

1617

@@ -618,6 +619,48 @@ describe('serverAccessLogger utility functions', () => {
618619
});
619620
});
620621

622+
describe('timestampToDateTime643', () => {
623+
it('should convert milliseconds to seconds with 3 decimal places', () => {
624+
const startTimeUnixMS = 1234567890000;
625+
const result = timestampToDateTime643(startTimeUnixMS);
626+
assert.strictEqual(result, '1234567890.000');
627+
});
628+
629+
it('should handle timestamp with milliseconds', () => {
630+
const startTimeUnixMS = 1234567890123;
631+
const result = timestampToDateTime643(startTimeUnixMS);
632+
assert.strictEqual(result, '1234567890.123');
633+
});
634+
635+
it('should handle 0', () => {
636+
const startTimeUnixMS = 0;
637+
const result = timestampToDateTime643(startTimeUnixMS);
638+
assert.strictEqual(result, '0.000');
639+
});
640+
641+
it('should return null when startTimeUnixMS is null', () => {
642+
const result = timestampToDateTime643(null);
643+
assert.strictEqual(result, null);
644+
});
645+
646+
it('should return null when startTimeUnixMS is undefined', () => {
647+
const result = timestampToDateTime643(undefined);
648+
assert.strictEqual(result, null);
649+
});
650+
651+
it('should handle small timestamps', () => {
652+
const startTimeUnixMS = 1000;
653+
const result = timestampToDateTime643(startTimeUnixMS);
654+
assert.strictEqual(result, '1.000');
655+
});
656+
657+
it('should handle timestamps with partial milliseconds', () => {
658+
const startTimeUnixMS = 1500;
659+
const result = timestampToDateTime643(startTimeUnixMS);
660+
assert.strictEqual(result, '1.500');
661+
});
662+
});
663+
621664
describe('logServerAccess', () => {
622665
let mockLogger;
623666
let sandbox;
@@ -773,7 +816,7 @@ describe('serverAccessLogger utility functions', () => {
773816
assert.strictEqual(loggedData.httpURL, '/test-bucket/test-key.txt');
774817

775818
// Verify AWS access server log fields
776-
assert.strictEqual(loggedData.startTime, 1234567890000);
819+
assert.strictEqual(loggedData.startTime, '1234567890.000');
777820
assert.strictEqual(loggedData.requester, 'canonical123');
778821
assert.strictEqual(loggedData.operation, 'REST.GET.OBJECT');
779822
assert.strictEqual(loggedData.requestURI, 'GET /test-bucket/test-key.txt HTTP/1.1');

0 commit comments

Comments
 (0)