@logtape/logtape 1.0.0-dev.246 → 1.0.0-dev.248
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/formatter.cjs +187 -18
- package/dist/formatter.d.cts.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +187 -18
- package/dist/formatter.js.map +1 -1
- package/dist/logger.cjs +26 -20
- package/dist/logger.js +26 -20
- package/dist/logger.js.map +1 -1
- package/dist/sink.cjs +107 -10
- package/dist/sink.d.cts +71 -2
- package/dist/sink.d.cts.map +1 -1
- package/dist/sink.d.ts +71 -2
- package/dist/sink.d.ts.map +1 -1
- package/dist/sink.js +107 -10
- package/dist/sink.js.map +1 -1
- package/formatter.ts +273 -68
- package/logger.ts +61 -30
- package/package.json +2 -1
- package/sink.test.ts +424 -5
- package/sink.ts +245 -13
package/deno.json
CHANGED
package/dist/formatter.cjs
CHANGED
|
@@ -32,6 +32,123 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
32
32
|
maxStringLength: Infinity,
|
|
33
33
|
...opts
|
|
34
34
|
}) : (v) => JSON.stringify(v);
|
|
35
|
+
function padZero(num) {
|
|
36
|
+
return num < 10 ? `0${num}` : `${num}`;
|
|
37
|
+
}
|
|
38
|
+
function padThree(num) {
|
|
39
|
+
return num < 10 ? `00${num}` : num < 100 ? `0${num}` : `${num}`;
|
|
40
|
+
}
|
|
41
|
+
const timestampFormatters = {
|
|
42
|
+
"date-time-timezone": (ts) => {
|
|
43
|
+
const d = new Date(ts);
|
|
44
|
+
const year = d.getUTCFullYear();
|
|
45
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
46
|
+
const day = padZero(d.getUTCDate());
|
|
47
|
+
const hour = padZero(d.getUTCHours());
|
|
48
|
+
const minute = padZero(d.getUTCMinutes());
|
|
49
|
+
const second = padZero(d.getUTCSeconds());
|
|
50
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
51
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms} +00:00`;
|
|
52
|
+
},
|
|
53
|
+
"date-time-tz": (ts) => {
|
|
54
|
+
const d = new Date(ts);
|
|
55
|
+
const year = d.getUTCFullYear();
|
|
56
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
57
|
+
const day = padZero(d.getUTCDate());
|
|
58
|
+
const hour = padZero(d.getUTCHours());
|
|
59
|
+
const minute = padZero(d.getUTCMinutes());
|
|
60
|
+
const second = padZero(d.getUTCSeconds());
|
|
61
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
62
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms} +00`;
|
|
63
|
+
},
|
|
64
|
+
"date-time": (ts) => {
|
|
65
|
+
const d = new Date(ts);
|
|
66
|
+
const year = d.getUTCFullYear();
|
|
67
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
68
|
+
const day = padZero(d.getUTCDate());
|
|
69
|
+
const hour = padZero(d.getUTCHours());
|
|
70
|
+
const minute = padZero(d.getUTCMinutes());
|
|
71
|
+
const second = padZero(d.getUTCSeconds());
|
|
72
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
73
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms}`;
|
|
74
|
+
},
|
|
75
|
+
"time-timezone": (ts) => {
|
|
76
|
+
const d = new Date(ts);
|
|
77
|
+
const hour = padZero(d.getUTCHours());
|
|
78
|
+
const minute = padZero(d.getUTCMinutes());
|
|
79
|
+
const second = padZero(d.getUTCSeconds());
|
|
80
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
81
|
+
return `${hour}:${minute}:${second}.${ms} +00:00`;
|
|
82
|
+
},
|
|
83
|
+
"time-tz": (ts) => {
|
|
84
|
+
const d = new Date(ts);
|
|
85
|
+
const hour = padZero(d.getUTCHours());
|
|
86
|
+
const minute = padZero(d.getUTCMinutes());
|
|
87
|
+
const second = padZero(d.getUTCSeconds());
|
|
88
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
89
|
+
return `${hour}:${minute}:${second}.${ms} +00`;
|
|
90
|
+
},
|
|
91
|
+
"time": (ts) => {
|
|
92
|
+
const d = new Date(ts);
|
|
93
|
+
const hour = padZero(d.getUTCHours());
|
|
94
|
+
const minute = padZero(d.getUTCMinutes());
|
|
95
|
+
const second = padZero(d.getUTCSeconds());
|
|
96
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
97
|
+
return `${hour}:${minute}:${second}.${ms}`;
|
|
98
|
+
},
|
|
99
|
+
"date": (ts) => {
|
|
100
|
+
const d = new Date(ts);
|
|
101
|
+
const year = d.getUTCFullYear();
|
|
102
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
103
|
+
const day = padZero(d.getUTCDate());
|
|
104
|
+
return `${year}-${month}-${day}`;
|
|
105
|
+
},
|
|
106
|
+
"rfc3339": (ts) => new Date(ts).toISOString(),
|
|
107
|
+
"none": () => null
|
|
108
|
+
};
|
|
109
|
+
const levelRenderersCache = {
|
|
110
|
+
ABBR: levelAbbreviations,
|
|
111
|
+
abbr: {
|
|
112
|
+
trace: "trc",
|
|
113
|
+
debug: "dbg",
|
|
114
|
+
info: "inf",
|
|
115
|
+
warning: "wrn",
|
|
116
|
+
error: "err",
|
|
117
|
+
fatal: "ftl"
|
|
118
|
+
},
|
|
119
|
+
FULL: {
|
|
120
|
+
trace: "TRACE",
|
|
121
|
+
debug: "DEBUG",
|
|
122
|
+
info: "INFO",
|
|
123
|
+
warning: "WARNING",
|
|
124
|
+
error: "ERROR",
|
|
125
|
+
fatal: "FATAL"
|
|
126
|
+
},
|
|
127
|
+
full: {
|
|
128
|
+
trace: "trace",
|
|
129
|
+
debug: "debug",
|
|
130
|
+
info: "info",
|
|
131
|
+
warning: "warning",
|
|
132
|
+
error: "error",
|
|
133
|
+
fatal: "fatal"
|
|
134
|
+
},
|
|
135
|
+
L: {
|
|
136
|
+
trace: "T",
|
|
137
|
+
debug: "D",
|
|
138
|
+
info: "I",
|
|
139
|
+
warning: "W",
|
|
140
|
+
error: "E",
|
|
141
|
+
fatal: "F"
|
|
142
|
+
},
|
|
143
|
+
l: {
|
|
144
|
+
trace: "t",
|
|
145
|
+
debug: "d",
|
|
146
|
+
info: "i",
|
|
147
|
+
warning: "w",
|
|
148
|
+
error: "e",
|
|
149
|
+
fatal: "f"
|
|
150
|
+
}
|
|
151
|
+
};
|
|
35
152
|
/**
|
|
36
153
|
* Get a text formatter with the specified options. Although it's flexible
|
|
37
154
|
* enough to create a custom formatter, if you want more control, you can
|
|
@@ -50,15 +167,39 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
50
167
|
* @since 0.6.0
|
|
51
168
|
*/
|
|
52
169
|
function getTextFormatter(options = {}) {
|
|
53
|
-
const timestampRenderer =
|
|
170
|
+
const timestampRenderer = (() => {
|
|
171
|
+
const tsOption = options.timestamp;
|
|
172
|
+
if (tsOption == null) return timestampFormatters["date-time-timezone"];
|
|
173
|
+
else if (tsOption === "disabled") return timestampFormatters["none"];
|
|
174
|
+
else if (typeof tsOption === "string" && tsOption in timestampFormatters) return timestampFormatters[tsOption];
|
|
175
|
+
else return tsOption;
|
|
176
|
+
})();
|
|
54
177
|
const categorySeparator = options.category ?? "·";
|
|
55
178
|
const valueRenderer = options.value ?? inspect;
|
|
56
|
-
const levelRenderer =
|
|
179
|
+
const levelRenderer = (() => {
|
|
180
|
+
const levelOption = options.level;
|
|
181
|
+
if (levelOption == null || levelOption === "ABBR") return (level) => levelRenderersCache.ABBR[level];
|
|
182
|
+
else if (levelOption === "abbr") return (level) => levelRenderersCache.abbr[level];
|
|
183
|
+
else if (levelOption === "FULL") return (level) => levelRenderersCache.FULL[level];
|
|
184
|
+
else if (levelOption === "full") return (level) => levelRenderersCache.full[level];
|
|
185
|
+
else if (levelOption === "L") return (level) => levelRenderersCache.L[level];
|
|
186
|
+
else if (levelOption === "l") return (level) => levelRenderersCache.l[level];
|
|
187
|
+
else return levelOption;
|
|
188
|
+
})();
|
|
57
189
|
const formatter = options.format ?? (({ timestamp, level, category, message }) => `${timestamp ? `${timestamp} ` : ""}[${level}] ${category}: ${message}`);
|
|
58
190
|
return (record) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
191
|
+
const msgParts = record.message;
|
|
192
|
+
const msgLen = msgParts.length;
|
|
193
|
+
let message;
|
|
194
|
+
if (msgLen === 1) message = msgParts[0];
|
|
195
|
+
else if (msgLen <= 6) {
|
|
196
|
+
message = "";
|
|
197
|
+
for (let i = 0; i < msgLen; i++) message += i % 2 === 0 ? msgParts[i] : valueRenderer(msgParts[i]);
|
|
198
|
+
} else {
|
|
199
|
+
const parts = new Array(msgLen);
|
|
200
|
+
for (let i = 0; i < msgLen; i++) parts[i] = i % 2 === 0 ? msgParts[i] : valueRenderer(msgParts[i]);
|
|
201
|
+
message = parts.join("");
|
|
202
|
+
}
|
|
62
203
|
const timestamp = timestampRenderer(record.timestamp);
|
|
63
204
|
const level = levelRenderer(record.level);
|
|
64
205
|
const category = typeof categorySeparator === "function" ? categorySeparator(record.category) : record.category.join(categorySeparator);
|
|
@@ -175,25 +316,39 @@ const ansiColorFormatter = getAnsiColorFormatter();
|
|
|
175
316
|
* @since 0.11.0
|
|
176
317
|
*/
|
|
177
318
|
function getJsonLinesFormatter(options = {}) {
|
|
319
|
+
if (!options.categorySeparator && !options.message && !options.properties) return (record) => {
|
|
320
|
+
if (record.message.length === 3) return JSON.stringify({
|
|
321
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
322
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
323
|
+
message: record.message[0] + JSON.stringify(record.message[1]) + record.message[2],
|
|
324
|
+
logger: record.category.join("."),
|
|
325
|
+
properties: record.properties
|
|
326
|
+
});
|
|
327
|
+
if (record.message.length === 1) return JSON.stringify({
|
|
328
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
329
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
330
|
+
message: record.message[0],
|
|
331
|
+
logger: record.category.join("."),
|
|
332
|
+
properties: record.properties
|
|
333
|
+
});
|
|
334
|
+
let msg = record.message[0];
|
|
335
|
+
for (let i = 1; i < record.message.length; i++) msg += i & 1 ? JSON.stringify(record.message[i]) : record.message[i];
|
|
336
|
+
return JSON.stringify({
|
|
337
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
338
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
339
|
+
message: msg,
|
|
340
|
+
logger: record.category.join("."),
|
|
341
|
+
properties: record.properties
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
const isTemplateMessage = options.message === "template";
|
|
345
|
+
const propertiesOption = options.properties ?? "nest:properties";
|
|
178
346
|
let joinCategory;
|
|
179
347
|
if (typeof options.categorySeparator === "function") joinCategory = options.categorySeparator;
|
|
180
348
|
else {
|
|
181
349
|
const separator = options.categorySeparator ?? ".";
|
|
182
350
|
joinCategory = (category) => category.join(separator);
|
|
183
351
|
}
|
|
184
|
-
let getMessage;
|
|
185
|
-
if (options.message === "template") getMessage = (record) => {
|
|
186
|
-
if (typeof record.rawMessage === "string") return record.rawMessage;
|
|
187
|
-
let msg = "";
|
|
188
|
-
for (let i = 0; i < record.rawMessage.length; i++) msg += i % 2 < 1 ? record.rawMessage[i] : "{}";
|
|
189
|
-
return msg;
|
|
190
|
-
};
|
|
191
|
-
else getMessage = (record) => {
|
|
192
|
-
let msg = "";
|
|
193
|
-
for (let i = 0; i < record.message.length; i++) msg += i % 2 < 1 ? record.message[i] : JSON.stringify(record.message[i]);
|
|
194
|
-
return msg;
|
|
195
|
-
};
|
|
196
|
-
const propertiesOption = options.properties ?? "nest:properties";
|
|
197
352
|
let getProperties;
|
|
198
353
|
if (propertiesOption === "flatten") getProperties = (properties) => properties;
|
|
199
354
|
else if (propertiesOption.startsWith("prepend:")) {
|
|
@@ -208,6 +363,20 @@ function getJsonLinesFormatter(options = {}) {
|
|
|
208
363
|
const key = propertiesOption.substring(5);
|
|
209
364
|
getProperties = (properties) => ({ [key]: properties });
|
|
210
365
|
} else throw new TypeError(`Invalid properties option: ${JSON.stringify(propertiesOption)}. It must be "flatten", "prepend:<prefix>", or "nest:<key>".`);
|
|
366
|
+
let getMessage;
|
|
367
|
+
if (isTemplateMessage) getMessage = (record) => {
|
|
368
|
+
if (typeof record.rawMessage === "string") return record.rawMessage;
|
|
369
|
+
let msg = "";
|
|
370
|
+
for (let i = 0; i < record.rawMessage.length; i++) msg += i % 2 < 1 ? record.rawMessage[i] : "{}";
|
|
371
|
+
return msg;
|
|
372
|
+
};
|
|
373
|
+
else getMessage = (record) => {
|
|
374
|
+
const msgLen = record.message.length;
|
|
375
|
+
if (msgLen === 1) return record.message[0];
|
|
376
|
+
let msg = "";
|
|
377
|
+
for (let i = 0; i < msgLen; i++) msg += i % 2 < 1 ? record.message[i] : JSON.stringify(record.message[i]);
|
|
378
|
+
return msg;
|
|
379
|
+
};
|
|
211
380
|
return (record) => {
|
|
212
381
|
return JSON.stringify({
|
|
213
382
|
"@timestamp": new Date(record.timestamp).toISOString(),
|
package/dist/formatter.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.d.cts","names":[],"sources":["../formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AA+DA;AA+BA;;;AAuGoB,KArMR,aAAA,GAqMQ,CAAA,MAAA,EArMiB,SAqMjB,EAAA,GAAA,MAAA;AAAe;
|
|
1
|
+
{"version":3,"file":"formatter.d.cts","names":[],"sources":["../formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AA+DA;AA+BA;;;AAuGoB,KArMR,aAAA,GAqMQ,CAAA,MAAA,EArMiB,SAqMjB,EAAA,GAAA,MAAA;AAAe;AAgJnC;;;AAEG,UAxRc,eAAA,CAwRd;EAAa;AAiGhB;AAQA;EAyBY,SAAA,EAAA,MAAS,GAAA,IAAA;EA4BJ;;;EAwCW,KAKT,EAAA,MAAA;EAAS;;;EAiBc,QAA1B,EAAA,MAAA;EAAM;;;EA9DiD,OAAA,EAAA,MAAA;EAmFvD;;;EACyB,MACtC,EAnfO,SAmfP;AAAa;AA4DhB;AAMA;AAsDA;;AACW,UArmBM,oBAAA,CAqmBN;EAA8B;AACzB;AA2JhB;AAUA;AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAluBe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAyCK;;;;;;;;;;;;;;;;;;;iBAgJJ,gBAAA,WACL,uBACR;;;;;;;;;;;cAiGU,sBAAsB;;;;;KAQvB,SAAA;;;;;KAyBA,SAAA;;;;;UA4BK,yBAAA,SAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAwChC;;;;mBAKA;;;;eAKJ;;;;;;;;;;;gBAYC,OAAO,UAAU;;;;kBAKf;;;;kBAKA;;;;;;;;;;iBAWF,qBAAA,WACL,4BACR;;;;;;;;;;cA4DU,oBAAoB;;;;;UAMhB,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDD,qBAAA,WACL,4BACR;;;;;;;;;;;;;;;;;cA2JU,oBAAoB;;;;;;;;;KAUrB,gBAAA,YAA4B;;;;;;;;iBAqBxB,uBAAA,SAAgC"}
|
package/dist/formatter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.d.ts","names":[],"sources":["../formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AA+DA;AA+BA;;;AAuGoB,KArMR,aAAA,GAqMQ,CAAA,MAAA,EArMiB,SAqMjB,EAAA,GAAA,MAAA;AAAe;
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","names":[],"sources":["../formatter.ts"],"sourcesContent":[],"mappings":";;;;;;;AAWA;AA+DA;AA+BA;;;AAuGoB,KArMR,aAAA,GAqMQ,CAAA,MAAA,EArMiB,SAqMjB,EAAA,GAAA,MAAA;AAAe;AAgJnC;;;AAEG,UAxRc,eAAA,CAwRd;EAAa;AAiGhB;AAQA;EAyBY,SAAA,EAAA,MAAS,GAAA,IAAA;EA4BJ;;;EAwCW,KAKT,EAAA,MAAA;EAAS;;;EAiBc,QAA1B,EAAA,MAAA;EAAM;;;EA9DiD,OAAA,EAAA,MAAA;EAmFvD;;;EACyB,MACtC,EAnfO,SAmfP;AAAa;AA4DhB;AAMA;AAsDA;;AACW,UArmBM,oBAAA,CAqmBN;EAA8B;AACzB;AA2JhB;AAUA;AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAluBe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAyCK;;;;;;;;;;;;;;;;;;;iBAgJJ,gBAAA,WACL,uBACR;;;;;;;;;;;cAiGU,sBAAsB;;;;;KAQvB,SAAA;;;;;KAyBA,SAAA;;;;;UA4BK,yBAAA,SAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAwChC;;;;mBAKA;;;;eAKJ;;;;;;;;;;;gBAYC,OAAO,UAAU;;;;kBAKf;;;;kBAKA;;;;;;;;;;iBAWF,qBAAA,WACL,4BACR;;;;;;;;;;cA4DU,oBAAoB;;;;;UAMhB,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsDD,qBAAA,WACL,4BACR;;;;;;;;;;;;;;;;;cA2JU,oBAAoB;;;;;;;;;KAUrB,gBAAA,YAA4B;;;;;;;;iBAqBxB,uBAAA,SAAgC"}
|
package/dist/formatter.js
CHANGED
|
@@ -31,6 +31,123 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
31
31
|
maxStringLength: Infinity,
|
|
32
32
|
...opts
|
|
33
33
|
}) : (v) => JSON.stringify(v);
|
|
34
|
+
function padZero(num) {
|
|
35
|
+
return num < 10 ? `0${num}` : `${num}`;
|
|
36
|
+
}
|
|
37
|
+
function padThree(num) {
|
|
38
|
+
return num < 10 ? `00${num}` : num < 100 ? `0${num}` : `${num}`;
|
|
39
|
+
}
|
|
40
|
+
const timestampFormatters = {
|
|
41
|
+
"date-time-timezone": (ts) => {
|
|
42
|
+
const d = new Date(ts);
|
|
43
|
+
const year = d.getUTCFullYear();
|
|
44
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
45
|
+
const day = padZero(d.getUTCDate());
|
|
46
|
+
const hour = padZero(d.getUTCHours());
|
|
47
|
+
const minute = padZero(d.getUTCMinutes());
|
|
48
|
+
const second = padZero(d.getUTCSeconds());
|
|
49
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
50
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms} +00:00`;
|
|
51
|
+
},
|
|
52
|
+
"date-time-tz": (ts) => {
|
|
53
|
+
const d = new Date(ts);
|
|
54
|
+
const year = d.getUTCFullYear();
|
|
55
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
56
|
+
const day = padZero(d.getUTCDate());
|
|
57
|
+
const hour = padZero(d.getUTCHours());
|
|
58
|
+
const minute = padZero(d.getUTCMinutes());
|
|
59
|
+
const second = padZero(d.getUTCSeconds());
|
|
60
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
61
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms} +00`;
|
|
62
|
+
},
|
|
63
|
+
"date-time": (ts) => {
|
|
64
|
+
const d = new Date(ts);
|
|
65
|
+
const year = d.getUTCFullYear();
|
|
66
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
67
|
+
const day = padZero(d.getUTCDate());
|
|
68
|
+
const hour = padZero(d.getUTCHours());
|
|
69
|
+
const minute = padZero(d.getUTCMinutes());
|
|
70
|
+
const second = padZero(d.getUTCSeconds());
|
|
71
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
72
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}.${ms}`;
|
|
73
|
+
},
|
|
74
|
+
"time-timezone": (ts) => {
|
|
75
|
+
const d = new Date(ts);
|
|
76
|
+
const hour = padZero(d.getUTCHours());
|
|
77
|
+
const minute = padZero(d.getUTCMinutes());
|
|
78
|
+
const second = padZero(d.getUTCSeconds());
|
|
79
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
80
|
+
return `${hour}:${minute}:${second}.${ms} +00:00`;
|
|
81
|
+
},
|
|
82
|
+
"time-tz": (ts) => {
|
|
83
|
+
const d = new Date(ts);
|
|
84
|
+
const hour = padZero(d.getUTCHours());
|
|
85
|
+
const minute = padZero(d.getUTCMinutes());
|
|
86
|
+
const second = padZero(d.getUTCSeconds());
|
|
87
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
88
|
+
return `${hour}:${minute}:${second}.${ms} +00`;
|
|
89
|
+
},
|
|
90
|
+
"time": (ts) => {
|
|
91
|
+
const d = new Date(ts);
|
|
92
|
+
const hour = padZero(d.getUTCHours());
|
|
93
|
+
const minute = padZero(d.getUTCMinutes());
|
|
94
|
+
const second = padZero(d.getUTCSeconds());
|
|
95
|
+
const ms = padThree(d.getUTCMilliseconds());
|
|
96
|
+
return `${hour}:${minute}:${second}.${ms}`;
|
|
97
|
+
},
|
|
98
|
+
"date": (ts) => {
|
|
99
|
+
const d = new Date(ts);
|
|
100
|
+
const year = d.getUTCFullYear();
|
|
101
|
+
const month = padZero(d.getUTCMonth() + 1);
|
|
102
|
+
const day = padZero(d.getUTCDate());
|
|
103
|
+
return `${year}-${month}-${day}`;
|
|
104
|
+
},
|
|
105
|
+
"rfc3339": (ts) => new Date(ts).toISOString(),
|
|
106
|
+
"none": () => null
|
|
107
|
+
};
|
|
108
|
+
const levelRenderersCache = {
|
|
109
|
+
ABBR: levelAbbreviations,
|
|
110
|
+
abbr: {
|
|
111
|
+
trace: "trc",
|
|
112
|
+
debug: "dbg",
|
|
113
|
+
info: "inf",
|
|
114
|
+
warning: "wrn",
|
|
115
|
+
error: "err",
|
|
116
|
+
fatal: "ftl"
|
|
117
|
+
},
|
|
118
|
+
FULL: {
|
|
119
|
+
trace: "TRACE",
|
|
120
|
+
debug: "DEBUG",
|
|
121
|
+
info: "INFO",
|
|
122
|
+
warning: "WARNING",
|
|
123
|
+
error: "ERROR",
|
|
124
|
+
fatal: "FATAL"
|
|
125
|
+
},
|
|
126
|
+
full: {
|
|
127
|
+
trace: "trace",
|
|
128
|
+
debug: "debug",
|
|
129
|
+
info: "info",
|
|
130
|
+
warning: "warning",
|
|
131
|
+
error: "error",
|
|
132
|
+
fatal: "fatal"
|
|
133
|
+
},
|
|
134
|
+
L: {
|
|
135
|
+
trace: "T",
|
|
136
|
+
debug: "D",
|
|
137
|
+
info: "I",
|
|
138
|
+
warning: "W",
|
|
139
|
+
error: "E",
|
|
140
|
+
fatal: "F"
|
|
141
|
+
},
|
|
142
|
+
l: {
|
|
143
|
+
trace: "t",
|
|
144
|
+
debug: "d",
|
|
145
|
+
info: "i",
|
|
146
|
+
warning: "w",
|
|
147
|
+
error: "e",
|
|
148
|
+
fatal: "f"
|
|
149
|
+
}
|
|
150
|
+
};
|
|
34
151
|
/**
|
|
35
152
|
* Get a text formatter with the specified options. Although it's flexible
|
|
36
153
|
* enough to create a custom formatter, if you want more control, you can
|
|
@@ -49,15 +166,39 @@ const inspect = typeof document !== "undefined" || typeof navigator !== "undefin
|
|
|
49
166
|
* @since 0.6.0
|
|
50
167
|
*/
|
|
51
168
|
function getTextFormatter(options = {}) {
|
|
52
|
-
const timestampRenderer =
|
|
169
|
+
const timestampRenderer = (() => {
|
|
170
|
+
const tsOption = options.timestamp;
|
|
171
|
+
if (tsOption == null) return timestampFormatters["date-time-timezone"];
|
|
172
|
+
else if (tsOption === "disabled") return timestampFormatters["none"];
|
|
173
|
+
else if (typeof tsOption === "string" && tsOption in timestampFormatters) return timestampFormatters[tsOption];
|
|
174
|
+
else return tsOption;
|
|
175
|
+
})();
|
|
53
176
|
const categorySeparator = options.category ?? "·";
|
|
54
177
|
const valueRenderer = options.value ?? inspect;
|
|
55
|
-
const levelRenderer =
|
|
178
|
+
const levelRenderer = (() => {
|
|
179
|
+
const levelOption = options.level;
|
|
180
|
+
if (levelOption == null || levelOption === "ABBR") return (level) => levelRenderersCache.ABBR[level];
|
|
181
|
+
else if (levelOption === "abbr") return (level) => levelRenderersCache.abbr[level];
|
|
182
|
+
else if (levelOption === "FULL") return (level) => levelRenderersCache.FULL[level];
|
|
183
|
+
else if (levelOption === "full") return (level) => levelRenderersCache.full[level];
|
|
184
|
+
else if (levelOption === "L") return (level) => levelRenderersCache.L[level];
|
|
185
|
+
else if (levelOption === "l") return (level) => levelRenderersCache.l[level];
|
|
186
|
+
else return levelOption;
|
|
187
|
+
})();
|
|
56
188
|
const formatter = options.format ?? (({ timestamp, level, category, message }) => `${timestamp ? `${timestamp} ` : ""}[${level}] ${category}: ${message}`);
|
|
57
189
|
return (record) => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
190
|
+
const msgParts = record.message;
|
|
191
|
+
const msgLen = msgParts.length;
|
|
192
|
+
let message;
|
|
193
|
+
if (msgLen === 1) message = msgParts[0];
|
|
194
|
+
else if (msgLen <= 6) {
|
|
195
|
+
message = "";
|
|
196
|
+
for (let i = 0; i < msgLen; i++) message += i % 2 === 0 ? msgParts[i] : valueRenderer(msgParts[i]);
|
|
197
|
+
} else {
|
|
198
|
+
const parts = new Array(msgLen);
|
|
199
|
+
for (let i = 0; i < msgLen; i++) parts[i] = i % 2 === 0 ? msgParts[i] : valueRenderer(msgParts[i]);
|
|
200
|
+
message = parts.join("");
|
|
201
|
+
}
|
|
61
202
|
const timestamp = timestampRenderer(record.timestamp);
|
|
62
203
|
const level = levelRenderer(record.level);
|
|
63
204
|
const category = typeof categorySeparator === "function" ? categorySeparator(record.category) : record.category.join(categorySeparator);
|
|
@@ -174,25 +315,39 @@ const ansiColorFormatter = getAnsiColorFormatter();
|
|
|
174
315
|
* @since 0.11.0
|
|
175
316
|
*/
|
|
176
317
|
function getJsonLinesFormatter(options = {}) {
|
|
318
|
+
if (!options.categorySeparator && !options.message && !options.properties) return (record) => {
|
|
319
|
+
if (record.message.length === 3) return JSON.stringify({
|
|
320
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
321
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
322
|
+
message: record.message[0] + JSON.stringify(record.message[1]) + record.message[2],
|
|
323
|
+
logger: record.category.join("."),
|
|
324
|
+
properties: record.properties
|
|
325
|
+
});
|
|
326
|
+
if (record.message.length === 1) return JSON.stringify({
|
|
327
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
328
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
329
|
+
message: record.message[0],
|
|
330
|
+
logger: record.category.join("."),
|
|
331
|
+
properties: record.properties
|
|
332
|
+
});
|
|
333
|
+
let msg = record.message[0];
|
|
334
|
+
for (let i = 1; i < record.message.length; i++) msg += i & 1 ? JSON.stringify(record.message[i]) : record.message[i];
|
|
335
|
+
return JSON.stringify({
|
|
336
|
+
"@timestamp": new Date(record.timestamp).toISOString(),
|
|
337
|
+
level: record.level === "warning" ? "WARN" : record.level.toUpperCase(),
|
|
338
|
+
message: msg,
|
|
339
|
+
logger: record.category.join("."),
|
|
340
|
+
properties: record.properties
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
const isTemplateMessage = options.message === "template";
|
|
344
|
+
const propertiesOption = options.properties ?? "nest:properties";
|
|
177
345
|
let joinCategory;
|
|
178
346
|
if (typeof options.categorySeparator === "function") joinCategory = options.categorySeparator;
|
|
179
347
|
else {
|
|
180
348
|
const separator = options.categorySeparator ?? ".";
|
|
181
349
|
joinCategory = (category) => category.join(separator);
|
|
182
350
|
}
|
|
183
|
-
let getMessage;
|
|
184
|
-
if (options.message === "template") getMessage = (record) => {
|
|
185
|
-
if (typeof record.rawMessage === "string") return record.rawMessage;
|
|
186
|
-
let msg = "";
|
|
187
|
-
for (let i = 0; i < record.rawMessage.length; i++) msg += i % 2 < 1 ? record.rawMessage[i] : "{}";
|
|
188
|
-
return msg;
|
|
189
|
-
};
|
|
190
|
-
else getMessage = (record) => {
|
|
191
|
-
let msg = "";
|
|
192
|
-
for (let i = 0; i < record.message.length; i++) msg += i % 2 < 1 ? record.message[i] : JSON.stringify(record.message[i]);
|
|
193
|
-
return msg;
|
|
194
|
-
};
|
|
195
|
-
const propertiesOption = options.properties ?? "nest:properties";
|
|
196
351
|
let getProperties;
|
|
197
352
|
if (propertiesOption === "flatten") getProperties = (properties) => properties;
|
|
198
353
|
else if (propertiesOption.startsWith("prepend:")) {
|
|
@@ -207,6 +362,20 @@ function getJsonLinesFormatter(options = {}) {
|
|
|
207
362
|
const key = propertiesOption.substring(5);
|
|
208
363
|
getProperties = (properties) => ({ [key]: properties });
|
|
209
364
|
} else throw new TypeError(`Invalid properties option: ${JSON.stringify(propertiesOption)}. It must be "flatten", "prepend:<prefix>", or "nest:<key>".`);
|
|
365
|
+
let getMessage;
|
|
366
|
+
if (isTemplateMessage) getMessage = (record) => {
|
|
367
|
+
if (typeof record.rawMessage === "string") return record.rawMessage;
|
|
368
|
+
let msg = "";
|
|
369
|
+
for (let i = 0; i < record.rawMessage.length; i++) msg += i % 2 < 1 ? record.rawMessage[i] : "{}";
|
|
370
|
+
return msg;
|
|
371
|
+
};
|
|
372
|
+
else getMessage = (record) => {
|
|
373
|
+
const msgLen = record.message.length;
|
|
374
|
+
if (msgLen === 1) return record.message[0];
|
|
375
|
+
let msg = "";
|
|
376
|
+
for (let i = 0; i < msgLen; i++) msg += i % 2 < 1 ? record.message[i] : JSON.stringify(record.message[i]);
|
|
377
|
+
return msg;
|
|
378
|
+
};
|
|
210
379
|
return (record) => {
|
|
211
380
|
return JSON.stringify({
|
|
212
381
|
"@timestamp": new Date(record.timestamp).toISOString(),
|