From 9914218b81d0d33b09297ef0300555ff3e1efe29 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 28 Feb 2026 19:50:55 +0200 Subject: [PATCH] =?UTF-8?q?enabled=20logging=20as=20well=20=F0=9F=91=8C?= =?UTF-8?q?=F0=9F=98=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/main/package.json | 2 + apps/main/src/instrumentation.server.ts | 18 ++++-- packages/logger/index.ts | 75 +++++------------------- packages/logger/package.json | 5 +- pnpm-lock.yaml | 78 ++++++------------------- 5 files changed, 50 insertions(+), 128 deletions(-) diff --git a/apps/main/package.json b/apps/main/package.json index 2db21c0..8fdc432 100644 --- a/apps/main/package.json +++ b/apps/main/package.json @@ -18,9 +18,11 @@ "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/auto-instrumentations-node": "^0.70.1", + "@opentelemetry/exporter-logs-otlp-proto": "^0.212.0", "@opentelemetry/exporter-metrics-otlp-proto": "^0.212.0", "@opentelemetry/exporter-trace-otlp-proto": "^0.212.0", "@opentelemetry/sdk-node": "^0.212.0", + "@opentelemetry/sdk-logs": "^0.212.0", "@pkg/db": "workspace:*", "@pkg/logger": "workspace:*", "@pkg/logic": "workspace:*", diff --git a/apps/main/src/instrumentation.server.ts b/apps/main/src/instrumentation.server.ts index 0a70058..4184ea0 100644 --- a/apps/main/src/instrumentation.server.ts +++ b/apps/main/src/instrumentation.server.ts @@ -1,6 +1,8 @@ import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node"; +import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto"; import { createAddHookMessageChannel } from "import-in-the-middle"; +import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs"; import { NodeSDK } from "@opentelemetry/sdk-node"; import { settings } from "@pkg/settings"; import { register } from "node:module"; @@ -9,11 +11,17 @@ const { registerOptions } = createAddHookMessageChannel(); register("import-in-the-middle/hook.mjs", import.meta.url, registerOptions); const sdk = new NodeSDK({ - serviceName: settings.appName, - traceExporter: new OTLPTraceExporter({ - // url: settings.otelExporterOtlpHttpEndpoint, - }), - instrumentations: [getNodeAutoInstrumentations()], + serviceName: settings.otelServiceName || settings.appName, + traceExporter: new OTLPTraceExporter(), + logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter())], + instrumentations: [ + getNodeAutoInstrumentations({ + "@opentelemetry/instrumentation-winston": { + // We add OpenTelemetryTransportV3 explicitly in @pkg/logger. + disableLogSending: true, + }, + }), + ], }); sdk.start(); diff --git a/packages/logger/index.ts b/packages/logger/index.ts index 20889e5..319f819 100644 --- a/packages/logger/index.ts +++ b/packages/logger/index.ts @@ -1,15 +1,13 @@ -import DailyRotateFile from "winston-daily-rotate-file"; +import { OpenTelemetryTransportV3 } from "@opentelemetry/winston-transport"; import { settings } from "@pkg/settings"; import type { Err } from "@pkg/result"; import winston from "winston"; import util from "util"; -import path from "path"; process.on("warning", (warning) => { const msg = String(warning?.message || ""); const name = String((warning as any)?.name || ""); - // Ignore the noisy timer warning from Node/kafkajs interplay if ( name === "TimeoutNegativeWarning" || msg.includes("TimeoutNegativeWarning") || @@ -18,7 +16,6 @@ process.on("warning", (warning) => { return; } - // Keep other warnings visible console.warn(warning); }); @@ -28,7 +25,7 @@ const levels = { info: 2, http: 3, debug: 4, -}; +} as const; const colors = { error: "red", @@ -40,13 +37,12 @@ const colors = { const level = () => { const envLevel = process.env.LOG_LEVEL?.toLowerCase(); - if (envLevel && envLevel in Object.keys(levels)) { - return envLevel; + if (envLevel && Object.prototype.hasOwnProperty.call(levels, envLevel)) { + return envLevel as keyof typeof levels; } return settings.isDevelopment ? "debug" : "warn"; }; -// Console format with colors const consoleFormat = winston.format.combine( winston.format.errors({ stack: true }), winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss:ms" }), @@ -54,19 +50,13 @@ const consoleFormat = winston.format.combine( winston.format.printf((info) => { const { level, message, timestamp, ...extra } = info; - let formattedMessage = ""; - if (message instanceof Error) { - formattedMessage = message.stack || message.message; - } else if (typeof message === "object") { - formattedMessage = util.inspect(message, { - depth: null, - colors: true, - }); - } else { - formattedMessage = message as any as string; - } + const formattedMessage = + message instanceof Error + ? message.stack || message.message + : typeof message === "object" + ? util.inspect(message, { depth: null, colors: true }) + : String(message); - // Handle extra fields (if any) const formattedExtra = Object.keys(extra).length > 0 ? `\n${util.inspect(extra, { depth: null, colors: true })}` @@ -76,53 +66,18 @@ const consoleFormat = winston.format.combine( }), ); -// JSON format for file logging -const fileFormat = winston.format.combine( - winston.format.errors({ stack: true }), - winston.format.timestamp(), - winston.format.json(), -); - -// File transport with daily rotation -const fileTransport = new DailyRotateFile({ - filename: path.join("logs", "app-%DATE%.log"), - datePattern: "YYYY-MM-DD", - maxSize: "20m", - maxFiles: "14d", - format: fileFormat, -}); - -// Error file transport with daily rotation -const errorFileTransport = new DailyRotateFile({ - filename: path.join("logs", "error-%DATE%.log"), - datePattern: "YYYY-MM-DD", - maxSize: "20m", - maxFiles: "14d", - level: "error", - format: fileFormat, -}); - -const transports: winston.transport[] = [ - new winston.transports.Console({ format: consoleFormat }), - fileTransport, - errorFileTransport, -]; - winston.addColors(colors); const logger = winston.createLogger({ level: level(), levels, - transports, - format: fileFormat, - exceptionHandlers: [ + format: consoleFormat, + transports: [ new winston.transports.Console({ format: consoleFormat }), - fileTransport, - ], - rejectionHandlers: [ - new winston.transports.Console({ format: consoleFormat }), - fileTransport, + new OpenTelemetryTransportV3(), ], + exceptionHandlers: [new winston.transports.Console({ format: consoleFormat })], + rejectionHandlers: [new winston.transports.Console({ format: consoleFormat })], }); const stream = { write: (message: string) => logger.http(message.trim()) }; diff --git a/packages/logger/package.json b/packages/logger/package.json index 294435d..b2d4e79 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -9,10 +9,9 @@ "typescript": "^5.9.3" }, "dependencies": { - "@axiomhq/winston": "^1.3.1", + "@opentelemetry/winston-transport": "^0.22.0", "@pkg/result": "workspace:*", "@pkg/settings": "workspace:*", - "winston": "^3.17.0", - "winston-daily-rotate-file": "^5.0.0" + "winston": "^3.17.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 025adbb..dbf7c04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,12 +35,18 @@ importers: '@opentelemetry/auto-instrumentations-node': specifier: ^0.70.1 version: 0.70.1(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0)) + '@opentelemetry/exporter-logs-otlp-proto': + specifier: ^0.212.0 + version: 0.212.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-metrics-otlp-proto': specifier: ^0.212.0 version: 0.212.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-trace-otlp-proto': specifier: ^0.212.0 version: 0.212.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': + specifier: ^0.212.0 + version: 0.212.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-node': specifier: ^0.212.0 version: 0.212.0(@opentelemetry/api@1.9.0) @@ -261,9 +267,9 @@ importers: packages/logger: dependencies: - '@axiomhq/winston': - specifier: ^1.3.1 - version: 1.4.0 + '@opentelemetry/winston-transport': + specifier: ^0.22.0 + version: 0.22.0 '@pkg/result': specifier: workspace:* version: link:../result @@ -276,9 +282,6 @@ importers: winston: specifier: ^3.17.0 version: 3.19.0 - winston-daily-rotate-file: - specifier: ^5.0.0 - version: 5.0.0(winston@3.19.0) devDependencies: '@types/bun': specifier: latest @@ -415,14 +418,6 @@ packages: '@ark/util@0.56.0': resolution: {integrity: sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==} - '@axiomhq/js@1.4.0': - resolution: {integrity: sha512-wC5x1ud/QJMstrjpicATkyY8+ZVWEl4WlXMtA5EZf7hkj0+b191yv4yynLxLEfr/MveXora9m6CWdJq4DsbcAg==} - engines: {node: '>=20'} - - '@axiomhq/winston@1.4.0': - resolution: {integrity: sha512-fVHwkWROOOyCuzVSXanMMkw5EVYwwKMal7zk87l6R9Zn69RBvIWVIFC8iSYM9Ea3Cg7t1sJHaDdeKvO9O4NXUw==} - engines: {node: '>=20'} - '@babel/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} @@ -1462,6 +1457,10 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 + '@opentelemetry/winston-transport@0.22.0': + resolution: {integrity: sha512-VuiSjTxfAk5GNuTtBPbvPEDPFV8U9qWgn4DyGHuBNfuJrBcz21mmRyQxpOR+ueG6oA7Nrx7MmTFJ4JiWDvF2Vw==} + engines: {node: ^18.19.0 || >=20.6.0} + '@otplib/core@13.3.0': resolution: {integrity: sha512-pnQDOuCmFVeF/XnboJq9TOJgLoo2idNPJKMymOF8vGqJJ+ReKRYM9bUGjNPRWC0tHjMwu1TXbnzyBp494JgRag==} @@ -2683,12 +2682,6 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} - fetch-retry@6.0.0: - resolution: {integrity: sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag==} - - file-stream-rotator@0.6.1: - resolution: {integrity: sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ==} - find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -3059,9 +3052,6 @@ packages: module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} - moment@2.30.1: - resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -3120,10 +3110,6 @@ packages: resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} engines: {node: '>=14.16'} - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} @@ -3917,12 +3903,6 @@ packages: engines: {node: '>=8'} hasBin: true - winston-daily-rotate-file@5.0.0: - resolution: {integrity: sha512-JDjiXXkM5qvwY06733vf09I2wnMXpZEhxEVOSPenZMii+g7pcDcTBt2MRugnoi8BwVSuCT2jfRXBUy+n1Zz/Yw==} - engines: {node: '>=8'} - peerDependencies: - winston: ^3 - winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -4017,15 +3997,6 @@ snapshots: '@ark/util@0.56.0': optional: true - '@axiomhq/js@1.4.0': - dependencies: - fetch-retry: 6.0.0 - - '@axiomhq/winston@1.4.0': - dependencies: - '@axiomhq/js': 1.4.0 - winston-transport: 4.9.0 - '@babel/runtime@7.28.6': optional: true @@ -5097,6 +5068,11 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/winston-transport@0.22.0': + dependencies: + '@opentelemetry/api-logs': 0.212.0 + winston-transport: 4.9.0 + '@otplib/core@13.3.0': {} '@otplib/hotp@13.3.0': @@ -6140,12 +6116,6 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - fetch-retry@6.0.0: {} - - file-stream-rotator@0.6.1: - dependencies: - moment: 2.30.1 - find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -6560,8 +6530,6 @@ snapshots: module-details-from-path@1.0.4: {} - moment@2.30.1: {} - mri@1.2.0: {} mrmime@2.0.1: {} @@ -6597,8 +6565,6 @@ snapshots: normalize-url@8.1.1: optional: true - object-hash@3.0.0: {} - obug@2.1.1: {} on-exit-leak-free@2.1.2: {} @@ -7339,14 +7305,6 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - winston-daily-rotate-file@5.0.0(winston@3.19.0): - dependencies: - file-stream-rotator: 0.6.1 - object-hash: 3.0.0 - triple-beam: 1.4.1 - winston: 3.19.0 - winston-transport: 4.9.0 - winston-transport@4.9.0: dependencies: logform: 2.7.0