Skip to content

Commit 43b8e9a

Browse files
committed
Make JSON output appear in one line, Fix #191
1 parent f915a80 commit 43b8e9a

File tree

8 files changed

+119
-127
lines changed

8 files changed

+119
-127
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ Example on changing `minLevel` on runtime:
322322
- `json` prints out a `JSON` formatted log entry.
323323
- `hidden` suppresses any output whatsoever and can be used with attached loggers for example.
324324

325+
> Hint: Each JSON log is printed in one line, making it easily parsable by external services.
326+
325327
```typescript
326328
// pretty output
327329
const defaultPrettyLogger = new Logger();

src/runtime/browser/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,22 @@ export function transportFormatted<LogObj>(logMetaMarkup: string, logArgs: unkno
170170
}
171171

172172
export function transportJSON<LogObj>(json: LogObj & ILogObjMeta): void {
173-
console.log(JSON.stringify(json, null, 2));
173+
console.log(jsonStringifyRecursive(json));
174+
175+
function jsonStringifyRecursive(obj: unknown) {
176+
const cache = new Set();
177+
return JSON.stringify(obj, (key, value) => {
178+
if (typeof value === "object" && value !== null) {
179+
if (cache.has(value)) {
180+
// Circular reference found, discard key
181+
return "[Circular]";
182+
}
183+
// Store value in our collection
184+
cache.add(value);
185+
}
186+
return value;
187+
});
188+
}
174189
}
175190

176191
export function isBuffer(arg: unknown) {

src/runtime/nodejs/index.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,21 +145,17 @@ export function transportJSON<LogObj>(json: LogObj & ILogObjMeta): void {
145145

146146
function jsonStringifyRecursive(obj: unknown) {
147147
const cache = new Set();
148-
return JSON.stringify(
149-
obj,
150-
(key, value) => {
151-
if (typeof value === "object" && value !== null) {
152-
if (cache.has(value)) {
153-
// Circular reference found, discard key
154-
return "[Circular]";
155-
}
156-
// Store value in our collection
157-
cache.add(value);
148+
return JSON.stringify(obj, (key, value) => {
149+
if (typeof value === "object" && value !== null) {
150+
if (cache.has(value)) {
151+
// Circular reference found, discard key
152+
return "[Circular]";
158153
}
159-
return value;
160-
},
161-
2
162-
);
154+
// Store value in our collection
155+
cache.add(value);
156+
}
157+
return value;
158+
});
163159
}
164160
}
165161

tests/Browser/1_json.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ describe("Browser: JSON: Log level", () => {
2626
logger.silly("Test");
2727
});
2828

29-
expect(consoleOutput).toContain('"0": "Test"');
30-
expect(consoleOutput).toContain('"_meta": {');
31-
expect(consoleOutput).toContain('"runtime": "Browser"');
32-
expect(consoleOutput).toContain(`"date": "${new Date().toISOString().split(".")[0]}`); // ignore ms
33-
expect(consoleOutput).toContain('"logLevelId": 0');
34-
expect(consoleOutput).toContain('"logLevelName": "SILLY"');
35-
expect(consoleOutput).toContain('"path": {');
36-
expect(consoleOutput).toContain('"fileLine": "4"');
29+
expect(consoleOutput).toContain('"0":"Test"');
30+
expect(consoleOutput).toContain('"_meta":{');
31+
expect(consoleOutput).toContain('"runtime":"Browser"');
32+
expect(consoleOutput).toContain(`"date":"${new Date().toISOString().split(".")[0]}`); // ignore ms
33+
expect(consoleOutput).toContain('"logLevelId":0');
34+
expect(consoleOutput).toContain('"logLevelName":"SILLY"');
35+
expect(consoleOutput).toContain('"path":{');
36+
expect(consoleOutput).toContain('"fileLine":"4"');
3737
});
3838

3939
it("pretty", async () => {

tests/Nodejs/1_json_loglevel.test.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,57 @@ describe("JSON: Log level", () => {
1818

1919
test("silly (console)", (): void => {
2020
logger.silly("Test");
21-
expect(getConsoleLog()).toContain('"0": "Test"');
22-
expect(getConsoleLog()).toContain('"_meta": {');
23-
expect(getConsoleLog()).toContain('"runtime": "');
24-
expect(getConsoleLog()).toContain('"hostname": "');
25-
expect(getConsoleLog()).toContain(`"date": "${new Date().toISOString().split("T")[0]}`); // ignore time
26-
expect(getConsoleLog()).toContain('"logLevelId": 0');
27-
expect(getConsoleLog()).toContain('"logLevelName": "SILLY"');
28-
expect(getConsoleLog()).toContain('"path": {');
29-
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/1_json_loglevel.test.ts",');
30-
expect(getConsoleLog()).toContain('"fileLine": "20"');
21+
expect(getConsoleLog()).toContain('"0":"Test"');
22+
expect(getConsoleLog()).toContain('"_meta":{');
23+
expect(getConsoleLog()).toContain('"runtime":"');
24+
expect(getConsoleLog()).toContain('"hostname":"');
25+
expect(getConsoleLog()).toContain(`"date":"${new Date().toISOString().split("T")[0]}`); // ignore time
26+
expect(getConsoleLog()).toContain('"logLevelId":0');
27+
expect(getConsoleLog()).toContain('"logLevelName":"SILLY"');
28+
expect(getConsoleLog()).toContain('"path":{');
29+
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/1_json_loglevel.test.ts",');
30+
expect(getConsoleLog()).toContain('"fileLine":"20"');
3131
});
3232

3333
test("trace (console)", (): void => {
3434
logger.trace("Test");
35-
expect(getConsoleLog()).toContain('"0": "Test"');
36-
expect(getConsoleLog()).toContain('"_meta": {');
37-
expect(getConsoleLog()).toContain('"logLevelName": "TRACE"');
35+
expect(getConsoleLog()).toContain('"0":"Test"');
36+
expect(getConsoleLog()).toContain('"_meta":{');
37+
expect(getConsoleLog()).toContain('"logLevelName":"TRACE"');
3838
});
3939

4040
test("debug (console)", (): void => {
4141
logger.debug("Test");
42-
expect(getConsoleLog()).toContain('"0": "Test"');
43-
expect(getConsoleLog()).toContain('"_meta": {');
44-
expect(getConsoleLog()).toContain('"logLevelName": "DEBUG"');
42+
expect(getConsoleLog()).toContain('"0":"Test"');
43+
expect(getConsoleLog()).toContain('"_meta":{');
44+
expect(getConsoleLog()).toContain('"logLevelName":"DEBUG"');
4545
});
4646

4747
test("info (console)", (): void => {
4848
logger.info("Test");
49-
expect(getConsoleLog()).toContain('"0": "Test"');
50-
expect(getConsoleLog()).toContain('"_meta": {');
51-
expect(getConsoleLog()).toContain('"logLevelName": "INFO"');
49+
expect(getConsoleLog()).toContain('"0":"Test"');
50+
expect(getConsoleLog()).toContain('"_meta":{');
51+
expect(getConsoleLog()).toContain('"logLevelName":"INFO"');
5252
});
5353

5454
test("warn (console)", (): void => {
5555
logger.warn("Test");
56-
expect(getConsoleLog()).toContain('"0": "Test"');
57-
expect(getConsoleLog()).toContain('"_meta": {');
58-
expect(getConsoleLog()).toContain('"logLevelName": "WARN"');
56+
expect(getConsoleLog()).toContain('"0":"Test"');
57+
expect(getConsoleLog()).toContain('"_meta":{');
58+
expect(getConsoleLog()).toContain('"logLevelName":"WARN"');
5959
});
6060

6161
test("error (console)", (): void => {
6262
logger.error("Test");
63-
expect(getConsoleLog()).toContain('"0": "Test"');
64-
expect(getConsoleLog()).toContain('"_meta": {');
65-
expect(getConsoleLog()).toContain('"logLevelName": "ERROR"');
63+
expect(getConsoleLog()).toContain('"0":"Test"');
64+
expect(getConsoleLog()).toContain('"_meta":{');
65+
expect(getConsoleLog()).toContain('"logLevelName":"ERROR"');
6666
});
6767

6868
test("fatal (console)", (): void => {
6969
logger.fatal("Test");
70-
expect(getConsoleLog()).toContain('"0": "Test"');
71-
expect(getConsoleLog()).toContain('"_meta": {');
72-
expect(getConsoleLog()).toContain('"logLevelName": "FATAL"');
70+
expect(getConsoleLog()).toContain('"0":"Test"');
71+
expect(getConsoleLog()).toContain('"_meta":{');
72+
expect(getConsoleLog()).toContain('"logLevelName":"FATAL"');
7373
});
7474
});

tests/Nodejs/4_json_Log_Types.test.ts

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,32 @@ describe("JSON: Log Types", () => {
1010
test("plain string", (): void => {
1111
const logger = new Logger({ type: "json" });
1212
logger.log(1234, "testLevel", "Test");
13-
expect(getConsoleLog()).toContain('"0": "Test"');
13+
expect(getConsoleLog()).toContain('"0":"Test"');
1414
});
1515

1616
test("two plain string", (): void => {
1717
const logger = new Logger({ type: "json" });
1818
logger.log(1234, "testLevel", "Test1", "Test2");
19-
expect(getConsoleLog()).toContain('"0": "Test1"');
20-
expect(getConsoleLog()).toContain('"1": "Test2"');
19+
expect(getConsoleLog()).toContain('"0":"Test1"');
20+
expect(getConsoleLog()).toContain('"1":"Test2"');
2121
});
2222

2323
test("boolean", (): void => {
2424
const logger = new Logger({ type: "json" });
2525
logger.log(1234, "testLevel", true);
26-
expect(getConsoleLog()).toContain('"0": true');
26+
expect(getConsoleLog()).toContain('"0":true');
2727
});
2828

2929
test("number", (): void => {
3030
const logger = new Logger({ type: "json" });
3131
logger.log(1234, "testLevel", 555);
32-
expect(getConsoleLog()).toContain('"0": 555');
32+
expect(getConsoleLog()).toContain('"0":555');
3333
});
3434

3535
test("Array", (): void => {
3636
const logger = new Logger({ type: "json" });
3737
logger.log(1234, "testLevel", [1, 2, 3, "test"]);
38-
expect(getConsoleLog()).toContain(`[
39-
1,
40-
2,
41-
3,`);
38+
expect(getConsoleLog()).toContain(`[1,2,3,`);
4239
});
4340

4441
test("Buffer", (): void => {
@@ -54,12 +51,7 @@ describe("JSON: Log Types", () => {
5451
test("Object", (): void => {
5552
const logger = new Logger({ type: "json" });
5653
logger.log(1234, "testLevel", { test: true, nested: { 1: false } });
57-
expect(getConsoleLog()).toContain(`{
58-
"test": true,
59-
"nested": {
60-
"1": false
61-
},
62-
"_meta": {`);
54+
expect(getConsoleLog()).toContain(`{"test":true,"nested":{"1":false},"_meta":{`);
6355
});
6456

6557
test("Date", (): void => {
@@ -73,43 +65,33 @@ describe("JSON: Log Types", () => {
7365
test("String, Object", (): void => {
7466
const logger = new Logger({ type: "json" });
7567
logger.log(1234, "testLevel", "test", { test: true, nested: { 1: false } });
76-
expect(getConsoleLog()).toContain('"0": "test"');
77-
expect(getConsoleLog()).toContain(`"1": {
78-
"test": true,
79-
"nested": {
80-
"1": false
81-
}
82-
},`);
68+
expect(getConsoleLog()).toContain('"0":"test"');
69+
expect(getConsoleLog()).toContain(`"1":{"test":true,"nested":{"1":false}},`);
8370
});
8471

8572
test("Object, String", (): void => {
8673
const logger = new Logger({ type: "json" });
8774
logger.log(1234, "testLevel", { test: true, nested: { 1: false } }, "test");
88-
expect(getConsoleLog()).toContain(`"0": {
89-
"test": true,
90-
"nested": {
91-
"1": false
92-
}
93-
},`);
94-
expect(getConsoleLog()).toContain('"1": "test"');
75+
expect(getConsoleLog()).toContain(`"0":{"test":true,"nested":{"1":false}},`);
76+
expect(getConsoleLog()).toContain('"1":"test"');
9577
});
9678

9779
test("Error", (): void => {
9880
const logger = new Logger({ type: "json" });
9981
const errorLog = logger.log(1234, "testLevel", new Error("test"));
100-
expect(getConsoleLog()).toContain('"nativeError": {},');
101-
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/4_json_Log_Types.test.ts",');
102-
expect(getConsoleLog()).toContain('"method": "Object.<anonymous>"');
82+
expect(getConsoleLog()).toContain('"nativeError":{},');
83+
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/4_json_Log_Types.test.ts",');
84+
expect(getConsoleLog()).toContain('"method":"Object.<anonymous>"');
10385
expect(errorLog?.nativeError).toBeInstanceOf(Error);
10486
expect(errorLog?.stack[0]?.fileName).toBe("4_json_Log_Types.test.ts");
10587
});
10688

10789
test("string and Error", (): void => {
10890
const logger = new Logger({ type: "json" });
10991
const errorLog = logger.log(1234, "testLevel", "test", new Error("test"));
110-
expect(getConsoleLog()).toContain('"nativeError": {},');
111-
expect(getConsoleLog()).toContain('"filePath": "/tests/Nodejs/4_json_Log_Types.test.ts",');
112-
expect(getConsoleLog()).toContain('"method": "Object.<anonymous>"');
92+
expect(getConsoleLog()).toContain('"nativeError":{},');
93+
expect(getConsoleLog()).toContain('"filePath":"/tests/Nodejs/4_json_Log_Types.test.ts",');
94+
expect(getConsoleLog()).toContain('"method":"Object.<anonymous>"');
11395
expect((errorLog?.["1"] as any)?.nativeError).toBeInstanceOf(Error);
11496
expect((errorLog?.["1"] as any)?.stack[0]?.fileName).toBe("4_json_Log_Types.test.ts");
11597
});

0 commit comments

Comments
 (0)