From 741e570189b79a78ac28fd97a4a8242ae039e066 Mon Sep 17 00:00:00 2001 From: Fred Boniface Date: Sun, 24 Sep 2023 21:35:36 +0100 Subject: [PATCH] Begin migration to Pino for logs Signed-off-by: Fred Boniface --- app.js | 21 ++- package-lock.json | 231 +++++++++++++++++++++++++++- package.json | 3 + src/middlewares/auth.middlewares.js | 23 +-- src/utils/auth.utils.ts | 18 +-- src/utils/logger.utils.ts | 14 ++ 6 files changed, 272 insertions(+), 38 deletions(-) create mode 100644 src/utils/logger.utils.ts diff --git a/app.js b/app.js index 9e6323c..3f2d472 100644 --- a/app.js +++ b/app.js @@ -5,6 +5,11 @@ console.log("Initialising OwlBoard"); const mode = process.env.NODE_ENV || "development"; +// Logging +const logger = require("./src/utils/logger.utils"); +const pino = require("pino-http"); +logger.logger.info("Logger Initialised"); + // External Requires const express = require("express"); const app = express(); @@ -47,12 +52,7 @@ const limiter = rateLimit({ }); // Print version number: -log.out(`app: Starting OwlBoard in ${mode} mode`, "init"); -log.out( - `app: Starting OwlBoard - Backend Version: ${version.app} - ` + - `API versions: ${version.api}`, - "init" -); +logger.logger.info(`Starting version ${version.app} in ${mode} mode`); // Remove X-Powered-By header: app.disable('x-powered-by'); @@ -75,6 +75,7 @@ app.use(express.json()); //JSON Parsing for POST Requests app.use(compression()); // Compress API Data if supported by client app.use(limiter); app.use(authenticate); +app.use(pino); // 2023 Rationalisation Routes (/api/v2, /misc) app.use("/api/v2/pis", pis2Rtr); // API Version 2 @@ -113,12 +114,8 @@ mode === "development" // Start Express app.listen(srvPort, srvListen, (error) => { if (!error) { - log.out(`app.listen: Listening on http://${srvListen}:${srvPort}`, "init"); - log.out("app.listen: State - alive", "init"); + logger.logger.info(`Listening on http://${srvListen}:${srvPort}`); } else { - log.out( - `app.listen: Error occurred, server can't start ${error.message}`, - "err" - ); + logger.logger.error(error, `Error starting server`); } }); diff --git a/package-lock.json b/package-lock.json index d6bfbe6..4250fe0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,12 +20,15 @@ "moment-timezone": "^0.5.43", "mongodb": "^4.13.0", "nodemailer": "^6.9.1", + "pino": "^8.15.1", + "pino-http": "^8.5.0", "redis": "^4.6.7", "zlib": "^1.0.5" }, "devDependencies": { "@owlboard/ts-types": "^0.0.9", "@types/jest": "^29.5.3", + "@types/pino": "^7.0.5", "eslint": "^8.39.0", "jest": "^29.6.2", "prettier": "^2.8.8", @@ -2684,6 +2687,16 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz", "integrity": "sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==" }, + "node_modules/@types/pino": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/pino/-/pino-7.0.5.tgz", + "integrity": "sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==", + "deprecated": "This is a stub types definition. pino provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "pino": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -2719,6 +2732,17 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2856,6 +2880,14 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/axios": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", @@ -3973,6 +4005,22 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -4110,6 +4158,14 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-redact": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-xml-parser": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", @@ -4321,7 +4377,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5986,6 +6041,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -6210,6 +6270,52 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pino": { + "version": "8.15.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.1.tgz", + "integrity": "sha512-Cp4QzUQrvWCRJaQ8Lzv0mJzXVk4z2jlq8JNKMGaixC2Pz5L4l2p95TkuRvYbrEbe85NQsDKrAd4zalf7Ml6WiA==", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.1.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz", + "integrity": "sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==", + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-http": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.5.0.tgz", + "integrity": "sha512-kLGKNLyfWfdmrG1Ug0YdYpCTGbNcuD/YGC3g+elRU/Cm44UTs+tj/dZTxDN3bYauekxFxdLZhJuZdKKl0cml9w==", + "dependencies": { + "get-caller-file": "^2.0.5", + "pino": "^8.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -6333,6 +6439,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -6421,6 +6540,11 @@ } ] }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -6457,6 +6581,52 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/redis": { "version": "4.6.8", "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.8.tgz", @@ -6596,6 +6766,14 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6747,6 +6925,14 @@ "npm": ">= 3.0.0" } }, + "node_modules/sonic-boom": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6774,6 +6960,14 @@ "memory-pager": "^1.0.2" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -6809,6 +7003,33 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -6928,6 +7149,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thread-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.0.tgz", + "integrity": "sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==", + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 9d5d1ee..6df13f4 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,15 @@ "moment-timezone": "^0.5.43", "mongodb": "^4.13.0", "nodemailer": "^6.9.1", + "pino": "^8.15.1", + "pino-http": "^8.5.0", "redis": "^4.6.7", "zlib": "^1.0.5" }, "devDependencies": { "@owlboard/ts-types": "^0.0.9", "@types/jest": "^29.5.3", + "@types/pino": "^7.0.5", "eslint": "^8.39.0", "jest": "^29.6.2", "prettier": "^2.8.8", diff --git a/src/middlewares/auth.middlewares.js b/src/middlewares/auth.middlewares.js index 036ad6c..306912d 100644 --- a/src/middlewares/auth.middlewares.js +++ b/src/middlewares/auth.middlewares.js @@ -1,15 +1,13 @@ const utils = require("../utils/auth.utils"); -const log = require("../utils/logs.utils"); +const logger = require("../utils/logger.utils"); module.exports = async function authCheck(req, res, next) { - log.out("authMiddlewares: Checking authentication", "dbug"); + //log.out("authMiddlewares: Checking authentication", "dbug"); + logger.logger.debug("Auth check starting") try { var uuid = req.headers.uuid; } catch (err) { - log.out( - "authMiddlewares: UNABLE TO READ HEADER 'UUID' - User !isAuthed", - "warn" - ); + logger.logger.warn("Unable to read UUID header - Not authenticated") req.isAuthed = false; return next(); } @@ -17,18 +15,21 @@ module.exports = async function authCheck(req, res, next) { var result = (await utils.isAuthed(uuid)) || false; if (!result) { req.isAuthed = false; - log.out("authMiddlewares: User !isAuthed", "dbug"); + //log.out("authMiddlewares: User !isAuthed", "dbug"); + logger.logger.debug("Auth denied") } else { req.isAuthed = true; - log.out("authMiddlewares: User isAuthed", "dbug"); + //log.out("authMiddlewares: User isAuthed", "dbug"); + logger.logger.debug("Auth successful") } return next(); } catch (err) { - log.out( + /*log.out( "authMiddlewares: Unable to check auth, default to !isAuthed", "warn" - ); + );*/ + logger.logger.error(err, `Auth check failed`) req.isAuthed = false; - return next(); + return next(err); } }; diff --git a/src/utils/auth.utils.ts b/src/utils/auth.utils.ts index b433233..082d726 100644 --- a/src/utils/auth.utils.ts +++ b/src/utils/auth.utils.ts @@ -1,9 +1,9 @@ -const logs = require("../utils/logs.utils"); const crypt = require("crypto"); const db = require("../services/dbAccess.services"); const fs = require("fs/promises"); import { minifyMail } from "./minify.utils"; +import { logger } from "./logger.utils"; // Checks users registration key against issued keys async function isAuthed(uuid: string): Promise { @@ -12,10 +12,7 @@ async function isAuthed(uuid: string): Promise { uuid: uuid }; const res = await db.query("users", q); - logs.out( - "authUtils.checkUser: DB Query answer: " + JSON.stringify(res[0]), - "dbug" - ); + logger.debug(res, "checkUser: DB Query Result") const authorized = res && res[0] && res[0].domain; if (authorized) db.userAtime(uuid); return authorized; @@ -26,11 +23,7 @@ async function checkRequest(key: string) { // For some reason db.query seems to const collection = "registrations"; const query = { uuid: key }; const res = await db.query(collection, query); - logs.out("authUtils.checkRequest: Raw Result: " + res, "dbug") - logs.out( - "authUtils.checkRequest: DB Query result: " + JSON.stringify(res), - "dbug" - ); + logger.debug(res, "checkRequest: DB Lookup result") const result = res.length > 0 && res[0].time ? { result: true, domain: res[0].domain } @@ -57,10 +50,7 @@ async function generateConfirmationEmail(eml: string, uuid: string) { html: htmlMin, }; } catch (err) { - logs.out( - "mailServices.generateConfirmationEmail: Error reading template, " + err, - "err" - ); + logger.error(err, "generateConfirmationEmail: Error rendering email templates") return false; } } diff --git a/src/utils/logger.utils.ts b/src/utils/logger.utils.ts new file mode 100644 index 0000000..acf4616 --- /dev/null +++ b/src/utils/logger.utils.ts @@ -0,0 +1,14 @@ +import pino from "pino"; + +const runtime = process.env.NODE_ENV +let level: string + if (runtime === "production") { + level = "warning" + } else { + level = "debug" + } + + export const logger = pino({ + name: 'owlboard', + level: level, + });