Skip to content

Commit

Permalink
Make JSON output appear in one line, Fix #191
Browse files Browse the repository at this point in the history
  • Loading branch information
terehov committed Dec 20, 2022
1 parent f915a80 commit 43b8e9a
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 127 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ Example on changing `minLevel` on runtime:
- `json` prints out a `JSON` formatted log entry.
- `hidden` suppresses any output whatsoever and can be used with attached loggers for example.

> Hint: Each JSON log is printed in one line, making it easily parsable by external services.
```typescript
// pretty output
const defaultPrettyLogger = new Logger();
Expand Down
17 changes: 16 additions & 1 deletion src/runtime/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,22 @@ export function transportFormatted<LogObj>(logMetaMarkup: string, logArgs: unkno
}

export function transportJSON<LogObj>(json: LogObj & ILogObjMeta): void {
console.log(JSON.stringify(json, null, 2));
console.log(jsonStringifyRecursive(json));

function jsonStringifyRecursive(obj: unknown) {
const cache = new Set();
return JSON.stringify(obj, (key, value) => {
if (typeof value === "object" && value !== null) {
if (cache.has(value)) {
// Circular reference found, discard key
return "[Circular]";
}
// Store value in our collection
cache.add(value);
}
return value;
});
}
}

export function isBuffer(arg: unknown) {
Expand Down
24 changes: 10 additions & 14 deletions src/runtime/nodejs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,21 +145,17 @@ export function transportJSON<LogObj>(json: LogObj & ILogObjMeta): void {

function jsonStringifyRecursive(obj: unknown) {
const cache = new Set();
return JSON.stringify(
obj,
(key, value) => {
if (typeof value === "object" && value !== null) {
if (cache.has(value)) {
// Circular reference found, discard key
return "[Circular]";
}
// Store value in our collection
cache.add(value);
return JSON.stringify(obj, (key, value) => {
if (typeof value === "object" && value !== null) {
if (cache.has(value)) {
// Circular reference found, discard key
return "[Circular]";
}
return value;
},
2
);
// Store value in our collection
cache.add(value);
}
return value;
});
}
}

Expand Down
16 changes: 8 additions & 8 deletions tests/Browser/1_json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ describe("Browser: JSON: Log level", () => {
logger.silly("Test");
});

expect(consoleOutput).toContain('"0": "Test"');
expect(consoleOutput).toContain('"_meta": {');
expect(consoleOutput).toContain('"runtime": "Browser"');
expect(consoleOutput).toContain(`"date": "${new Date().toISOString().split(".")[0]}`); // ignore ms
expect(consoleOutput).toContain('"logLevelId": 0');
expect(consoleOutput).toContain('"logLevelName": "SILLY"');
expect(consoleOutput).toContain('"path": {');
expect(consoleOutput).toContain('"fileLine": "4"');
expect(consoleOutput).toContain('"0":"Test"');
expect(consoleOutput).toContain('"_meta":{');
expect(consoleOutput).toContain('"runtime":"Browser"');
expect(consoleOutput).toContain(`"date":"${new Date().toISOString().split(".")[0]}`); // ignore ms
expect(consoleOutput).toContain('"logLevelId":0');
expect(consoleOutput).toContain('"logLevelName":"SILLY"');
expect(consoleOutput).toContain('"path":{');
expect(consoleOutput).toContain('"fileLine":"4"');
});

it("pretty", async () => {
Expand Down
56 changes: 28 additions & 28 deletions tests/Nodejs/1_json_loglevel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,57 @@ describe("JSON: Log level", () => {

test("silly (console)", (): void => {
logger.silly("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"runtime": "');
expect(getConsoleLog()).toContain('"hostname": "');
expect(getConsoleLog()).toContain(`"date": "${new Date().toISOString().split("T")[0]}`); // ignore time
expect(getConsoleLog()).toContain('"logLevelId": 0');
expect(getConsoleLog()).toContain('"logLevelName": "SILLY"');
expect(getConsoleLog()).toContain('"path": {');
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/1_json_loglevel.test.ts",');
expect(getConsoleLog()).toContain('"fileLine": "20"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"runtime":"');
expect(getConsoleLog()).toContain('"hostname":"');
expect(getConsoleLog()).toContain(`"date":"${new Date().toISOString().split("T")[0]}`); // ignore time
expect(getConsoleLog()).toContain('"logLevelId":0');
expect(getConsoleLog()).toContain('"logLevelName":"SILLY"');
expect(getConsoleLog()).toContain('"path":{');
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/1_json_loglevel.test.ts",');
expect(getConsoleLog()).toContain('"fileLine":"20"');
});

test("trace (console)", (): void => {
logger.trace("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "TRACE"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"TRACE"');
});

test("debug (console)", (): void => {
logger.debug("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "DEBUG"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"DEBUG"');
});

test("info (console)", (): void => {
logger.info("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "INFO"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"INFO"');
});

test("warn (console)", (): void => {
logger.warn("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "WARN"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"WARN"');
});

test("error (console)", (): void => {
logger.error("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "ERROR"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"ERROR"');
});

test("fatal (console)", (): void => {
logger.fatal("Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"_meta": {');
expect(getConsoleLog()).toContain('"logLevelName": "FATAL"');
expect(getConsoleLog()).toContain('"0":"Test"');
expect(getConsoleLog()).toContain('"_meta":{');
expect(getConsoleLog()).toContain('"logLevelName":"FATAL"');
});
});
52 changes: 17 additions & 35 deletions tests/Nodejs/4_json_Log_Types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,32 @@ describe("JSON: Log Types", () => {
test("plain string", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", "Test");
expect(getConsoleLog()).toContain('"0": "Test"');
expect(getConsoleLog()).toContain('"0":"Test"');
});

test("two plain string", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", "Test1", "Test2");
expect(getConsoleLog()).toContain('"0": "Test1"');
expect(getConsoleLog()).toContain('"1": "Test2"');
expect(getConsoleLog()).toContain('"0":"Test1"');
expect(getConsoleLog()).toContain('"1":"Test2"');
});

test("boolean", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", true);
expect(getConsoleLog()).toContain('"0": true');
expect(getConsoleLog()).toContain('"0":true');
});

test("number", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", 555);
expect(getConsoleLog()).toContain('"0": 555');
expect(getConsoleLog()).toContain('"0":555');
});

test("Array", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", [1, 2, 3, "test"]);
expect(getConsoleLog()).toContain(`[
1,
2,
3,`);
expect(getConsoleLog()).toContain(`[1,2,3,`);
});

test("Buffer", (): void => {
Expand All @@ -54,12 +51,7 @@ describe("JSON: Log Types", () => {
test("Object", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", { test: true, nested: { 1: false } });
expect(getConsoleLog()).toContain(`{
"test": true,
"nested": {
"1": false
},
"_meta": {`);
expect(getConsoleLog()).toContain(`{"test":true,"nested":{"1":false},"_meta":{`);
});

test("Date", (): void => {
Expand All @@ -73,43 +65,33 @@ describe("JSON: Log Types", () => {
test("String, Object", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", "test", { test: true, nested: { 1: false } });
expect(getConsoleLog()).toContain('"0": "test"');
expect(getConsoleLog()).toContain(`"1": {
"test": true,
"nested": {
"1": false
}
},`);
expect(getConsoleLog()).toContain('"0":"test"');
expect(getConsoleLog()).toContain(`"1":{"test":true,"nested":{"1":false}},`);
});

test("Object, String", (): void => {
const logger = new Logger({ type: "json" });
logger.log(1234, "testLevel", { test: true, nested: { 1: false } }, "test");
expect(getConsoleLog()).toContain(`"0": {
"test": true,
"nested": {
"1": false
}
},`);
expect(getConsoleLog()).toContain('"1": "test"');
expect(getConsoleLog()).toContain(`"0":{"test":true,"nested":{"1":false}},`);
expect(getConsoleLog()).toContain('"1":"test"');
});

test("Error", (): void => {
const logger = new Logger({ type: "json" });
const errorLog = logger.log(1234, "testLevel", new Error("test"));
expect(getConsoleLog()).toContain('"nativeError": {},');
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/4_json_Log_Types.test.ts",');
expect(getConsoleLog()).toContain('"method": "Object.<anonymous>"');
expect(getConsoleLog()).toContain('"nativeError":{},');
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/4_json_Log_Types.test.ts",');
expect(getConsoleLog()).toContain('"method":"Object.<anonymous>"');
expect(errorLog?.nativeError).toBeInstanceOf(Error);
expect(errorLog?.stack[0]?.fileName).toBe("4_json_Log_Types.test.ts");
});

test("string and Error", (): void => {
const logger = new Logger({ type: "json" });
const errorLog = logger.log(1234, "testLevel", "test", new Error("test"));
expect(getConsoleLog()).toContain('"nativeError": {},');
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/4_json_Log_Types.test.ts",');
expect(getConsoleLog()).toContain('"method": "Object.<anonymous>"');
expect(getConsoleLog()).toContain('"nativeError":{},');
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/4_json_Log_Types.test.ts",');
expect(getConsoleLog()).toContain('"method":"Object.<anonymous>"');
expect((errorLog?.["1"] as any)?.nativeError).toBeInstanceOf(Error);
expect((errorLog?.["1"] as any)?.stack[0]?.fileName).toBe("4_json_Log_Types.test.ts");
});
Expand Down
Loading

0 comments on commit 43b8e9a

Please sign in to comment.