ADR-0007 — EvoLogger facade kept instead of migrating to pino¶
Status: Accepted Date: 2026-04-16 Author(s): Platform engineering
Context¶
After adopting nestjs-pino as the Nest framework logger (see ADR-0001), ~40 call sites across all five NestJS apps still use EvoLogger — a winston-backed logging facade from @bebkovan/server-core. The natural question: should those 40 call sites be migrated to pino?
Both loggers now produce trace-correlated output:
- Pino records carry
trace_id,span_id,trace_flagsvia@opentelemetry/instrumentation-pino(configured inlibs/shared/src/basic/pre/pre-otel.main.ts:78-82). Records are bridged into the OTel logs SDK and exported via OTLP to the Collector → Loki. - EvoLogger/winston records carry the same three fields via
WinstonInstrumentation(enabled by default ingetNodeAutoInstrumentations). Records go to docker stdout and reach Loki via thefilelog/dockerCollector receiver.
Both paths produce trace-correlated, queryable logs in Loki. The difference is the ingest route, not the observability value.
Decision¶
Keep EvoLogger as-is. Do not migrate the ~40 call sites to pino. New code should prefer the Nest-injected pino logger (constructor(private logger: Logger) from nestjs-pino), but existing EvoLogger call sites are not worth touching.
Alternatives considered¶
-
Migrate all ~40 EvoLogger call sites to pino. Rejected: touches 40+ files across every module. Every call site already produces trace-tagged, Loki-queryable output. The migration adds risk (each
EvoLogger.log()→this.logger.log()requires injecting a NestLoggerinto the constructor, potentially changing class initialization order) for zero observability gain. -
Remove the
@bebkovan/server-coredependency entirely. Rejected:EvoLoggeris not the only export from@bebkovan/server-core. Other utilities from the package are still in use. Removing the dependency requires auditing all imports, not just the logger. -
Write a pino-backed
EvoLoggershim (same API, pino transport). Rejected: adds complexity for marginal benefit. The EvoLogger API and pino'sLoggerAPI are different enough that a shim would be a maintenance surface. The two-logger setup already works.
Consequences¶
- Two logger APIs coexist. New engineers should read ADR-0001 and the observability doc to understand which logger to use where.
- EvoLogger records in Loki are tagged
source=docker_filelogand lackservice.nameresource attributes. Query them with{source="docker_filelog"} |= "EvoLogger". - Pino records in Loki arrive via OTLP with full OTel resource attributes (
service.name,service.version). Query them with{service_name="ebit-api"}. - If
@bebkovan/server-coreis ever removed from the dependency tree for unrelated reasons, the 40 EvoLogger call sites must be migrated at that time — but as a consequence of the dependency removal, not as a standalone effort.
References¶
libs/shared/src/basic/pre/pre-otel.main.ts:78-82— PinoInstrumentation with customlogKeyslibs/shared/src/logger/pino-logger.module.ts—NestLoggerModule.forRoot()libs/shared/src/basic/base.main.ts—app.useLogger(app.get(Logger))framework logger swap- ADR-0001 — Pino + Winston coexistence decision
docs/observability.md— two-logger explanation and Loki query recipes