Skip to content

Commit 1ededc7

Browse files
committed
serializers with optimizations
1 parent e87d4ec commit 1ededc7

File tree

1 file changed

+62
-17
lines changed

1 file changed

+62
-17
lines changed

lib/logger.js

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const {
44
DateNow,
5-
ErrorIsError,
5+
Error,
66
JSONStringify,
77
ObjectAssign,
88
ObjectKeys,
@@ -164,30 +164,35 @@ class JSONConsumer extends LogConsumer {
164164
}
165165

166166
handle(record) {
167-
const logObj = {
168-
level: record.level,
169-
time: record.time,
170-
msg: record.msg,
171-
};
167+
// Start building JSON manually
168+
let json = '{"level":"' + record.level + '",' +
169+
'"time":' + record.time + ',' +
170+
'"msg":"' + record.msg + '"';
172171

173-
// Merge fields in order: consumer fields -> bindings -> log fields
174-
// Using direct property assignment for better performance
172+
// Add consumer fields
175173
const consumerFields = this.#fields;
176174
for (const key in consumerFields) {
177-
logObj[key] = consumerFields[key];
175+
const value = consumerFields[key];
176+
json += ',"' + key + '":';
177+
json += typeof value === 'string' ?
178+
'"' + value + '"' :
179+
JSONStringify(value);
178180
}
179181

180-
const bindings = record.bindings;
181-
for (const key in bindings) {
182-
logObj[key] = bindings[key];
183-
}
182+
// Add pre-serialized bindings
183+
json += record.bindingsStr;
184184

185+
// Add log fields
185186
const fields = record.fields;
186187
for (const key in fields) {
187-
logObj[key] = fields[key];
188+
const value = fields[key];
189+
json += ',"' + key + '":';
190+
json += typeof value === 'string' ?
191+
'"' + value + '"' :
192+
JSONStringify(value);
188193
}
189194

190-
const json = JSONStringify(logObj) + '\n';
195+
json += '}\n';
191196
this.#stream.write(json);
192197
}
193198

@@ -221,7 +226,9 @@ class Logger {
221226
#level;
222227
#levelValue;
223228
#bindings;
229+
#bindingsStr; // Pre-serialized bindings JSON string
224230
#serializers;
231+
#hasCustomSerializers;
225232

226233
constructor(options = kEmptyObject) {
227234
validateObject(options, 'options');
@@ -256,14 +263,47 @@ class Logger {
256263
this.#serializers = { __proto__: null };
257264
// Add default err serializer (can be overridden)
258265
this.#serializers.err = stdSerializers.err;
266+
267+
// Track if we have custom serializers beyond 'err'
268+
let hasCustom = false;
259269
// Add custom serializers
260270
for (const key in serializers) {
261271
this.#serializers[key] = serializers[key];
272+
if (key !== 'err') {
273+
hasCustom = true;
274+
}
262275
}
276+
this.#hasCustomSerializers = hasCustom;
277+
278+
// Pre-serialize bindings
279+
this.#bindingsStr = this.#serializeBindings(bindings);
263280

264281
this.#setLogMethods();
265282
}
266283

284+
/**
285+
* Pre-serialize bindings
286+
* @param {object} bindings
287+
* @returns {string}
288+
* @private
289+
*/
290+
#serializeBindings(bindings) {
291+
if (!bindings || typeof bindings !== 'object') {
292+
return '';
293+
}
294+
295+
let result = '';
296+
for (const key in bindings) {
297+
const value = bindings[key];
298+
// Apply serializer if exists
299+
const serialized = this.#serializers[key] ?
300+
this.#serializers[key](value) :
301+
value;
302+
result += ',"' + key + '":' + JSONStringify(serialized);
303+
}
304+
return result;
305+
}
306+
267307
/**
268308
* Replace disabled log methods with noop for performance
269309
* @private
@@ -340,7 +380,7 @@ class Logger {
340380
* @private
341381
*/
342382
#isError(value) {
343-
return ErrorIsError(value);
383+
return value instanceof Error;
344384
}
345385

346386
/**
@@ -354,6 +394,11 @@ class Logger {
354394
return obj;
355395
}
356396

397+
// Fast path: no custom serializers, return as-is
398+
if (!this.#hasCustomSerializers) {
399+
return obj;
400+
}
401+
357402
const serialized = { __proto__: null };
358403
const serializers = this.#serializers;
359404

@@ -444,7 +489,7 @@ class Logger {
444489
level,
445490
msg,
446491
time: DateNow(),
447-
bindings: this.#bindings,
492+
bindingsStr: this.#bindingsStr, // Pre-serialized bindings string
448493
fields: logFields,
449494
};
450495

0 commit comments

Comments
 (0)