Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
447341e
lib: added logger api in node core
mertcanaltin Nov 30, 2025
90c12b1
fix: validate log level in LogConsumer.enabled method
mertcanaltin Dec 2, 2025
80d5556
fix: improve error serialization check in serializeErr function
mertcanaltin Dec 3, 2025
fc1b7f3
fix: update error serialization check and improve log level validation
mertcanaltin Dec 3, 2025
76a6612
fix: replace ErrorIsError with isNativeError for better error seriali…
mertcanaltin Dec 6, 2025
f5b0dbe
fix: remove unused Error import in logger.js
mertcanaltin Dec 6, 2025
8372347
fix: update logger module imports to use 'node:logger' for consistency
mertcanaltin Dec 6, 2025
73186e7
fix: remove unused spawnSyncAndAssert import in test-require-module-t…
mertcanaltin Dec 6, 2025
d6a9d6a
fix: add missing commas in spawnSync options for consistency
mertcanaltin Dec 6, 2025
b0e6e1e
fix: update consumer end method to use callback for asynchronous log …
mertcanaltin Dec 7, 2025
4dd5954
fix: remove log file empty assertion message for clarity
mertcanaltin Dec 7, 2025
d8535fb
fix: refactor test assertions to use common.mustSucceed for consistency
mertcanaltin Dec 7, 2025
7745b7b
docs: add LogConsumer class and enabled method documentation
mertcanaltin Dec 10, 2025
a57c8e8
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
b20fa90
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
70f2fcb
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
a1bf6f2
Update lib/logger.js
mertcanaltin Dec 24, 2025
ab8a344
Update lib/logger.js
mertcanaltin Dec 24, 2025
3cbfa7d
Update lib/logger.js
mertcanaltin Dec 24, 2025
c06cb20
Enhance JSDoc comments for serializers and logger methods
mertcanaltin Dec 24, 2025
75de15a
Refactor JSDoc for HTTP request serializer and remove unused error code
mertcanaltin Dec 24, 2025
fa27eb7
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
e1bc224
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
598bdfb
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
534c14a
enhance logger and serializers: improve error serialization and refac…
mertcanaltin Jan 5, 2026
7fd6250
add logger types to custom types map
mertcanaltin Jan 5, 2026
a6eaf8d
add enabled property to logger methods for performance checks
mertcanaltin Jan 6, 2026
79f85d7
update doc
mertcanaltin Jan 7, 2026
a4d99b1
dead code delete
mertcanaltin Jan 7, 2026
36e530a
ditto delete
mertcanaltin Jan 7, 2026
f688d73
remove redundant parameter documentation from Logger methods
mertcanaltin Jan 7, 2026
52709ef
added rfc5424
mertcanaltin Jan 7, 2026
f8b450e
used template literal
mertcanaltin Jan 28, 2026
a19b1aa
Update lib/logger.js
mertcanaltin Jan 28, 2026
f2c4e4c
Update doc/api/logger.md
mertcanaltin Jan 28, 2026
cab1e85
add experimental logger module support
mertcanaltin Jan 28, 2026
5bc27ba
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
10e7d4b
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
23e78c8
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
ea4e3c7
added experimental flag for tests
mertcanaltin Jan 31, 2026
219ac1e
used node:test
mertcanaltin Jan 31, 2026
5883172
refactor logger initialization in benchmark tests to use new Logger c…
mertcanaltin Jan 31, 2026
fda687c
refactor logger documentation for clarity and consistency
mertcanaltin Jan 31, 2026
912801b
implemented serialize symbol
mertcanaltin Jan 31, 2026
f579e91
add experimental logger module and update related tests
mertcanaltin Jan 31, 2026
7200dd9
added experimental for structured logging
mertcanaltin Jan 31, 2026
28b9b30
fix: update logger module imports to use 'node:logger' for consistency
mertcanaltin Dec 6, 2025
a07f953
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
83e37fc
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
b52ec41
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
fc77736
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
5a21c34
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
4c0fa3e
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
ea8c753
add experimental logger module and update related tests
mertcanaltin Jan 31, 2026
a9371b1
used ObjectKeys
mertcanaltin Feb 5, 2026
57f29b2
review fix
mertcanaltin Feb 5, 2026
87e50d5
refactor(logger): update enabled checks to use property access for lo…
mertcanaltin Feb 5, 2026
d2ab9e1
refactor(logger): remove unused ObjectHasOwn import
mertcanaltin Feb 5, 2026
c142ab3
remove outdated reference to logger level enabled property
mertcanaltin Feb 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
174 changes: 174 additions & 0 deletions benchmark/logger/basic-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
'use strict';

const common = require('../common');
const fs = require('node:fs');

const bench = common.createBenchmark(main, {
n: [1e5],
scenario: [
'string-short',
'string-long',
'object-simple',
'object-nested',
'object-array',
'object-mixed',
'child-logger',
'disabled-level',
'error-object',
],
});

function main({ n, scenario }) {
const { Logger, JSONConsumer } = require('node:logger');

const nullFd = fs.openSync('/dev/null', 'w');
const consumer = new JSONConsumer({ stream: nullFd, level: 'info' });
consumer.attach();

const logger = new Logger({ level: 'info' });

switch (scenario) {
case 'string-short': {
// Simple short string message
bench.start();
for (let i = 0; i < n; i++) {
logger.info('hello');
}
bench.end(n);
break;
}

case 'string-long': {
// Long string message (100 chars)
const longMsg = 'This is a much longer log message that contains ' +
'more text to serialize and process during logging operations';
bench.start();
for (let i = 0; i < n; i++) {
logger.info(longMsg);
}
bench.end(n);
break;
}

case 'object-simple': {
// Object with msg and a few string fields
bench.start();
for (let i = 0; i < n; i++) {
logger.info({
msg: 'user action',
userId: 'user-123',
action: 'login',
});
Comment on lines +57 to +61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These object benchmarks would also be measuring the construction time of each object constructed within each loop iteration. Not sure if we care about that for this benchmark, but figured it was worth pointing out.

}
bench.end(n);
break;
}

case 'object-nested': {
// Object with nested structure
bench.start();
for (let i = 0; i < n; i++) {
logger.info({
msg: 'request completed',
request: {
method: 'POST',
path: '/api/users',
headers: {
'content-type': 'application/json',
'user-agent': 'Mozilla/5.0',
},
},
response: {
statusCode: 200,
body: { success: true },
},
});
}
bench.end(n);
break;
}

case 'object-array': {
// Object with array fields
const tags = ['web', 'api', 'auth', 'production'];
const ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
bench.start();
for (let i = 0; i < n; i++) {
logger.info({
msg: 'batch operation',
tags,
processedIds: ids,
results: ['success', 'success', 'failed', 'success'],
});
}
bench.end(n);
break;
}

case 'object-mixed': {
// Mixed types: strings, numbers, booleans, null
bench.start();
for (let i = 0; i < n; i++) {
logger.info({
msg: 'mixed data',
stringField: 'value',
numberField: 42,
floatField: 3.14159,
booleanField: true,
nullField: null,
timestamp: 1704067200000,
});
}
bench.end(n);
break;
}

case 'child-logger': {
// Child logger with pre-bound context
const childLogger = logger.child({
service: 'api',
version: '1.0.0',
env: 'production',
});
bench.start();
for (let i = 0; i < n; i++) {
childLogger.info({
msg: 'request',
requestId: 'req-123',
duration: 150,
});
}
bench.end(n);
break;
}

case 'disabled-level': {
// Logging at disabled level (debug when level is info)
bench.start();
for (let i = 0; i < n; i++) {
logger.debug('this will be skipped');
}
bench.end(n);
break;
}

case 'error-object': {
// Logging with Error object
const error = new Error('Something went wrong');
error.code = 'ERR_SOMETHING';
bench.start();
for (let i = 0; i < n; i++) {
logger.error({
msg: 'operation failed',
err: error,
operation: 'database-query',
});
}
bench.end(n);
break;
}
}

consumer.flushSync();
fs.closeSync(nullFd);
}
146 changes: 146 additions & 0 deletions benchmark/logger/vs-pino.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
'use strict';

const common = require('../common');
const fs = require('node:fs');

const bench = common.createBenchmark(main, {
n: [1e5],
logger: ['node-logger', 'pino'],
scenario: ['simple', 'child', 'disabled', 'fields'],
});

function main({ n, logger, scenario }) {
const nullFd = fs.openSync('/dev/null', 'w');
let testLogger;
let consumer;

if (logger === 'node-logger') {
const { Logger, JSONConsumer } = require('node:logger');

switch (scenario) {
case 'simple': {
consumer = new JSONConsumer({ stream: nullFd, level: 'info' });
consumer.attach();
testLogger = new Logger({ level: 'info' });

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info('benchmark test message');
}
bench.end(n);
break;
}

case 'child': {
consumer = new JSONConsumer({ stream: nullFd, level: 'info' });
consumer.attach();
const baseLogger = new Logger({ level: 'info' });
testLogger = baseLogger.child({ requestId: 'req-123', userId: 456 });

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info('benchmark test message');
}
bench.end(n);
break;
}

case 'disabled': {
consumer = new JSONConsumer({ stream: nullFd, level: 'warn' });
consumer.attach();
testLogger = new Logger({ level: 'warn' });

bench.start();
for (let i = 0; i < n; i++) {
testLogger.debug('benchmark test message');
}
bench.end(n);
break;
}

case 'fields': {
consumer = new JSONConsumer({ stream: nullFd, level: 'info' });
consumer.attach();
testLogger = new Logger({ level: 'info' });

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info('benchmark test message', {
field1: 'value1',
field2: 'value2',
field3: 'value3',
field4: 'value4',
field5: 'value5',
});
}
bench.end(n);
break;
}
}

if (consumer) {
consumer.flushSync();
}
fs.closeSync(nullFd);

} else if (logger === 'pino') {
const pino = require('pino');
const destination = pino.destination({ dest: nullFd, sync: false });

switch (scenario) {
case 'simple': {
testLogger = pino({ level: 'info' }, destination);

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info('benchmark test message');
}
bench.end(n);
break;
}

case 'child': {
const baseLogger = pino({ level: 'info' }, destination);
testLogger = baseLogger.child({ requestId: 'req-123', userId: 456 });

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info('benchmark test message');
}
bench.end(n);
break;
}

case 'disabled': {
testLogger = pino({ level: 'warn' }, destination);

bench.start();
for (let i = 0; i < n; i++) {
testLogger.debug('benchmark test message');
}
bench.end(n);
break;
}

case 'fields': {
testLogger = pino({ level: 'info' }, destination);

bench.start();
for (let i = 0; i < n; i++) {
testLogger.info({
msg: 'benchmark test message',
field1: 'value1',
field2: 'value2',
field3: 'value3',
field4: 'value4',
field5: 'value5',
});
}
bench.end(n);
break;
}
}

destination.flushSync();
}
}
13 changes: 13 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,17 @@ Specify the `module` containing exported [asynchronous module customization hook

This feature requires `--allow-worker` if used with the [Permission Model][].

### `--experimental-logger`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental

Enable the experimental `node:logger` module for structured logging.
See the [Logger][] documentation for more details.

### `--experimental-network-inspection`

<!-- YAML
Expand Down Expand Up @@ -3594,6 +3605,7 @@ one is included in the list below.
* `--experimental-import-meta-resolve`
* `--experimental-json-modules`
* `--experimental-loader`
* `--experimental-logger`
* `--experimental-modules`
* `--experimental-print-required-tla`
* `--experimental-quic`
Expand Down Expand Up @@ -4177,6 +4189,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
[ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions
[File System Permissions]: permissions.md#file-system-permissions
[Loading ECMAScript modules using `require()`]: modules.md#loading-ecmascript-modules-using-require
[Logger]: logger.md
[Module resolution and loading]: packages.md#module-resolution-and-loading
[Navigator API]: globals.md#navigator
[Node.js issue tracker]: https://github.com/nodejs/node/issues
Expand Down
1 change: 1 addition & 0 deletions doc/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
* [UDP/datagram](dgram.md)
* [URL](url.md)
* [Utilities](util.md)
* [Logger](logger.md)
* [V8](v8.md)
* [VM](vm.md)
* [WASI](wasi.md)
Expand Down
Loading
Loading