Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
afd452c
lib: added logger api in node core
mertcanaltin Nov 30, 2025
ca93100
fix: validate log level in LogConsumer.enabled method
mertcanaltin Dec 2, 2025
2ce155f
fix: improve error serialization check in serializeErr function
mertcanaltin Dec 3, 2025
8d06114
fix: update error serialization check and improve log level validation
mertcanaltin Dec 3, 2025
6135300
fix: replace ErrorIsError with isNativeError for better error seriali…
mertcanaltin Dec 6, 2025
a846c4d
fix: remove unused Error import in logger.js
mertcanaltin Dec 6, 2025
1683f9c
fix: update logger module imports to use 'node:logger' for consistency
mertcanaltin Dec 6, 2025
ea9afcb
fix: remove unused spawnSyncAndAssert import in test-require-module-t…
mertcanaltin Dec 6, 2025
54a02d3
fix: add missing commas in spawnSync options for consistency
mertcanaltin Dec 6, 2025
f9214af
fix: update consumer end method to use callback for asynchronous log …
mertcanaltin Dec 7, 2025
87df951
fix: remove log file empty assertion message for clarity
mertcanaltin Dec 7, 2025
8816f19
fix: refactor test assertions to use common.mustSucceed for consistency
mertcanaltin Dec 7, 2025
92a3108
docs: add LogConsumer class and enabled method documentation
mertcanaltin Dec 10, 2025
ea72e34
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
c859729
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
8a43c23
Update lib/internal/logger/serializers.js
mertcanaltin Dec 24, 2025
bff1b52
Update lib/logger.js
mertcanaltin Dec 24, 2025
7a8a90f
Update lib/logger.js
mertcanaltin Dec 24, 2025
d0b944b
Update lib/logger.js
mertcanaltin Dec 24, 2025
2cf5532
Enhance JSDoc comments for serializers and logger methods
mertcanaltin Dec 24, 2025
9dc3dbf
Refactor JSDoc for HTTP request serializer and remove unused error code
mertcanaltin Dec 24, 2025
bd4cdb5
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
2bbda05
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
680e443
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
3260825
enhance logger and serializers: improve error serialization and refac…
mertcanaltin Jan 5, 2026
565faac
add logger types to custom types map
mertcanaltin Jan 5, 2026
fe6c48d
add enabled property to logger methods for performance checks
mertcanaltin Jan 6, 2026
eb44686
update doc
mertcanaltin Jan 7, 2026
863c2a6
dead code delete
mertcanaltin Jan 7, 2026
36c05a9
ditto delete
mertcanaltin Jan 7, 2026
c1decc6
remove redundant parameter documentation from Logger methods
mertcanaltin Jan 7, 2026
d2fed43
added rfc5424
mertcanaltin Jan 7, 2026
e398469
used template literal
mertcanaltin Jan 28, 2026
163fa75
Update lib/logger.js
mertcanaltin Jan 28, 2026
108a2c4
Update doc/api/logger.md
mertcanaltin Jan 28, 2026
659b04c
add experimental logger module support
mertcanaltin Jan 28, 2026
cfb6a61
add benchmark utility for isNativeError function
mertcanaltin Dec 26, 2025
9ca6d31
Remove bytes submodule from commit
mertcanaltin Dec 26, 2025
8f7bfdd
Remove isNativeError benchmark utility
mertcanaltin Dec 30, 2025
4d432c5
added experimental flag for tests
mertcanaltin Jan 31, 2026
94d24a2
used node:test
mertcanaltin Jan 31, 2026
31a3a70
refactor logger initialization in benchmark tests to use new Logger c…
mertcanaltin Jan 31, 2026
14205c6
refactor logger documentation for clarity and consistency
mertcanaltin Jan 31, 2026
b53d408
implemented serialize symbol
mertcanaltin Jan 31, 2026
2aee9d0
add experimental logger module and update related tests
mertcanaltin Jan 31, 2026
e14b0bb
added experimental for structured logging
mertcanaltin Jan 31, 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',
});
}
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