From 1158c3469cd7121d15dfe32414372a73d1ad66d7 Mon Sep 17 00:00:00 2001 From: Romain Lenzotti Date: Wed, 18 Sep 2024 11:14:42 +0200 Subject: [PATCH] fix(logger): remove util.format usage in the codebase for common code --- packages/logger/src/browser/exports.ts | 5 +- .../layouts}/LayoutReplacer.ts | 14 +- packages/logger/src/common/index.ts | 1 - .../common/layouts/components/BasicLayout.ts | 6 +- .../layouts/components/ColoredLayout.ts | 4 +- .../components/MessagePassThroughLayout.ts | 5 +- .../layouts/components/PatternLayout.spec.ts | 2 +- .../layouts/components/PatternLayout.ts | 5 +- .../common/layouts/utils/logEventToObject.ts | 4 +- .../utils/timestampLevelAndCategory.ts | 4 +- packages/logger/src/node/exports.ts | 9 +- .../logger/src/node/layouts/LayoutReplacer.ts | 187 ++++++++++++++++++ 12 files changed, 216 insertions(+), 30 deletions(-) rename packages/logger/src/{common/layouts/class => browser/layouts}/LayoutReplacer.ts (91%) create mode 100644 packages/logger/src/node/layouts/LayoutReplacer.ts diff --git a/packages/logger/src/browser/exports.ts b/packages/logger/src/browser/exports.ts index d246fdb2..12cbf1d8 100644 --- a/packages/logger/src/browser/exports.ts +++ b/packages/logger/src/browser/exports.ts @@ -1,6 +1,9 @@ -import {Logger} from "../common"; +import {Logger, PatternLayout} from "../common"; +import {LayoutReplacer} from "./layouts/LayoutReplacer"; export * from "../common"; export const $log: Logger = new Logger("default"); $log.appenders.set("console", {type: "console", levels: ["info", "debug", "trace", "fatal", "error", "warn"]}); + +PatternLayout.LayoutReplacer = LayoutReplacer; diff --git a/packages/logger/src/common/layouts/class/LayoutReplacer.ts b/packages/logger/src/browser/layouts/LayoutReplacer.ts similarity index 91% rename from packages/logger/src/common/layouts/class/LayoutReplacer.ts rename to packages/logger/src/browser/layouts/LayoutReplacer.ts index f9f7e42e..a07b4ad3 100644 --- a/packages/logger/src/common/layouts/class/LayoutReplacer.ts +++ b/packages/logger/src/browser/layouts/LayoutReplacer.ts @@ -1,11 +1,11 @@ // @ts-ignore import * as dateFormat from "date-format"; -import {LogEvent} from "../../core/LogEvent"; -import {LOG_COLORS} from "../constants/logColors"; -import {colorizeEnd, colorizeStart} from "../utils/colorizeUtils"; -import {IReplacers} from "../interfaces/Replacers"; -import {TokensHandlers} from "../interfaces/BasicLayoutConfiguration"; -import {format} from "../utils/StringUtils"; +import {LogEvent} from "../../common/core/LogEvent"; +import {LOG_COLORS} from "../../common/layouts/constants/logColors"; +import {colorizeEnd, colorizeStart} from "../../common/layouts/utils/colorizeUtils"; +import {IReplacers} from "../../common/layouts/interfaces/Replacers"; +import {TokensHandlers} from "../../common/layouts/interfaces/BasicLayoutConfiguration"; +import {format} from "../../common/layouts/utils/StringUtils"; export class LayoutReplacer { static EOL = "\n"; @@ -131,7 +131,7 @@ export class LayoutReplacer { * @returns {string} */ public pid = (loggingEvent?: LogEvent): string => { - return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : process.pid.toString(); + return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : ""; }; /** * diff --git a/packages/logger/src/common/index.ts b/packages/logger/src/common/index.ts index 1ea52f53..58bce2b9 100644 --- a/packages/logger/src/common/index.ts +++ b/packages/logger/src/common/index.ts @@ -11,7 +11,6 @@ export * from "./core/LogContext"; export * from "./core/LogEvent"; export * from "./core/LogLevel"; export * from "./layouts/class/BaseLayout"; -export * from "./layouts/class/LayoutReplacer"; export * from "./layouts/class/Layouts"; export * from "./layouts/components/BasicLayout"; export * from "./layouts/components/ColoredLayout"; diff --git a/packages/logger/src/common/layouts/components/BasicLayout.ts b/packages/logger/src/common/layouts/components/BasicLayout.ts index a927bb5b..aad4db54 100644 --- a/packages/logger/src/common/layouts/components/BasicLayout.ts +++ b/packages/logger/src/common/layouts/components/BasicLayout.ts @@ -1,8 +1,8 @@ -import * as Util from "util"; import {timestampLevelAndCategory} from "../utils/timestampLevelAndCategory"; import {BaseLayout} from "../class/BaseLayout"; import {LogEvent} from "../../core/LogEvent"; import {Layout} from "../decorators/layout"; +import {format} from "../utils/StringUtils"; @Layout({name: "basic"}) export class BasicLayout extends BaseLayout { @@ -16,8 +16,6 @@ export class BasicLayout extends BaseLayout { * @author Stephan Strittmatter */ transform(loggingEvent: LogEvent, timezoneOffset?: number): string { - return ( - timestampLevelAndCategory(loggingEvent, undefined, timezoneOffset) + (Util.format as any)(...[].concat(loggingEvent.data as any)) - ); + return timestampLevelAndCategory(loggingEvent, undefined, timezoneOffset) + (format as any)(...[].concat(loggingEvent.data as any)); } } diff --git a/packages/logger/src/common/layouts/components/ColoredLayout.ts b/packages/logger/src/common/layouts/components/ColoredLayout.ts index 9b7e2b54..b9c4e6dc 100644 --- a/packages/logger/src/common/layouts/components/ColoredLayout.ts +++ b/packages/logger/src/common/layouts/components/ColoredLayout.ts @@ -1,9 +1,9 @@ -import * as Util from "util"; import {LogEvent} from "../../core/LogEvent"; import {timestampLevelAndCategory} from "../utils/timestampLevelAndCategory"; import {LOG_COLORS} from "../constants/logColors"; import {Layout} from "../decorators/layout"; import {BaseLayout} from "../class/BaseLayout"; +import {format} from "../utils/StringUtils"; @Layout({name: "colored"}) export class ColoredLayout extends BaseLayout { @@ -14,6 +14,6 @@ export class ColoredLayout extends BaseLayout { transform(loggingEvent: LogEvent, timezoneOffset?: number): string { const index: any = loggingEvent.level.toString(); const color = LOG_COLORS[index as keyof typeof LOG_COLORS]; - return timestampLevelAndCategory(loggingEvent, color, timezoneOffset) + (Util.format as any)(...[].concat(loggingEvent.data as any)); + return timestampLevelAndCategory(loggingEvent, color, timezoneOffset) + (format as any)(...[].concat(loggingEvent.data as any)); } } diff --git a/packages/logger/src/common/layouts/components/MessagePassThroughLayout.ts b/packages/logger/src/common/layouts/components/MessagePassThroughLayout.ts index d73c6fcd..09cd3722 100644 --- a/packages/logger/src/common/layouts/components/MessagePassThroughLayout.ts +++ b/packages/logger/src/common/layouts/components/MessagePassThroughLayout.ts @@ -1,11 +1,12 @@ import {BaseLayout} from "../class/BaseLayout"; import {LogEvent} from "../../core/LogEvent"; import {Layout} from "../decorators/layout"; -import * as Util from "util"; +import {format} from "../utils/StringUtils"; @Layout({name: "messagePassThrough"}) export class MessagePassThroughLayout extends BaseLayout { transform(loggingEvent: LogEvent, timezoneOffset?: number): string { - return (Util.format as any)(...[].concat(loggingEvent.data as any)); + // @ts-ignore + return format(...[].concat(loggingEvent.data as any)); } } diff --git a/packages/logger/src/common/layouts/components/PatternLayout.spec.ts b/packages/logger/src/common/layouts/components/PatternLayout.spec.ts index 3c7b4843..e294bc2b 100644 --- a/packages/logger/src/common/layouts/components/PatternLayout.spec.ts +++ b/packages/logger/src/common/layouts/components/PatternLayout.spec.ts @@ -4,7 +4,7 @@ import * as os from "os"; // @ts-ignore import * as dateFormat from "date-format"; import {PatternLayout} from "./PatternLayout"; -import {LayoutReplacer} from "../class/LayoutReplacer"; +import {LayoutReplacer} from "../../../node/layouts/LayoutReplacer"; const EOL = os.EOL || "\n"; LayoutReplacer.HOSTNAME = "hostname"; diff --git a/packages/logger/src/common/layouts/components/PatternLayout.ts b/packages/logger/src/common/layouts/components/PatternLayout.ts index e1730b31..761bfd26 100644 --- a/packages/logger/src/common/layouts/components/PatternLayout.ts +++ b/packages/logger/src/common/layouts/components/PatternLayout.ts @@ -1,7 +1,6 @@ import {truncateAndPad} from "../utils/StringUtils"; import {BaseLayout} from "../class/BaseLayout"; import {IReplacers} from "../interfaces/Replacers"; -import {LayoutReplacer} from "../class/LayoutReplacer"; import {LogEvent} from "../../core/LogEvent"; import {BasicLayoutConfiguration, TokensHandlers} from "../interfaces/BasicLayoutConfiguration"; import {Layout} from "../decorators/layout"; @@ -48,12 +47,14 @@ export class PatternLayout extends BaseLayout { readonly #tokens: TokensHandlers; readonly #pattern: string; + static LayoutReplacer: any; + constructor(config: BasicLayoutConfiguration) { super(config); this.#pattern = (config && config.pattern) || TTCC_CONVERSION_PATTERN; this.#tokens = config && config.tokens!; - this.#replacers = new LayoutReplacer(this.#tokens, this.config.timezoneOffset).build(); + this.#replacers = new PatternLayout.LayoutReplacer(this.#tokens, this.config.timezoneOffset).build(); } /** diff --git a/packages/logger/src/common/layouts/utils/logEventToObject.ts b/packages/logger/src/common/layouts/utils/logEventToObject.ts index 5156cf52..ed735c8d 100644 --- a/packages/logger/src/common/layouts/utils/logEventToObject.ts +++ b/packages/logger/src/common/layouts/utils/logEventToObject.ts @@ -1,6 +1,6 @@ -import Util from "util"; import {LogEvent} from "../../core/LogEvent"; import {removeColors} from "./colorizeUtils"; +import {format} from "./StringUtils"; export function logEventToObject(loggingEvent: LogEvent) { const log: any = { @@ -21,7 +21,7 @@ export function logEventToObject(loggingEvent: LogEvent) { return data; } - return [...data, removeColors(Util.format(current))]; + return [...data, removeColors(format(current))]; }, []); return log; diff --git a/packages/logger/src/common/layouts/utils/timestampLevelAndCategory.ts b/packages/logger/src/common/layouts/utils/timestampLevelAndCategory.ts index f26311e0..6af180a8 100644 --- a/packages/logger/src/common/layouts/utils/timestampLevelAndCategory.ts +++ b/packages/logger/src/common/layouts/utils/timestampLevelAndCategory.ts @@ -1,12 +1,12 @@ -import * as Util from "util"; // @ts-ignore import * as dateFormat from "date-format"; import {colorize} from "./colorizeUtils"; import {LogEvent} from "../../core/LogEvent"; +import {format} from "./StringUtils"; export function timestampLevelAndCategory(loggingEvent: LogEvent, colour: any, timezoneOffset: number | undefined) { return colorize( - Util.format( + format( "[%s] [%s] [%s] - ", dateFormat.asString(loggingEvent.startTime, timezoneOffset), loggingEvent.formattedLevel, diff --git a/packages/logger/src/node/exports.ts b/packages/logger/src/node/exports.ts index aee29180..2697a4fc 100644 --- a/packages/logger/src/node/exports.ts +++ b/packages/logger/src/node/exports.ts @@ -1,8 +1,7 @@ -import Os from "os"; -import Util from "util"; -import {LayoutReplacer, Logger} from "../common/index"; +import {Logger, PatternLayout} from "../common/index"; import "./appenders/StdoutAppender"; import "./appenders/StderrAppender"; +import {LayoutReplacer} from "./layouts/LayoutReplacer"; export const $log: Logger = new Logger("default"); @@ -10,6 +9,4 @@ $log.appenders .set("stdout", {type: "stdout", levels: ["info", "debug"]}) .set("stderr", {type: "stderr", levels: ["trace", "fatal", "error", "warn"]}); -LayoutReplacer.EOL = Os.EOL || "\n"; -LayoutReplacer.HOSTNAME = Os.hostname().toString(); -LayoutReplacer.formatter = Util.format; +PatternLayout.LayoutReplacer = LayoutReplacer; diff --git a/packages/logger/src/node/layouts/LayoutReplacer.ts b/packages/logger/src/node/layouts/LayoutReplacer.ts new file mode 100644 index 00000000..ea27761d --- /dev/null +++ b/packages/logger/src/node/layouts/LayoutReplacer.ts @@ -0,0 +1,187 @@ +// @ts-ignore +import * as dateFormat from "date-format"; +import {LogEvent} from "../../common/core/LogEvent"; +import {LOG_COLORS} from "../../common/layouts/constants/logColors"; +import {colorizeEnd, colorizeStart} from "../../common/layouts/utils/colorizeUtils"; +import {IReplacers} from "../../common/layouts/interfaces/Replacers"; +import {TokensHandlers} from "../../common/layouts/interfaces/BasicLayoutConfiguration"; +import Os from "os"; +import Util from "util"; + +export class LayoutReplacer { + static EOL = Os.EOL || "\n"; + static HOSTNAME = Os.hostname().toString(); + static formatter = Util.format; + + constructor( + private tokens: TokensHandlers, + private timezoneOffset: number + ) {} + + /** + * + * @param loggingEvent + * @param specifier + * @returns {any} + */ + public categoryName = (loggingEvent: LogEvent, specifier: string): string => { + let loggerName = loggingEvent.categoryName; + if (specifier) { + const precision = parseInt(specifier, 10); + const loggerNameBits = loggerName.split("."); + if (precision < loggerNameBits.length) { + loggerName = loggerNameBits.slice(loggerNameBits.length - precision).join("."); + } + } + return loggerName; + }; + /** + * + * @param loggingEvent + * @param specifier + * @returns {any} + */ + public formatAsDate = (loggingEvent: LogEvent, specifier: string): string => { + let format = dateFormat.ISO8601_FORMAT; + if (specifier) { + format = specifier; + // Pick up special cases + if (format === "ISO8601") { + format = dateFormat.ISO8601_FORMAT; + } else if (format === "ISO8601_WITH_TZ_OFFSET") { + format = dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT; + } else if (format === "ABSOLUTE") { + format = dateFormat.ABSOLUTETIME_FORMAT; + } else if (format === "DATE") { + format = dateFormat.DATETIME_FORMAT; + } + } + // Format the date + return dateFormat.asString(format, loggingEvent.startTime, this.timezoneOffset); + }; + /** + * + * @returns {string} + */ + public hostname = (): string => { + return LayoutReplacer.HOSTNAME || ""; + }; + /** + * + * @param loggingEvent + * @returns {any} + */ + public formatMessage = (loggingEvent: LogEvent): string => { + return (LayoutReplacer.formatter as any)(...loggingEvent.data); + }; + + public formatJson = (loggingEvent: LogEvent): string => { + return JSON.stringify(loggingEvent.data); + }; + /** + * + * @returns {string|string} + */ + public endOfLine = () => { + return LayoutReplacer.EOL; + }; + /** + * + * @param loggingEvent + * @returns {string} + */ + public logLevel = (loggingEvent: LogEvent): string => { + return loggingEvent.level.toString(); + }; + /** + * + * @param loggingEvent + * @returns {any} + */ + public startTime = (loggingEvent: LogEvent): string => { + return dateFormat.asString("hh:mm:ss", loggingEvent.startTime, this.timezoneOffset); + }; + /** + * + * @param loggingEvent + * @returns {string} + */ + public startColour = (loggingEvent: LogEvent): string => { + const index: any = loggingEvent.level.toString(); + return colorizeStart(LOG_COLORS[index as keyof typeof LOG_COLORS]); + }; + /** + * + * @param loggingEvent + * @returns {string} + */ + public endColour = (loggingEvent: LogEvent): string => { + const index: any = loggingEvent.level.toString(); + return colorizeEnd(LOG_COLORS[index as keyof typeof LOG_COLORS]); + }; + /** + * + * @returns {string} + */ + public percent = () => { + return "%"; + }; + /** + * + * @param loggingEvent + * @returns {string} + */ + public pid = (loggingEvent?: LogEvent): string => { + return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : process.pid.toString(); + }; + /** + * + * @param loggingEvent + * @param specifier + * @returns {any} + */ + public clusterInfo = (loggingEvent: LogEvent, specifier: string) => { + if (loggingEvent.cluster && specifier) { + return specifier + .replace("%m", loggingEvent.cluster.master) + .replace("%w", loggingEvent.cluster.worker) + .replace("%i", loggingEvent.cluster.workerId); + } else if (loggingEvent.cluster) { + return `${loggingEvent.cluster.worker}@${loggingEvent.cluster.master}`; + } + + return this.pid(); + }; + /** + * + * @param loggingEvent + * @param specifier + * @returns {any} + */ + public userDefined = (loggingEvent: LogEvent, specifier: string) => { + if (typeof this.tokens[specifier] !== "undefined") { + return typeof this.tokens[specifier] === "function" ? this.tokens[specifier](loggingEvent) : this.tokens[specifier]; + } + + return null; + }; + + build(): IReplacers { + return { + c: this.categoryName, + d: this.formatAsDate, + h: this.hostname, + m: this.formatMessage, + j: this.formatJson, + n: this.endOfLine, + p: this.logLevel, + r: this.startTime, + "[": this.startColour, + "]": this.endColour, + y: this.clusterInfo, + z: this.pid, + "%": this.percent, + x: this.userDefined + }; + } +}