add option for file line to colored context layout

This commit is contained in:
einhornimmond 2025-06-15 14:06:24 +02:00
parent 1f3235a34f
commit bb9759ace3
7 changed files with 45 additions and 13 deletions

View File

@ -24,6 +24,7 @@
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^17.0.21",
"jest": "27.2.4",
"typescript": "^4.9.5"
},
"dependencies": {

View File

@ -21,12 +21,6 @@ export const browserUrls = Joi.array()
.required()
.description('All URLs need to have same protocol to prevent mixed block errors')
export const DECAY_START_TIME = Joi.date()
.iso() // ISO 8601 format for date validation
.description('The start time for decay, expected in ISO 8601 format (e.g. 2021-05-13T17:46:31Z)')
.default(new Date('2021-05-13T17:46:31Z')) // default to the specified date if not provided
.required()
export const COMMUNITY_URL = Joi.string()
.uri({ scheme: ['http', 'https'] })
.custom((value: string, helpers: Joi.CustomHelpers<string>) => {
@ -131,6 +125,13 @@ export const LOG4JS_CONFIG = Joi.string()
.default('log4js-config.json')
.required()
export const LOG4JS_CONFIG_PLACEHOLDER = Joi.string()
.pattern(/^[a-zA-Z0-9-_]+(%v)?\.json$/)
.message('LOG4JS_CONFIG_PLACEHOLDER must be a valid filename ending with .json can contain %v as API Version placeholder before ending')
.description('config file name for log4js config file')
.default('log4js-config.json')
.required()
export const LOG_FILES_BASE_PATH = Joi.string()
.pattern(/^[a-zA-Z0-9-_\/\.]+$/)
.message('LOG_FILES_BASE_PATH must be a valid folder name, relative or absolute')

View File

@ -0,0 +1 @@
export const DECAY_START_TIME = new Date('2021-05-13T17:46:31Z')

View File

@ -2,4 +2,6 @@ import 'source-map-support/register'
export * from './commonSchema'
export { DatabaseConfigSchema } from './DatabaseConfigSchema'
export { validate } from './validate'
export { createLog4jsConfig, type Category, initLogger, defaultCategory } from './log4js-config'
export type { LogLevel, Category } from './log4js-config'
export { createLog4jsConfig, initLogger, defaultCategory } from './log4js-config'
export { DECAY_START_TIME } from './const'

View File

@ -5,6 +5,7 @@ import { LogLevel } from './types'
export type coloredContextLayoutConfig = {
withStack?: LogLevel | boolean
withFile?: LogLevel | boolean
withLine?: LogLevel | boolean
}
function colorize(str: string, level: Level): string {
@ -66,12 +67,35 @@ function isEnabledByLogLevel(eventLogLevel: Level, targetLogLevel?: LogLevel | b
return eventLogLevel.isGreaterThanOrEqualTo(targetLogLevel)
}
enum DetailKind {
Callstack = 'callstack',
File = 'file',
Line = 'line',
}
function resolveDetailKind(logEvent: LoggingEvent, config: coloredContextLayoutConfig): DetailKind | undefined {
if (logEvent.callStack && isEnabledByLogLevel(logEvent.level, config.withStack)) {
return DetailKind.Callstack
}
if (isEnabledByLogLevel(logEvent.level, config.withFile)) {
return DetailKind.File
}
if (isEnabledByLogLevel(logEvent.level, config.withLine)) {
return DetailKind.Line
}
return undefined
}
export function createColoredContextLayout(config: coloredContextLayoutConfig) {
return (logEvent: LoggingEvent) => {
const result: string[] = []
const detailKind = resolveDetailKind(logEvent, config)
let categoryName = logEvent.categoryName
if (detailKind === DetailKind.Line) {
categoryName += `:${logEvent.lineNumber}`
}
result.push(
colorize(
`[${logEvent.startTime.toISOString()}] [${logEvent.level}] ${logEvent.categoryName} -`,
`[${logEvent.startTime.toISOString()}] [${logEvent.level}] ${categoryName} -`,
logEvent.level,
),
)
@ -79,12 +103,11 @@ export function createColoredContextLayout(config: coloredContextLayoutConfig) {
result.push(composeContextString(logEvent.context))
}
result.push(composeDataString(logEvent.data))
const showCallstack =
logEvent.callStack && isEnabledByLogLevel(logEvent.level, config.withStack)
if (!showCallstack && isEnabledByLogLevel(logEvent.level, config.withFile)) {
if (detailKind === DetailKind.File) {
result.push(`\n at ${logEvent.fileName}:${logEvent.lineNumber}`)
}
if (showCallstack) {
if (detailKind === DetailKind.Callstack) {
result.push(`\n${logEvent.callStack}`)
}
return result.join(' ')

View File

@ -33,7 +33,7 @@ export function createLog4jsConfig(categories: Category[], basePath?: string): C
customFileAppenders.push({
name: category.name,
filename: category.filename,
withFile: true,
withLine: true,
withStack: 'error',
})
// needed by log4js, show all error message accidentally without (proper) Category

View File

@ -22,10 +22,14 @@ import { LogLevel } from './LogLevel'
* { name: 'warn', filename: 'warn.log', withStack: 'debug' },
* ])
* ```
* if stack is shown, no file and no line is shown, because it is already in the stack trace
* if file:line is shown, no extra line is shown
* line will be shown after category name:line
*/
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
}