@logtape/logtape 0.12.0-dev.184 → 0.12.0-dev.186

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/logger.ts CHANGED
@@ -10,6 +10,7 @@ import type { Sink } from "./sink.ts";
10
10
  *
11
11
  * ```typescript
12
12
  * const logger = getLogger("category");
13
+ * logger.trace `A trace message with ${value}`
13
14
  * logger.debug `A debug message with ${value}.`;
14
15
  * logger.info `An info message with ${value}.`;
15
16
  * logger.warn `A warning message with ${value}.`;
@@ -79,6 +80,94 @@ export interface Logger {
79
80
  */
80
81
  with(properties: Record<string, unknown>): Logger;
81
82
 
83
+ /**
84
+ * Log a trace message. Use this as a template string prefix.
85
+ *
86
+ * ```typescript
87
+ * logger.trace `A trace message with ${value}.`;
88
+ * ```
89
+ *
90
+ * @param message The message template strings array.
91
+ * @param values The message template values.
92
+ * @since 0.12.0
93
+ */
94
+ trace(message: TemplateStringsArray, ...values: readonly unknown[]): void;
95
+
96
+ /**
97
+ * Log a trace message with properties.
98
+ *
99
+ * ```typescript
100
+ * logger.trace('A trace message with {value}.', { value });
101
+ * ```
102
+ *
103
+ * If the properties are expensive to compute, you can pass a callback that
104
+ * returns the properties:
105
+ *
106
+ * ```typescript
107
+ * logger.trace(
108
+ * 'A trace message with {value}.',
109
+ * () => ({ value: expensiveComputation() })
110
+ * );
111
+ * ```
112
+ *
113
+ * @param message The message template. Placeholders to be replaced with
114
+ * `values` are indicated by keys in curly braces (e.g.,
115
+ * `{value}`).
116
+ * @param properties The values to replace placeholders with. For lazy
117
+ * evaluation, this can be a callback that returns the
118
+ * properties.
119
+ * @since 0.12.0
120
+ */
121
+ trace(
122
+ message: string,
123
+ properties?: Record<string, unknown> | (() => Record<string, unknown>),
124
+ ): void;
125
+
126
+ /**
127
+ * Log a trace values with no message. This is useful when you
128
+ * want to log properties without a message, e.g., when you want to log
129
+ * the context of a request or an operation.
130
+ *
131
+ * ```typescript
132
+ * logger.trace({ method: 'GET', url: '/api/v1/resource' });
133
+ * ```
134
+ *
135
+ * Note that this is a shorthand for:
136
+ *
137
+ * ```typescript
138
+ * logger.trace('{*}', { method: 'GET', url: '/api/v1/resource' });
139
+ * ```
140
+ *
141
+ * If the properties are expensive to compute, you cannot use this shorthand
142
+ * and should use the following syntax instead:
143
+ *
144
+ * ```typescript
145
+ * logger.trace('{*}', () => ({
146
+ * method: expensiveMethod(),
147
+ * url: expensiveUrl(),
148
+ * }));
149
+ * ```
150
+ *
151
+ * @param properties The values to log. Note that this does not take
152
+ * a callback.
153
+ * @since 0.12.0
154
+ */
155
+ trace(properties: Record<string, unknown>): void;
156
+
157
+ /**
158
+ * Lazily log a trace message. Use this when the message values are expensive
159
+ * to compute and should only be computed if the message is actually logged.
160
+ *
161
+ * ```typescript
162
+ * logger.trace(l => l`A trace message with ${expensiveValue()}.`);
163
+ * ```
164
+ *
165
+ * @param callback A callback that returns the message template prefix.
166
+ * @throws {TypeError} If no log record was made inside the callback.
167
+ * @since 0.12.0
168
+ */
169
+ trace(callback: LogCallback): void;
170
+
82
171
  /**
83
172
  * Log a debug message. Use this as a template string prefix.
84
173
  *
@@ -336,6 +425,95 @@ export interface Logger {
336
425
  */
337
426
  warn(callback: LogCallback): void;
338
427
 
428
+ /**
429
+ * Log a warning message. Use this as a template string prefix.
430
+ *
431
+ * ```typescript
432
+ * logger.warning `A warning message with ${value}.`;
433
+ * ```
434
+ *
435
+ * @param message The message template strings array.
436
+ * @param values The message template values.
437
+ * @since 0.12.0
438
+ */
439
+ warning(message: TemplateStringsArray, ...values: readonly unknown[]): void;
440
+
441
+ /**
442
+ * Log a warning message with properties.
443
+ *
444
+ * ```typescript
445
+ * logger.warning('A warning message with {value}.', { value });
446
+ * ```
447
+ *
448
+ * If the properties are expensive to compute, you can pass a callback that
449
+ * returns the properties:
450
+ *
451
+ * ```typescript
452
+ * logger.warning(
453
+ * 'A warning message with {value}.',
454
+ * () => ({ value: expensiveComputation() })
455
+ * );
456
+ * ```
457
+ *
458
+ * @param message The message template. Placeholders to be replaced with
459
+ * `values` are indicated by keys in curly braces (e.g.,
460
+ * `{value}`).
461
+ * @param properties The values to replace placeholders with. For lazy
462
+ * evaluation, this can be a callback that returns the
463
+ * properties.
464
+ * @since 0.12.0
465
+ */
466
+ warning(
467
+ message: string,
468
+ properties?: Record<string, unknown> | (() => Record<string, unknown>),
469
+ ): void;
470
+
471
+ /**
472
+ * Log a warning values with no message. This is useful when you
473
+ * want to log properties without a message, e.g., when you want to log
474
+ * the context of a request or an operation.
475
+ *
476
+ * ```typescript
477
+ * logger.warning({ method: 'GET', url: '/api/v1/resource' });
478
+ * ```
479
+ *
480
+ * Note that this is a shorthand for:
481
+ *
482
+ * ```typescript
483
+ * logger.warning('{*}', { method: 'GET', url: '/api/v1/resource' });
484
+ * ```
485
+ *
486
+ * If the properties are expensive to compute, you cannot use this shorthand
487
+ * and should use the following syntax instead:
488
+ *
489
+ * ```typescript
490
+ * logger.warning('{*}', () => ({
491
+ * method: expensiveMethod(),
492
+ * url: expensiveUrl(),
493
+ * }));
494
+ * ```
495
+ *
496
+ * @param properties The values to log. Note that this does not take
497
+ * a callback.
498
+ * @since 0.12.0
499
+ */
500
+ warning(properties: Record<string, unknown>): void;
501
+
502
+ /**
503
+ * Lazily log a warning message. Use this when the message values are
504
+ * expensive to compute and should only be computed if the message is actually
505
+ * logged.
506
+ *
507
+ * ```typescript
508
+ * logger.warning(l => l`A warning message with ${expensiveValue()}.`);
509
+ * ```
510
+ *
511
+ * @param callback A callback that returns the message template prefix.
512
+ * @throws {TypeError} If no log record was made inside the callback.
513
+ * @since 0.12.0
514
+ */
515
+ warning(callback: LogCallback): void;
516
+
339
517
  /**
340
518
  * Log an error message. Use this as a template string prefix.
341
519
  *
@@ -568,7 +746,7 @@ export class LoggerImpl implements Logger {
568
746
  readonly sinks: Sink[];
569
747
  parentSinks: "inherit" | "override" = "inherit";
570
748
  readonly filters: Filter[];
571
- lowestLevel: LogLevel | null = "debug";
749
+ lowestLevel: LogLevel | null = "trace";
572
750
  contextLocalStorage?: ContextLocalStorage<Record<string, unknown>>;
573
751
 
574
752
  static getLogger(category: string | readonly string[] = []): LoggerImpl {
@@ -626,7 +804,7 @@ export class LoggerImpl implements Logger {
626
804
  while (this.sinks.length > 0) this.sinks.shift();
627
805
  this.parentSinks = "inherit";
628
806
  while (this.filters.length > 0) this.filters.shift();
629
- this.lowestLevel = "debug";
807
+ this.lowestLevel = "trace";
630
808
  }
631
809
 
632
810
  /**
@@ -783,6 +961,25 @@ export class LoggerImpl implements Logger {
783
961
  });
784
962
  }
785
963
 
964
+ trace(
965
+ message:
966
+ | TemplateStringsArray
967
+ | string
968
+ | LogCallback
969
+ | Record<string, unknown>,
970
+ ...values: unknown[]
971
+ ): void {
972
+ if (typeof message === "string") {
973
+ this.log("trace", message, (values[0] ?? {}) as Record<string, unknown>);
974
+ } else if (typeof message === "function") {
975
+ this.logLazily("trace", message);
976
+ } else if (!Array.isArray(message)) {
977
+ this.log("trace", "{*}", message as Record<string, unknown>);
978
+ } else {
979
+ this.logTemplate("trace", message as TemplateStringsArray, values);
980
+ }
981
+ }
982
+
786
983
  debug(
787
984
  message:
788
985
  | TemplateStringsArray
@@ -844,6 +1041,17 @@ export class LoggerImpl implements Logger {
844
1041
  }
845
1042
  }
846
1043
 
1044
+ warning(
1045
+ message:
1046
+ | TemplateStringsArray
1047
+ | string
1048
+ | LogCallback
1049
+ | Record<string, unknown>,
1050
+ ...values: unknown[]
1051
+ ): void {
1052
+ this.warn(message, ...values);
1053
+ }
1054
+
847
1055
  error(
848
1056
  message:
849
1057
  | TemplateStringsArray
@@ -946,6 +1154,25 @@ export class LoggerCtx implements Logger {
946
1154
  this.logger.logTemplate(level, messageTemplate, values, this.properties);
947
1155
  }
948
1156
 
1157
+ trace(
1158
+ message:
1159
+ | TemplateStringsArray
1160
+ | string
1161
+ | LogCallback
1162
+ | Record<string, unknown>,
1163
+ ...values: unknown[]
1164
+ ): void {
1165
+ if (typeof message === "string") {
1166
+ this.log("trace", message, (values[0] ?? {}) as Record<string, unknown>);
1167
+ } else if (typeof message === "function") {
1168
+ this.logLazily("trace", message);
1169
+ } else if (!Array.isArray(message)) {
1170
+ this.log("trace", "{*}", message as Record<string, unknown>);
1171
+ } else {
1172
+ this.logTemplate("trace", message as TemplateStringsArray, values);
1173
+ }
1174
+ }
1175
+
949
1176
  debug(
950
1177
  message:
951
1178
  | TemplateStringsArray
@@ -1007,6 +1234,17 @@ export class LoggerCtx implements Logger {
1007
1234
  }
1008
1235
  }
1009
1236
 
1237
+ warning(
1238
+ message:
1239
+ | TemplateStringsArray
1240
+ | string
1241
+ | LogCallback
1242
+ | Record<string, unknown>,
1243
+ ...values: unknown[]
1244
+ ): void {
1245
+ this.warn(message, ...values);
1246
+ }
1247
+
1010
1248
  error(
1011
1249
  message:
1012
1250
  | TemplateStringsArray
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/logtape",
3
- "version": "0.12.0-dev.184+ca9e936b",
3
+ "version": "0.12.0-dev.186+8c242544",
4
4
  "description": "Simple logging library with zero dependencies for Deno/Node.js/Bun/browsers",
5
5
  "keywords": [
6
6
  "logging",
package/sink.test.ts CHANGED
@@ -2,7 +2,7 @@ import { suite } from "@hongminhee/suite";
2
2
  import { assertEquals } from "@std/assert/equals";
3
3
  import { assertThrows } from "@std/assert/throws";
4
4
  import makeConsoleMock from "consolemock";
5
- import { debug, error, fatal, info, warning } from "./fixtures.ts";
5
+ import { debug, error, fatal, info, trace, warning } from "./fixtures.ts";
6
6
  import { defaultTextFormatter } from "./formatter.ts";
7
7
  import type { LogLevel } from "./level.ts";
8
8
  import type { LogRecord } from "./record.ts";
@@ -13,6 +13,7 @@ const test = suite(import.meta);
13
13
  test("withFilter()", () => {
14
14
  const buffer: LogRecord[] = [];
15
15
  const sink = withFilter(buffer.push.bind(buffer), "warning");
16
+ sink(trace);
16
17
  sink(debug);
17
18
  sink(info);
18
19
  sink(warning);
@@ -36,6 +37,7 @@ test("getStreamSink()", async () => {
36
37
  },
37
38
  }),
38
39
  );
40
+ sink(trace);
39
41
  sink(debug);
40
42
  sink(info);
41
43
  sink(warning);
@@ -45,6 +47,7 @@ test("getStreamSink()", async () => {
45
47
  assertEquals(
46
48
  buffer,
47
49
  `\
50
+ 2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!
48
51
  2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!
49
52
  2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!
50
53
  2023-11-14 22:13:20.000 +00:00 [WRN] my-app·junk: Hello, 123 & 456!
@@ -58,12 +61,25 @@ test("getConsoleSink()", () => {
58
61
  // @ts-ignore: consolemock is not typed
59
62
  const mock: ConsoleMock = makeConsoleMock();
60
63
  const sink = getConsoleSink({ console: mock });
64
+ sink(trace);
61
65
  sink(debug);
62
66
  sink(info);
63
67
  sink(warning);
64
68
  sink(error);
65
69
  sink(fatal);
66
70
  assertEquals(mock.history(), [
71
+ {
72
+ DEBUG: [
73
+ "%c22:13:20.000 %cTRC%c %cmy-app·junk %cHello, %o & %o!",
74
+ "color: gray;",
75
+ "background-color: gray; color: white;",
76
+ "background-color: default;",
77
+ "color: gray;",
78
+ "color: default;",
79
+ 123,
80
+ 456,
81
+ ],
82
+ },
67
83
  {
68
84
  DEBUG: [
69
85
  "%c22:13:20.000 %cDBG%c %cmy-app·junk %cHello, %o & %o!",
@@ -138,12 +154,18 @@ test("getConsoleSink()", () => {
138
154
  console: mock2,
139
155
  formatter: defaultTextFormatter,
140
156
  });
157
+ sink2(trace);
141
158
  sink2(debug);
142
159
  sink2(info);
143
160
  sink2(warning);
144
161
  sink2(error);
145
162
  sink2(fatal);
146
163
  assertEquals(mock2.history(), [
164
+ {
165
+ DEBUG: [
166
+ "2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!",
167
+ ],
168
+ },
147
169
  {
148
170
  DEBUG: [
149
171
  "2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!",
@@ -176,6 +198,7 @@ test("getConsoleSink()", () => {
176
198
  const sink3 = getConsoleSink({
177
199
  console: mock3,
178
200
  levelMap: {
201
+ trace: "log",
179
202
  debug: "log",
180
203
  info: "log",
181
204
  warning: "log",
@@ -184,12 +207,18 @@ test("getConsoleSink()", () => {
184
207
  },
185
208
  formatter: defaultTextFormatter,
186
209
  });
210
+ sink3(trace);
187
211
  sink3(debug);
188
212
  sink3(info);
189
213
  sink3(warning);
190
214
  sink3(error);
191
215
  sink3(fatal);
192
216
  assertEquals(mock3.history(), [
217
+ {
218
+ LOG: [
219
+ "2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!",
220
+ ],
221
+ },
193
222
  {
194
223
  LOG: [
195
224
  "2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!",
package/sink.ts CHANGED
@@ -117,6 +117,7 @@ export interface ConsoleSinkOptions {
117
117
  *
118
118
  * ```typescript
119
119
  * {
120
+ * trace: "trace",
120
121
  * debug: "debug",
121
122
  * info: "info",
122
123
  * warning: "warn",
@@ -143,6 +144,7 @@ export interface ConsoleSinkOptions {
143
144
  export function getConsoleSink(options: ConsoleSinkOptions = {}): Sink {
144
145
  const formatter = options.formatter ?? defaultConsoleFormatter;
145
146
  const levelMap: Record<LogLevel, ConsoleMethod> = {
147
+ trace: "debug",
146
148
  debug: "debug",
147
149
  info: "info",
148
150
  warning: "warn",