Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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);
}
13 changes: 13 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,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 @@ -3613,6 +3624,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 @@ -4197,6 +4209,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