From ffe8974cc2584d9da176697157e548e904a8004e Mon Sep 17 00:00:00 2001 From: jlenon7 Date: Tue, 28 Apr 2026 14:48:29 -0300 Subject: [PATCH] refactor: remove cls-rtracer --- package-lock.json | 30 +----------- package.json | 3 +- src/formatters/Formatter.ts | 4 +- src/formatters/JsonFormatter.ts | 2 +- tests/unit/formatters/JsonFormatterTest.ts | 47 ++++++++++++------- tests/unit/formatters/RequestFormatterTest.ts | 10 ++-- 6 files changed, 39 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5541c9..1695b26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,16 @@ { "name": "@athenna/logger", - "version": "5.20.0", + "version": "5.21.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@athenna/logger", - "version": "5.20.0", + "version": "5.21.0", "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^1.18.1", "@opentelemetry/api-logs": "^0.213.0", - "cls-rtracer": "^2.6.3", "telegraf": "^4.16.3" }, "devDependencies": { @@ -2638,31 +2637,6 @@ "node": ">=0.8" } }, - "node_modules/cls-rtracer": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/cls-rtracer/-/cls-rtracer-2.6.3.tgz", - "integrity": "sha512-O7M/m2M/KfT9v+q7ka9nmsadS67ce9P8+1Zgm6VFamK56oFd1iCoJ9m8hYKUQpK4+RofyaexxHJlOBkxqCDs3Q==", - "license": "MIT", - "dependencies": { - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=12.17.0 <13.0.0 || >=13.14.0 <14.0.0 || >=14.0.0" - } - }, - "node_modules/cls-rtracer/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/collect.js": { "version": "4.36.1", "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.36.1.tgz", diff --git a/package.json b/package.json index 80a2e6b..4f1c127 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@athenna/logger", - "version": "5.20.0", + "version": "5.21.0", "description": "The Athenna logging solution. Log in stdout, files and buckets.", "license": "MIT", "author": "João Lenon ", @@ -64,7 +64,6 @@ "dependencies": { "@aws-lambda-powertools/logger": "^1.18.1", "@opentelemetry/api-logs": "^0.213.0", - "cls-rtracer": "^2.6.3", "telegraf": "^4.16.3" }, "devDependencies": { diff --git a/src/formatters/Formatter.ts b/src/formatters/Formatter.ts index e115466..c82fa84 100644 --- a/src/formatters/Formatter.ts +++ b/src/formatters/Formatter.ts @@ -7,8 +7,6 @@ * file that was distributed with this source code. */ -import rTracer from 'cls-rtracer' - import { hostname } from 'node:os' import { Is, Color, Module } from '@athenna/common' import type { ContextBinding } from '#src/types/ContextBinding' @@ -65,7 +63,7 @@ export abstract class Formatter { return otelApi?.trace?.getActiveSpan()?.spanContext().traceId } - return (rTracer.id() || null) as string | null + return null } /** diff --git a/src/formatters/JsonFormatter.ts b/src/formatters/JsonFormatter.ts index 8f20318..7b0409b 100644 --- a/src/formatters/JsonFormatter.ts +++ b/src/formatters/JsonFormatter.ts @@ -22,7 +22,7 @@ export class JsonFormatter extends Formatter { hostname: this.hostname(), traceId: this.traceId(), spanId: this.spanId(), - ...this.contextBindings(), + ...this.contextBindings() } if (Is.String(message)) { diff --git a/tests/unit/formatters/JsonFormatterTest.ts b/tests/unit/formatters/JsonFormatterTest.ts index 8822d33..bbadbad 100644 --- a/tests/unit/formatters/JsonFormatterTest.ts +++ b/tests/unit/formatters/JsonFormatterTest.ts @@ -7,8 +7,6 @@ * file that was distributed with this source code. */ -import { Is } from '@athenna/common' -import { runWithId } from 'cls-rtracer' import { JsonFormatter } from '#src/formatters/JsonFormatter' import { Test, BeforeEach, AfterEach, type Context } from '@athenna/test' import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks' @@ -41,18 +39,15 @@ export default class JsonFormatterTest { } @Test() - public async shouldBeAbleToFormatLogsToJsonFormatWithTheTraceId({ assert }: Context) { + public async shouldKeepTraceCorrelationNullWhenThereIsNoActiveOtelSpan({ assert }: Context) { const formatter = new JsonFormatter().config({ level: 'info' }) + const message = JSON.parse(formatter.format('hello')) - runWithId(() => { - const message = JSON.parse(formatter.format('hello')) - - assert.equal(message.msg, 'hello') - assert.equal(message.level, 'info') - assert.equal(message.pid, process.pid) - assert.isTrue(Is.Uuid(message.traceId)) - assert.equal(message.spanId, null) - }) + assert.equal(message.msg, 'hello') + assert.equal(message.level, 'info') + assert.equal(message.pid, process.pid) + assert.equal(message.traceId, null) + assert.equal(message.spanId, null) } @Test() @@ -96,7 +91,7 @@ export default class JsonFormatterTest { contextBindings: [ { field: 'tenantId', - resolver: activeContext => activeContext.getValue(tenantIdKey) + resolve: activeContext => activeContext.getValue(tenantIdKey) } ] }) @@ -120,7 +115,7 @@ export default class JsonFormatterTest { contextBindings: [ { field: 'namespace', - resolver: activeContext => activeContext.getValue(namespaceKey) + resolve: activeContext => activeContext.getValue(namespaceKey) } ] }) @@ -143,7 +138,7 @@ export default class JsonFormatterTest { contextBindings: [ { field: 'tenantId', - resolver: () => undefined + resolve: () => undefined } ] }) @@ -153,6 +148,26 @@ export default class JsonFormatterTest { assert.isFalse(Object.hasOwn(message, 'tenantId')) } + @Test() + public async shouldSkipContextBindingsWhenRequestContextIsNotInitialized({ assert }: Context) { + const { OtelImpl } = await import(new URL('../../../../Otel/src/otel/OtelImpl.js', import.meta.url).href) + const otel = new OtelImpl() + const formatter = new JsonFormatter().config({ + level: 'info', + contextBindings: [ + { + field: 'exampleId', + resolve: activeContext => otel.getCurrentContextValue('exampleId', activeContext) + } + ] + }) + + const message = JSON.parse(formatter.format('hello')) + + assert.equal(message.msg, 'hello') + assert.isFalse(Object.hasOwn(message, 'exampleId')) + } + @Test() public async shouldAllowResolversToUseGetCurrentContextValueWithoutWithContextValue({ assert }: Context) { const { OtelImpl } = await import(new URL('../../../../Otel/src/otel/OtelImpl.js', import.meta.url).href) @@ -162,7 +177,7 @@ export default class JsonFormatterTest { contextBindings: [ { field: 'exampleId', - resolver: activeContext => otel.getCurrentContextValue('exampleId', activeContext) + resolve: activeContext => otel.getCurrentContextValue('exampleId', activeContext) } ] }) diff --git a/tests/unit/formatters/RequestFormatterTest.ts b/tests/unit/formatters/RequestFormatterTest.ts index 76d442b..1ab970e 100644 --- a/tests/unit/formatters/RequestFormatterTest.ts +++ b/tests/unit/formatters/RequestFormatterTest.ts @@ -111,7 +111,6 @@ export default class RequestFormatterTest { assert.equal(message.metadata.statusCode, 200) assert.equal(message.metadata.url, ctx.request.hostUrl) assert.equal(message.metadata.path, ctx.request.baseUrl) - assert.isDefined(message.metadata.createdAt) assert.equal(message.metadata.spanId, null) } @@ -167,9 +166,7 @@ export default class RequestFormatterTest { } @Test() - public async shouldIncludeResolvedContextBindingsAtRootWhenFormattingAsJson({ - assert - }: Context) { + public async shouldIncludeResolvedContextBindingsAtRootWhenFormattingAsJson({ assert }: Context) { const exampleIdKey = Symbol('exampleId') const formatter = new RequestFormatter().config({ level: 'info', @@ -207,9 +204,8 @@ export default class RequestFormatterTest { } } - const message = context.with( - context.active().setValue(exampleIdKey as any, 'example-id-from-context'), - () => JSON.parse(formatter.format(ctx)) + const message = context.with(context.active().setValue(exampleIdKey as any, 'example-id-from-context'), () => + JSON.parse(formatter.format(ctx)) ) assert.equal(message.exampleId, 'example-id-from-context')