Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2e1a8f1
lib: add logger api in node core
mertcanaltin Feb 26, 2026
f7885a2
lib: address review feedback for logger API
mertcanaltin Feb 26, 2026
6f0d6aa
lib: address review feedback for logger API
mertcanaltin Feb 26, 2026
f7d60ac
added missing test
mertcanaltin Feb 26, 2026
7056fbe
logger: address review feedback
mertcanaltin Feb 27, 2026
b15ec5e
logger: address review feedback
mertcanaltin Feb 27, 2026
6a24b03
Update lib/internal/logger/serializers.js
mertcanaltin Feb 27, 2026
32a0e58
delete pino benchmark
mertcanaltin Feb 27, 2026
64a4241
delete exports (LEVELS, channels)
mertcanaltin Feb 27, 2026
932db90
edited logger api md
mertcanaltin Mar 29, 2026
003402a
address review feedback for logger api
mertcanaltin Apr 5, 2026
c6384d8
logger: skip input validation when no subscribers
mertcanaltin Apr 15, 2026
8d67c43
doc: address review feedback on logger.md
mertcanaltin Apr 15, 2026
0f9833a
doc: add log channels in diagnostics_channel
mertcanaltin Apr 15, 2026
8ae2fb7
Update serializers.js
mertcanaltin Apr 15, 2026
0e635e4
Update serializers.js
mertcanaltin Apr 15, 2026
2bb8fa6
Update logger.js
mertcanaltin Apr 15, 2026
1f2b586
Update lib/internal/logger/serializers.js
mertcanaltin Apr 15, 2026
95d2f3c
Merge branch 'main' into mert/create-logger-api/node-core
mertcanaltin Apr 19, 2026
f2d9074
logger: address review feedback
mertcanaltin Apr 19, 2026
0b2e2e5
Merge branch 'main' into mert/create-logger-api/node-core
mertcanaltin Apr 20, 2026
de96fec
src: remove duplicate experimental_stream_iter
mertcanaltin Apr 22, 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
Copy Markdown
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);
}
13 changes: 13 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,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.1 - Active Development

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

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

<!-- YAML
Expand Down Expand Up @@ -3701,6 +3712,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 @@ -4294,6 +4306,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
32 changes: 32 additions & 0 deletions doc/api/diagnostics_channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,37 @@ passed to `console.warn()`.
Emitted when `console.error()` is called. Receives and array of the arguments
passed to `console.error()`.

#### Logger

> Stability: 1.1 - Active Development

Published by the [`node:logger`][] module. Each log level has its own channel,
allowing subscribers to filter by severity without matching on record contents.

##### Event: `'log:trace'`

* `record` {Object} Log record emitted at the `trace` level.

##### Event: `'log:debug'`

* `record` {Object} Log record emitted at the `debug` level.

##### Event: `'log:info'`

* `record` {Object} Log record emitted at the `info` level.

##### Event: `'log:warn'`

* `record` {Object} Log record emitted at the `warn` level.

##### Event: `'log:error'`

* `record` {Object} Log record emitted at the `error` level.

##### Event: `'log:fatal'`

* `record` {Object} Log record emitted at the `fatal` level.

#### HTTP

> Stability: 1 - Experimental
Expand Down Expand Up @@ -1934,6 +1965,7 @@ Emitted when a new thread is created.
[`error` event]: #errorevent
[`locks.request()`]: worker_threads.md#locksrequestname-options-callback
[`net.Server.listen()`]: net.md#serverlisten
[`node:logger`]: logger.md
[`process.execve()`]: process.md#processexecvefile-args-env
[`start` event]: #startevent
[`worker_threads.locks`]: worker_threads.md#worker_threadslocks
Expand Down
1 change: 1 addition & 0 deletions doc/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,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