Skip to content
Open
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
429359b
lib: added logger api in node core
mertcanaltin Nov 30, 2025
6d56e36
fix: validate log level in LogConsumer.enabled method
mertcanaltin Dec 2, 2025
79faca4
fix: improve error serialization check in serializeErr function
mertcanaltin Dec 3, 2025
1a76b7f
fix: update error serialization check and improve log level validation
mertcanaltin Dec 3, 2025
61461e4
fix: replace ErrorIsError with isNativeError for better error seriali…
mertcanaltin Dec 6, 2025
c669174
fix: remove unused Error import in logger.js
mertcanaltin Dec 6, 2025
3ec6c9f
fix: update logger module imports to use 'node:logger' for consistency
mertcanaltin Dec 6, 2025
58cca8b
fix: remove unused spawnSyncAndAssert import in test-require-module-t…
mertcanaltin Dec 6, 2025
c5cb707
fix: add missing commas in spawnSync options for consistency
mertcanaltin Dec 6, 2025
5dc2b2d
fix: update consumer end method to use callback for asynchronous log …
mertcanaltin Dec 7, 2025
a9e288f
fix: remove log file empty assertion message for clarity
mertcanaltin Dec 7, 2025
8f88a71
fix: refactor test assertions to use common.mustSucceed for consistency
mertcanaltin Dec 7, 2025
83a12b7
docs: add LogConsumer class and enabled method documentation
mertcanaltin Dec 10, 2025
22ed15d
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
c38b9b1
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
8a300fe
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
68c520b
Update lib/logger.js
mertcanaltin Dec 24, 2025
1f5b449
Update lib/logger.js
mertcanaltin Dec 24, 2025
e0ae4d6
Update lib/logger.js
mertcanaltin Dec 24, 2025
8f4c641
Enhance JSDoc comments for serializers and logger methods
mertcanaltin Dec 24, 2025
09f0ef2
Refactor JSDoc for HTTP request serializer and remove unused error code
mertcanaltin Dec 24, 2025
b23e669
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
76b0742
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
da165bf
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
6cf3d03
enhance logger and serializers: improve error serialization and refac…
mertcanaltin Jan 5, 2026
b856491
add logger types to custom types map
mertcanaltin Jan 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 90 additions & 92 deletions test/parallel/test-log-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,16 @@

// Flush synchronously and read the output
consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');

// Parse the JSON output
const parsed = JSON.parse(output.trim());
assert.strictEqual(parsed.level, 'info');
assert.strictEqual(parsed.msg, 'test message');
assert.strictEqual(parsed.userId, 123);
assert.strictEqual(typeof parsed.time, 'number');

// Cleanup
fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');

Check failure on line 114 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`

Check failure on line 114 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.notStrictEqual()
const parsed = JSON.parse(output);
assert.strictEqual(parsed.level, 'info');

Check failure on line 116 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
assert.strictEqual(parsed.msg, 'test message');

Check failure on line 117 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
assert.strictEqual(parsed.userId, 123);

Check failure on line 118 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
assert.strictEqual(typeof parsed.time, 'number');

Check failure on line 119 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
fs.unlinkSync(tmpfile);
});
}

// Test JSONConsumer with additional fields
Expand All @@ -137,15 +135,16 @@
logger.info({ msg: 'with fields' });

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());
assert.strictEqual(parsed.hostname, 'test-host');
assert.strictEqual(parsed.pid, 12345);
assert.strictEqual(parsed.msg, 'with fields');

// Cleanup
fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');

Check failure on line 140 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`

Check failure on line 140 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.notStrictEqual()
const parsed = JSON.parse(output);
assert.strictEqual(parsed.hostname, 'test-host');

Check failure on line 142 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
assert.strictEqual(parsed.pid, 12345);

Check failure on line 143 in test/parallel/test-log-basic.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
assert.strictEqual(parsed.msg, 'with fields');
// Cleanup
fs.unlinkSync(tmpfile);
});
}

// Test child logger bindings in output
Expand All @@ -162,15 +161,15 @@
childLogger.info({ msg: 'child log', action: 'create' });

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());
assert.strictEqual(parsed.requestId, 'xyz-789');
assert.strictEqual(parsed.action, 'create');
assert.strictEqual(parsed.msg, 'child log');

// Cleanup
fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
assert.strictEqual(parsed.requestId, 'xyz-789');
assert.strictEqual(parsed.action, 'create');
assert.strictEqual(parsed.msg, 'child log');
fs.unlinkSync(tmpfile);
});
}

// Test invalid log level
Expand Down Expand Up @@ -239,14 +238,14 @@
logger.info('simple message');

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

assert.strictEqual(parsed.msg, 'simple message');
assert.strictEqual(parsed.level, 'info');

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
assert.strictEqual(parsed.msg, 'simple message');
assert.strictEqual(parsed.level, 'info');
fs.unlinkSync(tmpfile);
});
}

// Test string message with fields
Expand All @@ -262,15 +261,15 @@
logger.info('user login', { userId: 123, ip: '127.0.0.1' });

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

assert.strictEqual(parsed.msg, 'user login');
assert.strictEqual(parsed.userId, 123);
assert.strictEqual(parsed.ip, '127.0.0.1');

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
assert.strictEqual(parsed.msg, 'user login');
assert.strictEqual(parsed.userId, 123);
assert.strictEqual(parsed.ip, '127.0.0.1');
fs.unlinkSync(tmpfile);
});
}

// Test Error object serialization
Expand All @@ -288,18 +287,18 @@
logger.error({ msg: 'operation failed', err });

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

// Error should be serialized with stack trace
assert.strictEqual(parsed.msg, 'operation failed');
assert.strictEqual(typeof parsed.err, 'object');
assert.strictEqual(parsed.err.message, 'test error');
assert.strictEqual(parsed.err.code, 'TEST_ERROR');
assert(parsed.err.stack);

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
// Error should be serialized with stack trace
assert.strictEqual(parsed.msg, 'operation failed');
assert.strictEqual(typeof parsed.err, 'object');
assert.strictEqual(parsed.err.message, 'test error');
assert.strictEqual(parsed.err.code, 'TEST_ERROR');
assert(parsed.err.stack);
fs.unlinkSync(tmpfile);
});
}

// Test Error as first argument
Expand All @@ -316,15 +315,15 @@
logger.error(err); // Error as first arg

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

assert.strictEqual(parsed.msg, 'boom'); // message from error
assert.strictEqual(typeof parsed.err, 'object');
assert(parsed.err.stack);

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
assert.strictEqual(parsed.msg, 'boom'); // message from error
assert.strictEqual(typeof parsed.err, 'object');
assert(parsed.err.stack);
fs.unlinkSync(tmpfile);
});
}

// Test child logger with parent fields merge
Expand All @@ -342,17 +341,17 @@
childLogger.info('request processed', { duration: 150 }); // log fields

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

// Merge order: consumer fields < bindings < log fields
assert.strictEqual(parsed.service, 'api');
assert.strictEqual(parsed.requestId, '123');
assert.strictEqual(parsed.duration, 150);
assert.strictEqual(parsed.msg, 'request processed');

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
// Merge order: consumer fields < bindings < log fields
assert.strictEqual(parsed.service, 'api');
assert.strictEqual(parsed.requestId, '123');
assert.strictEqual(parsed.duration, 150);
assert.strictEqual(parsed.msg, 'request processed');
fs.unlinkSync(tmpfile);
});
}

// Test field override priority
Expand All @@ -370,15 +369,15 @@
childLogger.info('test', { env: 'production' });

consumer.flushSync();
consumer.end();
const output = fs.readFileSync(tmpfile, 'utf8');
const parsed = JSON.parse(output.trim());

// Log fields should override everything
assert.strictEqual(parsed.env, 'production');
assert.strictEqual(parsed.version, '1.0');

fs.unlinkSync(tmpfile);
consumer.end(() => {
const output = fs.readFileSync(tmpfile, 'utf8').trim();
assert.notStrictEqual(output, '', 'Log file is empty!');
const parsed = JSON.parse(output);
// Log fields should override everything
assert.strictEqual(parsed.env, 'production');
assert.strictEqual(parsed.version, '1.0');
fs.unlinkSync(tmpfile);
});
}

// Test multiple consumers (Qard's use case)
Expand Down Expand Up @@ -408,24 +407,23 @@
logger.error({ msg: 'error message' });

consumer1.flushSync();
consumer1.end();
consumer2.flushSync();
consumer1.end();
consumer2.end();

const output1 = fs.readFileSync(tmpfile1, 'utf8');
const lines1 = output1.trim().split('\n');

const output2 = fs.readFileSync(tmpfile2, 'utf8');
const lines2 = output2.trim().split('\n');

// Consumer1 should have all 4 logs (debug+)
// Consumer1 dosya formatı satır başına log yazıyorsa 4 olmalı, değilse bu kontrolü güncelle.
assert.strictEqual(lines1.length, 4);
assert.strictEqual(JSON.parse(lines1[0]).level, 'debug');
assert.strictEqual(JSON.parse(lines1[1]).level, 'info');
assert.strictEqual(JSON.parse(lines1[2]).level, 'warn');
assert.strictEqual(JSON.parse(lines1[3]).level, 'error');

// Consumer2 should have only 2 logs (warn+)
// Consumer2 dosya formatı satır başına log yazıyorsa 2 olmalı, değilse bu kontrolü güncelle.
assert.strictEqual(lines2.length, 2);
assert.strictEqual(JSON.parse(lines2[0]).level, 'warn');
assert.strictEqual(JSON.parse(lines2[1]).level, 'error');
Expand Down
Loading