widelogger 0.5.0 → 0.7.0

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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { DottedKey, FieldValue } from "./types";
1
+ import type { TransportMultiOptions, TransportSingleOptions } from "pino";
2
+ import type { DottedKey, ErrorParser, FieldValue } from "./types";
2
3
  export interface WideloggerOptions {
3
4
  service: string;
4
5
  defaultEventName: string;
@@ -7,6 +8,7 @@ export interface WideloggerOptions {
7
8
  instanceId?: string;
8
9
  environment?: string;
9
10
  level?: string;
11
+ transport?: TransportSingleOptions | TransportMultiOptions;
10
12
  }
11
13
  export interface ErrorFieldsOptions {
12
14
  prefix?: string;
@@ -32,6 +34,8 @@ export declare const widelog: {
32
34
  stop: <K extends string>(key: DottedKey<K>) => void;
33
35
  measure: typeof measure;
34
36
  };
37
+ errors: (parser: ErrorParser) => void;
38
+ error: <K extends string>(key: DottedKey<K>, error: unknown) => void;
35
39
  errorFields: (error: unknown, options?: ErrorFieldsOptions) => void;
36
40
  flush: () => void;
37
41
  };
@@ -43,4 +47,4 @@ export declare const widelogger: (options: WideloggerOptions) => {
43
47
  destroy: () => Promise<void>;
44
48
  };
45
49
  export type Widelog = typeof widelog;
46
- export {};
50
+ export type { TransportMultiOptions, TransportSingleOptions } from "pino";
package/dist/index.js CHANGED
@@ -32,9 +32,29 @@ var createAggregators = () => ({
32
32
  arrays: Object.create(null),
33
33
  maxValues: Object.create(null),
34
34
  minValues: Object.create(null),
35
- timers: Object.create(null)
35
+ timers: Object.create(null),
36
+ errors: Object.create(null)
36
37
  });
37
- var processOperation = (agg, entry) => {
38
+ var aggregateError = (agg, key, slug) => {
39
+ const existing = agg.errors[key];
40
+ if (existing) {
41
+ existing.total += 1;
42
+ const previousCount = existing.counts[slug];
43
+ if (typeof previousCount === "number") {
44
+ existing.counts[slug] = previousCount + 1;
45
+ } else {
46
+ existing.counts[slug] = 1;
47
+ existing.slugs.push(slug);
48
+ }
49
+ } else {
50
+ agg.errors[key] = {
51
+ slugs: [slug],
52
+ counts: { [slug]: 1 },
53
+ total: 1
54
+ };
55
+ }
56
+ };
57
+ var processOperation = (agg, entry, errorParser) => {
38
58
  switch (entry.operation) {
39
59
  case "set":
40
60
  setNested(agg.event, entry.key, entry.value);
@@ -66,9 +86,9 @@ var processOperation = (agg, entry) => {
66
86
  break;
67
87
  }
68
88
  case "time.start": {
69
- const existing = agg.timers[entry.key];
70
- if (existing) {
71
- existing.start = entry.time;
89
+ const existingTimer = agg.timers[entry.key];
90
+ if (existingTimer) {
91
+ existingTimer.start = entry.time;
72
92
  } else {
73
93
  agg.timers[entry.key] = { start: entry.time, accumulated: 0 };
74
94
  }
@@ -82,6 +102,13 @@ var processOperation = (agg, entry) => {
82
102
  }
83
103
  break;
84
104
  }
105
+ case "error": {
106
+ if (errorParser) {
107
+ const slug = errorParser(entry.error);
108
+ aggregateError(agg, entry.key, slug);
109
+ }
110
+ break;
111
+ }
85
112
  default:
86
113
  }
87
114
  };
@@ -90,7 +117,8 @@ var mergeAggregators = (agg) => {
90
117
  agg.counters,
91
118
  agg.arrays,
92
119
  agg.maxValues,
93
- agg.minValues
120
+ agg.minValues,
121
+ agg.errors
94
122
  ];
95
123
  for (const source of sources) {
96
124
  for (const key of Object.keys(source)) {
@@ -112,10 +140,10 @@ var flush = (context) => {
112
140
  }
113
141
  const agg = createAggregators();
114
142
  for (const entry of context.stickyOperations) {
115
- processOperation(agg, entry);
143
+ processOperation(agg, entry, context.errorParser);
116
144
  }
117
145
  for (const entry of context.operations) {
118
- processOperation(agg, entry);
146
+ processOperation(agg, entry, context.errorParser);
119
147
  }
120
148
  mergeAggregators(agg);
121
149
  context.operations = [];
@@ -252,6 +280,16 @@ var widelog = {
252
280
  },
253
281
  measure
254
282
  },
283
+ errors: (parser) => {
284
+ const store = storage.getStore();
285
+ if (!store) {
286
+ return;
287
+ }
288
+ store.errorParser = parser;
289
+ },
290
+ error: (key, error) => {
291
+ pushOp({ operation: "error", key, error });
292
+ },
255
293
  errorFields: (error, options = {}) => {
256
294
  const context = storage.getStore();
257
295
  if (!context) {
@@ -312,19 +350,28 @@ var widelog = {
312
350
  store.transport(event);
313
351
  }
314
352
  };
353
+ function resolveTransport(custom, isDevelopment) {
354
+ if (custom) {
355
+ return pino.transport(custom);
356
+ }
357
+ if (isDevelopment) {
358
+ return pino.transport({
359
+ target: "pino-pretty",
360
+ options: {
361
+ colorize: true,
362
+ singleLine: true,
363
+ translateTime: "SYS:standard",
364
+ ignore: "pid,hostname"
365
+ }
366
+ });
367
+ }
368
+ return;
369
+ }
315
370
  var widelogger = (options) => {
316
371
  const nodeEnvironment = typeof process.env === "object" ? "development" : undefined;
317
372
  const environment = options.environment ?? nodeEnvironment ?? "development";
318
373
  const isDevelopment = environment !== "production";
319
- const pinoTransport = isDevelopment ? pino.transport({
320
- target: "pino-pretty",
321
- options: {
322
- colorize: true,
323
- singleLine: true,
324
- translateTime: "SYS:standard",
325
- ignore: "pid,hostname"
326
- }
327
- }) : undefined;
374
+ const pinoTransport = resolveTransport(options.transport, isDevelopment);
328
375
  const logger = pino({
329
376
  level: options.level ?? process.env.LOG_LEVEL ?? "info",
330
377
  timestamp: pino.stdTimeFunctions.isoTime,
@@ -355,7 +402,12 @@ var widelogger = (options) => {
355
402
  }
356
403
  };
357
404
  function context(callback) {
358
- return storage.run({ operations: [], stickyOperations: [], transport }, () => {
405
+ return storage.run({
406
+ operations: [],
407
+ stickyOperations: [],
408
+ errorParser: null,
409
+ transport
410
+ }, () => {
359
411
  let result;
360
412
  try {
361
413
  result = callback();
package/dist/types.d.ts CHANGED
@@ -5,6 +5,7 @@ interface KeyErrorBrand {
5
5
  }
6
6
  type ValidateKey<T extends string> = T extends "" ? "widelog keys cannot be empty" & KeyErrorBrand : T extends `.${string}` ? "widelog keys cannot start with a dot" & KeyErrorBrand : T extends `${string}.` ? "widelog keys cannot end with a dot" & KeyErrorBrand : T extends `${string}..${string}` ? "widelog keys cannot contain empty segments" & KeyErrorBrand : T;
7
7
  export type DottedKey<T extends string> = ValidateKey<T>;
8
+ export type ErrorParser = (error: unknown) => string;
8
9
  export type Operation = {
9
10
  operation: "set";
10
11
  key: string;
@@ -33,10 +34,15 @@ export type Operation = {
33
34
  operation: "time.stop";
34
35
  key: string;
35
36
  time: number;
37
+ } | {
38
+ operation: "error";
39
+ key: string;
40
+ error: unknown;
36
41
  };
37
42
  export interface Context {
38
43
  operations: Operation[];
39
44
  stickyOperations: Operation[];
45
+ errorParser: ErrorParser | null;
40
46
  transport: (event: Record<string, unknown>) => void;
41
47
  }
42
48
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "widelogger",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",