add debug config, refine and test coloredContext

This commit is contained in:
einhornimmond 2025-06-17 15:39:37 +02:00
parent bfa9367050
commit 6cf82ad87c
23 changed files with 353 additions and 74 deletions

View File

@ -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

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
*.bak
.turbo
vite.config.mjs.timestamp-*
log4js-config*.json
/node_modules/*
messages.pot
nbproject

58
.vscode/launch.json vendored
View File

@ -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": [
"<node_internals>/**"
],
"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": [
"<node_internals>/**"
],
"console": "integratedTerminal",
"internalConsoleOptions": "openOnSessionStart",
"cwd": "${workspaceFolder}/federation"
},
{
"type": "node",
"request": "launch",
"name": "Backend Debug",
"stopOnEntry": true,
"runtimeExecutable": "yarn",
"runtimeArgs": [
"run",
"dev"
],
"skipFiles": [
"<node_internals>/**"
],
"console": "integratedTerminal",
"internalConsoleOptions": "openOnSessionStart",
"cwd": "${workspaceFolder}/backend"
}
]
}

View File

@ -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=="],

View File

@ -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"
},

View File

@ -68,8 +68,7 @@ export function createAppenderConfig(
}
dateFile.layout = {
type: 'coloredContext',
withStack: appender.withStack,
withFile: appender.withFile,
...appender.layout,
}
customAppender[appender.name] = dateFile
})

View File

@ -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`,
)
})
})
})

View File

@ -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)

View File

@ -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
}
})
})
})

View File

@ -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 = {

View File

@ -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,
},
}
}

View File

@ -0,0 +1,7 @@
import { LogLevel } from './LogLevel'
export type ColoredContextLayoutConfig = {
withStack?: LogLevel | boolean
withFile?: LogLevel | boolean
withLine?: LogLevel | boolean
}

View File

@ -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
}

View File

@ -1,3 +1,4 @@
export * from './Category'
export * from './CustomFileAppender'
export * from './LogLevel'
export * from './ColoredContextLayoutConfig'

View File

@ -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<string, string>, 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<string, string>(),
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]
}

View File

@ -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
}

View File

@ -59,7 +59,6 @@ export const startDHT = async (topic: string): Promise<void> => {
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<void> => {
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()

View File

@ -26,7 +26,6 @@ const createServer = async (
logger: Logger = dltLogger,
// localization: i18n.I18n = i18n,
): Promise<ServerDef> => {
logger.addContext('user', 'unknown')
logger.debug('createServer...')
// connect to db and test db version

View File

@ -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"]

View File

@ -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",

View File

@ -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)],

View File

@ -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)

View File

@ -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"