Skip to content

Commit

Permalink
fix(logger): fix util.format polyfill to accept object as given param…
Browse files Browse the repository at this point in the history
…eter
  • Loading branch information
Romakita committed Sep 18, 2024
1 parent d0170b6 commit 60e4c62
Show file tree
Hide file tree
Showing 36 changed files with 220 additions and 138 deletions.
2 changes: 1 addition & 1 deletion packages/connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@
"peerDependencies": {
"@tsed/logger": "6.7.6"
}
}
}
2 changes: 1 addition & 1 deletion packages/file/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
"peerDependencies": {
"@tsed/logger": "6.7.6"
}
}
}
2 changes: 1 addition & 1 deletion packages/insight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
"peerDependencies": {
"@tsed/logger": "6.7.6"
}
}
}
2 changes: 1 addition & 1 deletion packages/logentries/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
"peerDependencies": {
"@tsed/logger": "6.7.6"
}
}
}
14 changes: 12 additions & 2 deletions packages/logger/.barrelsby.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"directory": ["./src/common", "./src/browser", "./src/node"],
"exclude": ["__mock__", "__mocks__", ".spec.ts"],
"directory": [
"./src/common",
"./src/browser",
"./src/node"
],
"exclude": [
"__mock__",
"__mocks__",
".spec.ts",
"utils",
"LayoutReplacer"
],
"delete": true
}
5 changes: 3 additions & 2 deletions packages/logger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,6 @@
"barrelsby": "^2.8.1",
"typescript": "5.4.2",
"vite": "5.1.6"
}
}
},
"peerDependencies": {}
}
4 changes: 3 additions & 1 deletion packages/logger/src/browser/exports.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {Logger, PatternLayout} from "../common";
import {Logger, PatternLayout, StringUtils} from "../common";
import {LayoutReplacer} from "./layouts/LayoutReplacer";
import {format} from "./utils/format";

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;
StringUtils.format = format;
1 change: 0 additions & 1 deletion packages/logger/src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
*/

export * from "./exports";
export * from "./layouts/LayoutReplacer";
2 changes: 1 addition & 1 deletion packages/logger/src/browser/layouts/LayoutReplacer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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";
import {format} from "../utils/format";

export class LayoutReplacer {
static EOL = "\n";
Expand Down
58 changes: 58 additions & 0 deletions packages/logger/src/browser/utils/format.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {format} from "./format";

describe("format()", () => {
it("should use format string", () => {
const res = format("foo");
expect(res).toEqual("foo");
});

it("should format string (%s)", () => {
const res = format("%s", "foo");
expect(res).toEqual("foo");
});

it("should format multiple strings (%s:%s)", () => {
const res = format("%s:%s", "foo", "bar");
expect(res).toEqual("foo:bar");
});

it("should format digit as NaN (%d)", () => {
const res = format("%d", "foo");
expect(res).toEqual("NaN");
});

it("should format digit (%d)", () => {
const res = format("%d", "16");
expect(res).toEqual("16");
});

it("should format json string (%j)", () => {
const res = format("%j", "foo");
expect(res).toEqual('"foo"');
});

it("should format json array (%j)", () => {
const res = format("%j", [1, 2, 3]);
expect(res).toEqual("[1,2,3]");
});

it("should format object string (%o)", () => {
const res = format("%o", "foo");
expect(res).toEqual("foo");
});

it("should format error (%o)", () => {
const res = format("%o", new Error("mock error"));
expect(res).toEqual("Error: mock error");
});

it("should format object array (%o)", () => {
const res = format("%o", [1, 2, 3]);
expect(res).toEqual("[1,2,3]");
});

it("should format escaped string (%s)", () => {
const res = format("%%s", "foo");
expect(res).toEqual("%s foo");
});
});
48 changes: 48 additions & 0 deletions packages/logger/src/browser/utils/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export function format(fmt: string | object, ...args: unknown[]) {
const re = /(%?)(%([ojds]))/g;

if (typeof fmt === "object") {
fmt = JSON.stringify(fmt, null, 2);
}

if (args.length) {
const replacer = (match: any, escaped: any, ptn: any, flag: any) => {
let arg = args.shift();
switch (flag) {
case "o":
if (Array.isArray(arg)) {
arg = JSON.stringify(arg);
break;
}
case "s":
arg = "" + arg;
break;
case "d":
arg = Number(arg);
break;
case "j":
arg = JSON.stringify(arg);
break;
}

if (!escaped) {
return arg;
}

args.unshift(arg);
return match;
};

fmt = String(fmt).replace(re, replacer);
}

// arguments remain after formatting
if (args.length) {
fmt += " " + args.join(" ");
}

// update escaped %% values
fmt = String(fmt).replace(/%{2,2}/g, "%");

return "" + fmt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import {ConsoleAppender} from "./ConsoleAppender";
import {LogEvent} from "../../core/LogEvent";
import {levels} from "../../core/LogLevel";
import "../../layouts/components/ColoredLayout";
import {StringUtils} from "../../layouts/utils/StringUtils";
import {format} from "node:util";

StringUtils.format = format;

describe("ConsoleAppender", () => {
it("should log something", () => {
Expand Down
5 changes: 0 additions & 5 deletions packages/logger/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,5 @@ export * from "./layouts/decorators/layout";
export * from "./layouts/interfaces/BasicLayoutConfiguration";
export * from "./layouts/interfaces/Replacers";
export * from "./layouts/registries/LayoutsRegistry";
export * from "./layouts/utils/StringUtils";
export * from "./layouts/utils/colorizeUtils";
export * from "./layouts/utils/logEventToObject";
export * from "./layouts/utils/timestampLevelAndCategory";
export * from "./logger/class/Logger";
export * from "./logger/class/LoggerAppenders";
export * from "./logger/utils/tableUtils";
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {LogEvent} from "../../core/LogEvent";
import {levels} from "../../core/LogLevel";
import {BasicLayout} from "./BasicLayout";
import {StringUtils} from "../utils/StringUtils";
import {format} from "node:util";

StringUtils.format = format;

describe("BasicLayout", () => {
it("should return a formated string", () => {
Expand Down
7 changes: 5 additions & 2 deletions packages/logger/src/common/layouts/components/BasicLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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";
import {StringUtils} from "../utils/StringUtils";

@Layout({name: "basic"})
export class BasicLayout extends BaseLayout {
Expand All @@ -16,6 +16,9 @@ export class BasicLayout extends BaseLayout {
* @author Stephan Strittmatter
*/
transform(loggingEvent: LogEvent, timezoneOffset?: number): string {
return timestampLevelAndCategory(loggingEvent, undefined, timezoneOffset) + (format as any)(...[].concat(loggingEvent.data as any));
return (
timestampLevelAndCategory(loggingEvent, undefined, timezoneOffset) +
(StringUtils.format as any)(...[].concat(loggingEvent.data as any))
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {LogEvent} from "../../core/LogEvent";
import {levels} from "../../core/LogLevel";
import {ColoredLayout} from "./ColoredLayout";
import {StringUtils} from "../utils/StringUtils";
import {format} from "node:util";

StringUtils.format = format;

describe("ColoredLayout", () => {
it("should return a formatted string", () => {
Expand All @@ -18,4 +22,37 @@ describe("ColoredLayout", () => {

expect(result).toEqual(expect.stringContaining("[36m[2017-06-18T22:29:38.234] [DEBUG] [category] - data"));
});

it("should return a formatted string from object", () => {
const layout = new ColoredLayout({
type: "colored"
});

const context = new Map();
context.set("user", "romain");

const logEvent = new LogEvent(
"category",
levels().DEBUG,
[
{
id: "id",
event: "event",
headers: {
accept: "application/json"
}
}
],
context as any
);
(logEvent as any)._startTime = new Date("2017-06-18 22:29:38.234");

const result = layout.transform(logEvent);

expect(result).toEqual(
expect.stringContaining(
"[2017-06-18T22:29:38.234] [DEBUG] [category] - { id: 'id', event: 'event', headers: { accept: 'application/json' } }"
)
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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";
import {StringUtils} from "../utils/StringUtils";

@Layout({name: "colored"})
export class ColoredLayout extends BaseLayout {
Expand All @@ -14,6 +14,8 @@ 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) + (format as any)(...[].concat(loggingEvent.data as any));
return (
timestampLevelAndCategory(loggingEvent, color, timezoneOffset) + (StringUtils.format as any)(...[].concat(loggingEvent.data as any))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import {LogEvent} from "../../core/LogEvent";
import {levels} from "../../core/LogLevel";
import {JsonLayout} from "./JsonLayout";
import {LogContext} from "../../core/LogContext";
import {StringUtils} from "../utils/StringUtils";
import {format} from "node:util";

StringUtils.format = format;

describe("JsonLayout", () => {
describe("when separator is given", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {LogEvent} from "../../core/LogEvent";
import {levels} from "../../core/LogLevel";
import {MessagePassThroughLayout} from "./MessagePassThroughLayout";
import {StringUtils} from "../utils/StringUtils";
import {format} from "node:util";

StringUtils.format = format;

describe("MessagePassThroughLayout", () => {
it("should return a formatted string", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {BaseLayout} from "../class/BaseLayout";
import {LogEvent} from "../../core/LogEvent";
import {Layout} from "../decorators/layout";
import {format} from "../utils/StringUtils";
import {StringUtils} from "../utils/StringUtils";

@Layout({name: "messagePassThrough"})
export class MessagePassThroughLayout extends BaseLayout {
transform(loggingEvent: LogEvent, timezoneOffset?: number): string {
// @ts-ignore
return format(...[].concat(loggingEvent.data as any));
return StringUtils.format(...[].concat(loggingEvent.data as any));
}
}
Loading

0 comments on commit 60e4c62

Please sign in to comment.