UNPKG

2.38 kBJavaScriptView Raw
1import pino from "pino";
2import { environment, isProduction } from "../env.js";
3import { isNil } from "../lodash.js";
4import { noop } from "../utils.js";
5import { writeGithubActions, writePretty } from "./writer.js";
6
7const writersLookup = {
8 pretty: writePretty,
9 "github-actions": writeGithubActions,
10};
11
12/**
13 * @typedef {import("../../types/advanced-types").LoggerOptions} LoggerOptions
14 */
15
16/**
17 * Create a new logger instance
18 *
19 * @since 0.1.0
20 *
21 * @param {LoggerOptions|undefined} [options]
22 * @returns {import("../../types/advanced-types.js").Logger}
23 */
24export function newLogger(options) {
25 const app = environment.APP_NAME;
26 const stream = options?.stream ?? process.stdout;
27
28 const printer =
29 options?.printer ??
30 (environment.GITHUB_ACTIONS !== "true"
31 ? isProduction()
32 ? "ndjson"
33 : "pretty"
34 : "github-actions");
35
36 const context = options?.ctx ?? {};
37 if (isProduction() && app) {
38 context.application = app;
39 }
40
41 if (printer === "ndjson") {
42 const pinoLogger = pino(
43 {
44 formatters: {
45 level: (label) => ({ level: label }),
46 bindings: () => ({}),
47 },
48 serializers: {},
49 base: {},
50 transport: options?.pinoOptions?.transport,
51 },
52 // @ts-ignore
53 options?.pinoOptions?.destination ??
54 (isNil(options?.pinoOptions?.transport)
55 ? pino.destination(1)
56 : undefined),
57 ).child({ context });
58
59 return {
60 info: options?.disableInfoLogger
61 ? noop
62 : (message) => pinoLogger.info({ message }),
63 error: options?.disableErrorLogger
64 ? noop
65 : (message) => pinoLogger.error({ message }),
66 };
67 }
68
69 const info = options?.disableInfoLogger
70 ? noop
71 : wrapWriter(writersLookup[printer], stream, "info", context);
72 const error = options?.disableErrorLogger
73 ? noop
74 : wrapWriter(writersLookup[printer], stream, "error", context);
75
76 return {
77 info,
78 error,
79 };
80}
81
82/**
83 * Wrap provided writer function to be used in the Logger
84 *
85 * @param {Function} fn
86 * @param {NodeJS.WriteStream} stream
87 * @param {string} level
88 * @param {Record<string, any>} context
89 * @returns {(arg: any) => void}
90 */
91function wrapWriter(fn, stream, level, context) {
92 return (message) => {
93 const timestamp = new Date();
94 fn(stream, level, timestamp, context, message ?? {});
95 };
96}