From 6cf82ad87c4c5d39a95dee55c3d2dc57af2cde71 Mon Sep 17 00:00:00 2001 From: einhornimmond Date: Tue, 17 Jun 2025 15:39:37 +0200 Subject: [PATCH] add debug config, refine and test coloredContext --- .github/workflows/test_config.yml | 5 +- .gitignore | 1 + .vscode/launch.json | 58 +++++++- bun.lock | 9 ++ config-schema/package.json | 1 + config-schema/src/log4js-config/appenders.ts | 3 +- .../src/log4js-config/coloredContext.test.ts | 135 ++++++++++++++++++ .../src/log4js-config/coloredContext.ts | 22 ++- config-schema/src/log4js-config/index.test.ts | 28 ++++ config-schema/src/log4js-config/index.ts | 9 +- .../src/log4js-config/types/Category.ts | 8 ++ .../types/ColoredContextLayoutConfig.ts | 7 + .../log4js-config/types/CustomFileAppender.ts | 5 +- .../src/log4js-config/types/index.ts | 1 + config-schema/test/testSetup.ts | 106 +++++++++----- database/src/logging/AbstractLogging.view.ts | 6 +- dht-node/src/dht_node/index.ts | 5 +- dlt-connector/src/server/createServer.ts | 1 - federation/Dockerfile | 3 - federation/package.json | 1 + federation/src/index.ts | 3 +- federation/test/helpers.ts | 3 +- yarn.lock | 7 + 23 files changed, 353 insertions(+), 74 deletions(-) create mode 100644 config-schema/src/log4js-config/coloredContext.test.ts create mode 100644 config-schema/src/log4js-config/index.test.ts create mode 100644 config-schema/src/log4js-config/types/ColoredContextLayoutConfig.ts diff --git a/.github/workflows/test_config.yml b/.github/workflows/test_config.yml index 5ba0832c6..8643bf959 100644 --- a/.github/workflows/test_config.yml +++ b/.github/workflows/test_config.yml @@ -21,7 +21,7 @@ jobs: list-files: shell build: - name: typecheck - Config-Schema + name: Unit Tests, typecheck - Config-Schema if: needs.files-changed.outputs.config == 'true' || needs.files-changed.outputs.docker-compose == 'true' needs: files-changed runs-on: ubuntu-latest @@ -38,3 +38,6 @@ jobs: - name: typecheck run: cd config-schema && yarn typecheck + - name: unit tests + run: cd config-schema && yarn test + diff --git a/.gitignore b/.gitignore index 3d7f34078..d96592bc8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.bak .turbo vite.config.mjs.timestamp-* +log4js-config*.json /node_modules/* messages.pot nbproject diff --git a/.vscode/launch.json b/.vscode/launch.json index 5ef63cc68..5fcb62e09 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,13 +4,6 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "type": "chrome", - "request": "launch", - "name": "Launch Chrome", - "url": "http://localhost:3000", - "webRoot": "${workspaceFolder}/frontend" - }, { "type": "node", "request": "launch", @@ -27,6 +20,23 @@ "internalConsoleOptions": "neverOpen", "cwd": "${workspaceFolder}/dht-node" }, + { + "type": "node", + "request": "launch", + "name": "DHT-Node Debug", + "stopOnEntry": true, + "runtimeExecutable": "yarn", + "runtimeArgs": [ + "run", + "dev" + ], + "skipFiles": [ + "/**" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "openOnSessionStart", + "cwd": "${workspaceFolder}/dht-node" + }, { "type": "node", "request": "launch", @@ -42,6 +52,40 @@ "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "cwd": "${workspaceFolder}/federation" + }, + { + "type": "node", + "request": "launch", + "name": "Federation Debug", + "stopOnEntry": true, + "runtimeExecutable": "yarn", + "runtimeArgs": [ + "run", + "dev" + ], + "skipFiles": [ + "/**" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "openOnSessionStart", + "cwd": "${workspaceFolder}/federation" + }, + { + "type": "node", + "request": "launch", + "name": "Backend Debug", + "stopOnEntry": true, + "runtimeExecutable": "yarn", + "runtimeArgs": [ + "run", + "dev" + ], + "skipFiles": [ + "/**" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "openOnSessionStart", + "cwd": "${workspaceFolder}/backend" } ] } \ No newline at end of file diff --git a/bun.lock b/bun.lock index 4711384ee..cf0f46bb5 100644 --- a/bun.lock +++ b/bun.lock @@ -105,6 +105,7 @@ "@types/node": "^17.0.21", "@types/nodemailer": "^6.4.4", "@types/sodium-native": "^2.3.5", + "@types/source-map-support": "^0.5.10", "@types/uuid": "^8.3.4", "apollo-server-express": "^2.25.2", "apollo-server-testing": "^2.25.2", @@ -143,6 +144,7 @@ "random-bigint": "^0.0.1", "reflect-metadata": "^0.1.13", "regenerator-runtime": "^0.14.1", + "source-map-support": "^0.5.21", "ts-jest": "27.0.5", "ts-node": "^10.9.2", "tsconfig-paths": "^4.1.1", @@ -161,6 +163,7 @@ "dependencies": { "esbuild": "^0.25.2", "joi": "^17.13.3", + "log4js": "^6.9.1", "source-map-support": "^0.5.21", "yoctocolors-cjs": "^2.1.2", "zod": "^3.25.61", @@ -168,6 +171,7 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "@types/node": "^17.0.21", + "jest": "27.2.4", "typescript": "^4.9.5", }, }, @@ -279,6 +283,7 @@ "nodemon": "^2.0.7", "prettier": "^3.5.3", "reflect-metadata": "^0.1.13", + "source-map-support": "^0.5.21", "ts-jest": "27.0.5", "tsconfig-paths": "^4.1.1", "type-graphql": "^1.1.1", @@ -1010,6 +1015,8 @@ "@types/sodium-native": ["@types/sodium-native@2.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-jZIg5ltGH1okmnH3FrLQsgwjcjOVozMSHwSiEm1/LpMekhOMHbQqp21P4H24mizh1BjwI6Q8qmphmD/HJuAqWg=="], + "@types/source-map-support": ["@types/source-map-support@0.5.10", "", { "dependencies": { "source-map": "^0.6.0" } }, "sha512-tgVP2H469x9zq34Z0m/fgPewGhg/MLClalNOiPIzQlXrSS2YrKu/xCdSCKnEDwkFha51VKEKB6A9wW26/ZNwzA=="], + "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="], "@types/uuid": ["@types/uuid@8.3.4", "", {}, "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="], @@ -3454,6 +3461,8 @@ "@types/sodium-native/@types/node": ["@types/node@18.19.96", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-PzBvgsZ7YdFs/Kng1BSW8IGv68/SPcOxYYhT7luxD7QyzIhFS1xPTpfK3K9eHBa7hVwlW+z8nN0mOd515yaduQ=="], + "@types/source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "@types/ws/@types/node": ["@types/node@18.19.96", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-PzBvgsZ7YdFs/Kng1BSW8IGv68/SPcOxYYhT7luxD7QyzIhFS1xPTpfK3K9eHBa7hVwlW+z8nN0mOd515yaduQ=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], diff --git a/config-schema/package.json b/config-schema/package.json index 0b0487255..d5d0494f1 100644 --- a/config-schema/package.json +++ b/config-schema/package.json @@ -18,6 +18,7 @@ "build": "esbuild src/index.ts --outdir=build --sourcemap --platform=node --target=node18.20.7 --bundle --packages=external", "build:bun": "bun build src/index.ts --outdir=build --target=bun --packages=external", "typecheck": "tsc --noEmit", + "test": "bun test", "lint": "biome check --error-on-warnings .", "lint:fix": "biome check --error-on-warnings . --write" }, diff --git a/config-schema/src/log4js-config/appenders.ts b/config-schema/src/log4js-config/appenders.ts index 6648d2924..19f74dccd 100644 --- a/config-schema/src/log4js-config/appenders.ts +++ b/config-schema/src/log4js-config/appenders.ts @@ -68,8 +68,7 @@ export function createAppenderConfig( } dateFile.layout = { type: 'coloredContext', - withStack: appender.withStack, - withFile: appender.withFile, + ...appender.layout, } customAppender[appender.name] = dateFile }) diff --git a/config-schema/src/log4js-config/coloredContext.test.ts b/config-schema/src/log4js-config/coloredContext.test.ts new file mode 100644 index 000000000..38bde4d96 --- /dev/null +++ b/config-schema/src/log4js-config/coloredContext.test.ts @@ -0,0 +1,135 @@ +import { createColoredContextLayout } from './coloredContext' +import { levels, LoggingEvent } from 'log4js' +import colors from 'yoctocolors-cjs' + +let defaultLogEvent: LoggingEvent +let colorFn: (input: string) => string +const startTime = new Date() +const startTimeString = startTime.toISOString() + +describe('createColoredContextLayout', () => { + beforeEach(() => { + defaultLogEvent = { + level: levels.INFO, + categoryName: 'config', + data: ['message'], + context: { user: 1 }, + startTime, + fileName: 'file', + lineNumber: 1, + callStack: 'stack', + pid: 1, + serialise: () => { + throw new Error('Function not implemented.') + }, + } + }) + it('returns a function', () => { + expect(typeof createColoredContextLayout({})).toBe('function') + }) + describe('level:info, color:green', () => { + beforeEach(() => { + defaultLogEvent.level = levels.INFO + colorFn = colors.green + }) + it('format with all undefined', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({})(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with stack', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({ withStack: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \nstack`, + ) + }) + it('format with file', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({ withFile: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \n at file:1`, + ) + }) + it('format with file only if it where level:warn', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({ withFile: 'warn' })(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with line', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config:1 -`) + expect(createColoredContextLayout({ withLine: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with line only if it where level:warn', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({ withLine: 'warn' })(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with file and line', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config -`) + expect(createColoredContextLayout({ withFile: true, withLine: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \n at file:1`, + ) + }) + it('format withStack: error, withLine: true, withFile: warn', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.INFO}] config:1 -`) + expect(createColoredContextLayout({ + withStack: 'error', + withFile: 'warn', + withLine: true + })(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + }) + + describe('level:error, color:red', () => { + beforeEach(() => { + defaultLogEvent.level = levels.ERROR + colorFn = colors.redBright + }) + it('format with all undefined', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config -`) + expect(createColoredContextLayout({})(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with stack', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config -`) + expect(createColoredContextLayout({ withStack: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \nstack`, + ) + }) + it('format with file', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config -`) + expect(createColoredContextLayout({ withFile: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \n at file:1`, + ) + }) + it('format with line', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config:1 -`) + expect(createColoredContextLayout({ withLine: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message`, + ) + }) + it('format with file and line', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config -`) + expect(createColoredContextLayout({ withFile: true, withLine: true })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \n at file:1`, + ) + }) + it('format withStack: error, withLine: true, withFile: warn', () => { + const coloredString = colorFn(`[${startTimeString}] [${levels.ERROR}] config -`) + expect(createColoredContextLayout({ + withStack: 'error', + withFile: 'warn', + withLine: true + })(defaultLogEvent)).toBe( + `${coloredString} user=1 message \nstack`, + ) + }) + }) +}) diff --git a/config-schema/src/log4js-config/coloredContext.ts b/config-schema/src/log4js-config/coloredContext.ts index 21a2d7b28..0fc7476a8 100644 --- a/config-schema/src/log4js-config/coloredContext.ts +++ b/config-schema/src/log4js-config/coloredContext.ts @@ -1,12 +1,6 @@ import { Level, LoggingEvent } from 'log4js' import colors from 'yoctocolors-cjs' -import { LogLevel } from './types' - -export type coloredContextLayoutConfig = { - withStack?: LogLevel | boolean - withFile?: LogLevel | boolean - withLine?: LogLevel | boolean -} +import { LogLevel, ColoredContextLayoutConfig } from './types' function colorize(str: string, level: Level): string { switch (level.colour) { @@ -36,12 +30,14 @@ function colorize(str: string, level: Level): string { // distinguish between objects with valid toString function (for examples classes derived from AbstractLoggingView) and other objects function composeDataString(data: (string | Object)[]): string { return data - .map((data) => { + .map((d) => { // if it is a object and his toString function return only garbage - if (typeof data === 'object' && data.toString() === '[object Object]') { - return JSON.stringify(data) + if (typeof d === 'object' && d.toString() === '[object Object]') { + return JSON.stringify(d) + } + if (d) { + return d.toString() } - return data.toString() }) .join(' ') } @@ -72,7 +68,7 @@ enum DetailKind { File = 'file', Line = 'line', } -function resolveDetailKind(logEvent: LoggingEvent, config: coloredContextLayoutConfig): DetailKind | undefined { +function resolveDetailKind(logEvent: LoggingEvent, config: ColoredContextLayoutConfig): DetailKind | undefined { if (logEvent.callStack && isEnabledByLogLevel(logEvent.level, config.withStack)) { return DetailKind.Callstack } @@ -85,7 +81,7 @@ function resolveDetailKind(logEvent: LoggingEvent, config: coloredContextLayoutC return undefined } -export function createColoredContextLayout(config: coloredContextLayoutConfig) { +export function createColoredContextLayout(config: ColoredContextLayoutConfig) { return (logEvent: LoggingEvent) => { const result: string[] = [] const detailKind = resolveDetailKind(logEvent, config) diff --git a/config-schema/src/log4js-config/index.test.ts b/config-schema/src/log4js-config/index.test.ts new file mode 100644 index 000000000..5f5ea6b5b --- /dev/null +++ b/config-schema/src/log4js-config/index.test.ts @@ -0,0 +1,28 @@ +import { createLog4jsConfig, defaultCategory } from '.' + +describe('createLog4jsConfig', () => { + it('should create a log4js config', () => { + const config = createLog4jsConfig([ + defaultCategory('test', 'debug') + ]) + expect(config).toBeDefined() + expect(config.appenders).toBeDefined() + expect(config.categories).toBeDefined() + expect(config.appenders).toHaveProperty('test') + expect(config.categories).toHaveProperty('test') + expect(config.appenders.test).toMatchObject({ + type: 'dateFile', + pattern: 'yyyy-MM-dd', + compress: true, + keepFileExt: true, + fileNameSep: '_', + numBackups: 30, + filename: 'test.log', + layout: { + type: 'coloredContext', + withStack: 'error', + withLine: true + } + }) + }) +}) \ No newline at end of file diff --git a/config-schema/src/log4js-config/index.ts b/config-schema/src/log4js-config/index.ts index 18699639f..94721d384 100644 --- a/config-schema/src/log4js-config/index.ts +++ b/config-schema/src/log4js-config/index.ts @@ -2,9 +2,11 @@ import { readFileSync, writeFileSync } from 'node:fs' import { Configuration, LoggingEvent, addLayout, configure } from 'log4js' import { createAppenderConfig } from './appenders' import { createColoredContextLayout } from './coloredContext' -import { Category, CustomFileAppender, LogLevel, defaultCategory } from './types' +import type { Category, CustomFileAppender, LogLevel } from './types' +import { defaultCategory } from './types' -export { Category, LogLevel, defaultCategory } +export type { Category, LogLevel } +export { defaultCategory } /** * Creates the log4js configuration. @@ -33,8 +35,7 @@ export function createLog4jsConfig(categories: Category[], basePath?: string): C customFileAppenders.push({ name: category.name, filename: category.filename, - withLine: true, - withStack: 'error', + layout: category.layout, }) // needed by log4js, show all error message accidentally without (proper) Category result.categories.default = { diff --git a/config-schema/src/log4js-config/types/Category.ts b/config-schema/src/log4js-config/types/Category.ts index 889401b30..880fd141b 100644 --- a/config-schema/src/log4js-config/types/Category.ts +++ b/config-schema/src/log4js-config/types/Category.ts @@ -1,4 +1,5 @@ import { LogLevel } from './LogLevel' +import { ColoredContextLayoutConfig } from './ColoredContextLayoutConfig' /** * Configuration for a log4js category. @@ -8,6 +9,7 @@ import { LogLevel } from './LogLevel' * @property {boolean} [stdout] - Whether to log to stdout. * @property {boolean} [additionalErrorsFile] - Whether to log errors additional to the default error file. * @property {LogLevel} level - The logging level. + * @property {ColoredContextLayoutConfig} [layout] - The layout for the category. */ export type Category = { name: string @@ -15,6 +17,7 @@ export type Category = { stdout?: boolean additionalErrorsFile?: boolean level: LogLevel + layout?: ColoredContextLayoutConfig } export function defaultCategory(name: string, level: LogLevel): Category { @@ -23,5 +26,10 @@ export function defaultCategory(name: string, level: LogLevel): Category { level, stdout: true, additionalErrorsFile: true, + layout: { + withStack: 'error', + withFile: 'warn', + withLine: true, + }, } } diff --git a/config-schema/src/log4js-config/types/ColoredContextLayoutConfig.ts b/config-schema/src/log4js-config/types/ColoredContextLayoutConfig.ts new file mode 100644 index 000000000..7084adfa1 --- /dev/null +++ b/config-schema/src/log4js-config/types/ColoredContextLayoutConfig.ts @@ -0,0 +1,7 @@ +import { LogLevel } from './LogLevel' + +export type ColoredContextLayoutConfig = { + withStack?: LogLevel | boolean + withFile?: LogLevel | boolean + withLine?: LogLevel | boolean +} \ No newline at end of file diff --git a/config-schema/src/log4js-config/types/CustomFileAppender.ts b/config-schema/src/log4js-config/types/CustomFileAppender.ts index 46c292349..5bb67769c 100644 --- a/config-schema/src/log4js-config/types/CustomFileAppender.ts +++ b/config-schema/src/log4js-config/types/CustomFileAppender.ts @@ -1,4 +1,5 @@ import { LogLevel } from './LogLevel' +import { ColoredContextLayoutConfig } from './ColoredContextLayoutConfig' /** * use default dateFile Template for custom file appenders * @@ -29,7 +30,5 @@ import { LogLevel } from './LogLevel' export type CustomFileAppender = { name: string filename?: string - withStack?: LogLevel | boolean // with stack if boolean or from log level on or above - withFile?: LogLevel | boolean // with filename and line if boolean or from log level on or above - withLine?: LogLevel | boolean // with line if boolean or from log level on or above + layout?: ColoredContextLayoutConfig } diff --git a/config-schema/src/log4js-config/types/index.ts b/config-schema/src/log4js-config/types/index.ts index e79261487..67279ff57 100644 --- a/config-schema/src/log4js-config/types/index.ts +++ b/config-schema/src/log4js-config/types/index.ts @@ -1,3 +1,4 @@ export * from './Category' export * from './CustomFileAppender' export * from './LogLevel' +export * from './ColoredContextLayoutConfig' diff --git a/config-schema/test/testSetup.ts b/config-schema/test/testSetup.ts index 1d1b63f23..c1d679d8a 100644 --- a/config-schema/test/testSetup.ts +++ b/config-schema/test/testSetup.ts @@ -1,59 +1,99 @@ jest.setTimeout(1000000) -const loggers: { [key: string]: any } = {} -const logs: { level: string; message: string; logger: string; additional: string }[] = [] +type LogEntry = { + level: string; + message: string; + logger: string; + context: string; + additional: any[]; +} -function addLog(level: string, message: string, logger: string, additional: any[]) { - logs.push({ level, message, logger, additional: JSON.stringify(additional, null, 2) }) +const loggers: { [key: string]: any } = {} +const logs: LogEntry[] = [] + +function addLog(level: string, message: string, logger: string, context: Map, additional: any[]) { + logs.push({ + level, + context: [...context.entries()].map(([key, value]) => `${key}=${value}`).join(' ').trimEnd(), + message, + logger, + additional + }) } export function printLogs() { for (const log of logs) { - process.stdout.write(`${log.logger} [${log.level}] ${log.message} ${log.additional}\n`) + const messages = [] + messages.push(log.message) + messages.push(log.additional.map((d) => { + if (typeof d === 'object' && d.toString() === '[object Object]') { + return JSON.stringify(d) + } + if (d) { + return d.toString() + } + }).filter((d) => d)) + process.stdout.write(`${log.logger} [${log.level}] ${log.context} ${messages.join(' ')}\n`) } } -export function cleanLogs(): void { +export function clearLogs(): void { logs.length = 0 } +const getLoggerMocked = jest.fn().mockImplementation((param: any) => { + if (loggers[param]) { + // TODO: check if it is working when tests run in parallel + loggers[param].clearContext() + return loggers[param] + } + // console.log('getLogger called with: ', param) + const fakeLogger = { + context: new Map(), + addContext: jest.fn((key: string, value: string) => { + fakeLogger.context.set(key, value) + }), + trace: jest.fn((message: string, ...args: any[]) => { + addLog('trace', message, param, fakeLogger.context, args) + }), + debug: jest.fn((message: string, ...args: any[]) => { + addLog('debug', message, param, fakeLogger.context, args) + }), + warn: jest.fn((message: string, ...args: any[]) => { + addLog('warn', message, param, fakeLogger.context, args) + }), + info: jest.fn((message: string, ...args: any[]) => { + addLog('info', message, param, fakeLogger.context, args) + }), + error: jest.fn((message: string, ...args: any[]) => { + addLog('error', message, param, fakeLogger.context, args) + }), + fatal: jest.fn((message: string, ...args: any[]) => { + addLog('fatal', message, param, fakeLogger.context, args) + }), + removeContext: jest.fn((key: string) => { + fakeLogger.context.delete(key) + }), + clearContext: jest.fn(() => { + fakeLogger.context.clear() + }) + } + loggers[param] = fakeLogger + return fakeLogger +}) + jest.mock('log4js', () => { const originalModule = jest.requireActual('log4js') return { __esModule: true, ...originalModule, - getLogger: jest.fn().mockImplementation((param: any) => { - // console.log('getLogger called with: ', param) - const fakeLogger = { - addContext: jest.fn(), - trace: jest.fn((message: string, ...args: any[]) => { - addLog('trace', message, param, args) - }), - debug: jest.fn((message: string, ...args: any[]) => { - addLog('debug', message, param, args) - }), - warn: jest.fn((message: string, ...args: any[]) => { - addLog('warn', message, param, args) - }), - info: jest.fn((message: string, ...args: any[]) => { - addLog('info', message, param, args) - }), - error: jest.fn((message: string, ...args: any[]) => { - addLog('error', message, param, args) - }), - fatal: jest.fn((message: string, ...args: any[]) => { - addLog('fatal', message, param, args) - }), - } - loggers[param] = fakeLogger - return fakeLogger - }), + getLogger: getLoggerMocked } }) export function getLogger(name: string) { if (!loggers[name]) { - throw new Error(`No logger with name ${name} was requested from code`) + return getLoggerMocked(name) } return loggers[name] } diff --git a/database/src/logging/AbstractLogging.view.ts b/database/src/logging/AbstractLogging.view.ts index 4d8824cc3..00fdd4703 100644 --- a/database/src/logging/AbstractLogging.view.ts +++ b/database/src/logging/AbstractLogging.view.ts @@ -23,7 +23,11 @@ export abstract class AbstractLoggingView { public dateToString(date: Date | undefined | null): string | undefined { if (date) { - return date.toISOString() + if (date instanceof Date) { + return date.toISOString() + } else { + return new Date(date).toISOString() + } } return undefined } diff --git a/dht-node/src/dht_node/index.ts b/dht-node/src/dht_node/index.ts index 3c88bc1c8..394c5d86c 100644 --- a/dht-node/src/dht_node/index.ts +++ b/dht-node/src/dht_node/index.ts @@ -59,7 +59,6 @@ export const startDHT = async (topic: string): Promise => { const server = node.createServer() server.on('connection', function (socket: any) { - logger.addContext('pubkey', socket.remotePublicKey.toString('hex')) logger.info(`server on... with Remote public key: ${socket.remotePublicKey.toString('hex')}`) socket.on('data', async (data: Buffer) => { @@ -111,10 +110,10 @@ export const startDHT = async (topic: string): Promise => { const variables = { apiVersion: recApiVersion.api, endPoint: recApiVersion.url, - publicKey: socket.remotePublicKey, + publicKey: socket.remotePublicKey.toString('hex'), lastAnnouncedAt: new Date(), } - logger.debug(`upsert with variables=${JSON.stringify(variables)}`) + logger.debug(`upsert with variables=${JSON.stringify(variables, null, 2)}`) // this will NOT update the updatedAt column, to distingue between a normal update and the last announcement await DbFederatedCommunity.createQueryBuilder() .insert() diff --git a/dlt-connector/src/server/createServer.ts b/dlt-connector/src/server/createServer.ts index 25e0a12e2..53bf3ab97 100755 --- a/dlt-connector/src/server/createServer.ts +++ b/dlt-connector/src/server/createServer.ts @@ -26,7 +26,6 @@ const createServer = async ( logger: Logger = dltLogger, // localization: i18n.I18n = i18n, ): Promise => { - logger.addContext('user', 'unknown') logger.debug('createServer...') // connect to db and test db version diff --git a/federation/Dockerfile b/federation/Dockerfile index 070fe3e2a..a8fcfd769 100644 --- a/federation/Dockerfile +++ b/federation/Dockerfile @@ -115,8 +115,5 @@ COPY --chown=app:app --from=build ${DOCKER_WORKDIR}/federation/build/index.js ./ # add node_modules from production_node_modules COPY --chown=app:app --from=production-node-modules ${DOCKER_WORKDIR}/node_modules ./node_modules -# Copy log4js-config.json to provide log configuration -COPY --chown=app:app --from=build ${DOCKER_WORKDIR}/federation/log4js-config.json ./log4js-config.json - # Run command CMD ["node", "index.js"] \ No newline at end of file diff --git a/federation/package.json b/federation/package.json index cf0ab77d4..95c1e5337 100644 --- a/federation/package.json +++ b/federation/package.json @@ -59,6 +59,7 @@ "nodemon": "^2.0.7", "prettier": "^3.5.3", "reflect-metadata": "^0.1.13", + "source-map-support": "^0.5.21", "ts-jest": "27.0.5", "tsconfig-paths": "^4.1.1", "type-graphql": "^1.1.1", diff --git a/federation/src/index.ts b/federation/src/index.ts index eb6404d5c..de2634465 100644 --- a/federation/src/index.ts +++ b/federation/src/index.ts @@ -1,3 +1,4 @@ +import 'source-map-support/register' import { createServer } from './server/createServer' import { defaultCategory, initLogger } from 'config-schema' @@ -7,7 +8,7 @@ import { CONFIG } from './config' import { LOG4JS_BASE_CATEGORY_NAME } from './config/const' async function main() { - // init logger + // init logger const log4jsConfigFileName = CONFIG.LOG4JS_CONFIG_PLACEHOLDER.replace('%v', CONFIG.FEDERATION_API) initLogger( [defaultCategory('federation', CONFIG.LOG_LEVEL), defaultCategory('apollo', CONFIG.LOG_LEVEL)], diff --git a/federation/test/helpers.ts b/federation/test/helpers.ts index 148ef6c54..c8523fe7e 100644 --- a/federation/test/helpers.ts +++ b/federation/test/helpers.ts @@ -4,7 +4,6 @@ import { createTestClient } from 'apollo-server-testing' import { createServer } from '@/server/createServer' import { getLogger } from 'config-schema/test/testSetup' -import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const' export const headerPushMock = jest.fn((t) => { context.token = t.value @@ -26,7 +25,7 @@ export const cleanDB = async () => { } } -export const testEnvironment = async (testLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apollo`) /*, testI18n = i18n */) => { +export const testEnvironment = async (testLogger = getLogger('apollo') /*, testI18n = i18n */) => { const server = await createServer(/* context, */ testLogger /* , testI18n */) const con = server.con const testClient = createTestClient(server.apollo) diff --git a/yarn.lock b/yarn.lock index 9f39a5e23..015b98c5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2569,6 +2569,13 @@ dependencies: "@types/node" "*" +"@types/source-map-support@^0.5.10": + version "0.5.10" + resolved "https://registry.yarnpkg.com/@types/source-map-support/-/source-map-support-0.5.10.tgz#824dcef989496bae98e9d04c8dc1ac1d70e1bd39" + integrity sha512-tgVP2H469x9zq34Z0m/fgPewGhg/MLClalNOiPIzQlXrSS2YrKu/xCdSCKnEDwkFha51VKEKB6A9wW26/ZNwzA== + dependencies: + source-map "^0.6.0" + "@types/stack-utils@^2.0.0": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"