From dd2c6eac323b1ff6541e3f3afed6b6464b478357 Mon Sep 17 00:00:00 2001 From: Alan Morel Date: Fri, 27 Oct 2023 14:06:58 -0400 Subject: [PATCH] feat: overhaul logger --- app/sharex/route.ts | 4 +- package.json | 4 +- pnpm-lock.yaml | 208 ++++++++++++++++++++++++- src/helpers/server/FileSystemHelper.ts | 29 +++- src/helpers/server/JournalHelper.ts | 14 +- src/helpers/server/Logger.ts | 120 ++++++++------ src/helpers/server/ResultHelper.ts | 4 +- 7 files changed, 314 insertions(+), 69 deletions(-) diff --git a/app/sharex/route.ts b/app/sharex/route.ts index 4823f76..48059da 100644 --- a/app/sharex/route.ts +++ b/app/sharex/route.ts @@ -1,6 +1,6 @@ import Config from "@/src/Config"; import { default as ServerConfig } from "@/src/helpers/Config"; -import { Logger } from "@/src/helpers/server/Logger"; +import logger from "@/src/helpers/server/Logger"; import { compareStrings, getRandomFilename } from "@/src/helpers/server/StringHelper"; import { promises as fs } from "fs"; @@ -41,7 +41,7 @@ export async function POST(request: Request): Promise { await fs.writeFile(path, data); - Logger.log(`Uploaded ${file.name} as ${filename}.${extension} from ShareX successfully`); + logger.log(`Uploaded ${file.name} as ${filename}.${extension} from ShareX successfully`); const result = { link: `${Config.app.url}/${path}` diff --git a/package.json b/package.json index 2910831..324e5c1 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,13 @@ "mime-types": "^2.1.35", "next": "^13.5.6", "nextjs-google-analytics": "^2.3.3", - "picocolors": "^1.0.0", + "pino": "^8.16.1", + "pino-pretty": "^10.2.3", "postcss": "^8.4.31", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", + "rotating-file-stream": "^3.1.1", "sharp": "^0.32.6", "tailwind-merge": "^1.14.0", "tailwindcss": "^3.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82393a7..ea1ae24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,9 +44,12 @@ dependencies: nextjs-google-analytics: specifier: ^2.3.3 version: 2.3.3(next@13.5.6)(react@18.2.0) - picocolors: - specifier: ^1.0.0 - version: 1.0.0 + pino: + specifier: ^8.16.1 + version: 8.16.1 + pino-pretty: + specifier: ^10.2.3 + version: 10.2.3 postcss: specifier: ^8.4.31 version: 8.4.31 @@ -59,6 +62,9 @@ dependencies: react-hot-toast: specifier: ^2.4.1 version: 2.4.1(csstype@3.1.2)(react-dom@18.2.0)(react@18.2.0) + rotating-file-stream: + specifier: ^3.1.1 + version: 3.1.1 sharp: specifier: ^0.32.6 version: 0.32.6 @@ -1057,6 +1063,13 @@ packages: through: 2.3.8 dev: true + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1240,6 +1253,11 @@ packages: has-symbols: 1.0.3 dev: true + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + /autoprefixer@10.4.16(postcss@8.4.31): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} @@ -1313,6 +1331,12 @@ packages: balanced-match: 1.0.2 concat-map: 0.0.1 + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -1337,6 +1361,13 @@ packages: ieee754: 1.2.1 dev: false + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /bundle-name@3.0.0: resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} engines: {node: '>=12'} @@ -1473,6 +1504,10 @@ packages: color-string: 1.9.1 dev: false + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: false + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -1573,6 +1608,10 @@ packages: engines: {node: '>=8'} dev: true + /dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dev: false + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -2187,6 +2226,16 @@ packages: engines: {node: '>=0.10.0'} dev: true + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -2222,6 +2271,10 @@ packages: engines: {node: '>=6'} dev: false + /fast-copy@3.0.1: + resolution: {integrity: sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==} + dev: false + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -2252,6 +2305,15 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fast-redact@3.3.0: + resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} + engines: {node: '>=6'} + dev: false + + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: false + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -2456,6 +2518,17 @@ packages: path-is-absolute: 1.0.1 dev: true + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: false + /global-dirs@0.1.1: resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} engines: {node: '>=4'} @@ -2563,6 +2636,13 @@ packages: dependencies: function-bind: 1.1.2 + /help-me@4.2.0: + resolution: {integrity: sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==} + dependencies: + glob: 8.1.0 + readable-stream: 3.6.2 + dev: false + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true @@ -2905,6 +2985,11 @@ packages: react: 18.2.0 dev: false + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: false + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3162,6 +3247,13 @@ packages: dependencies: brace-expansion: 1.1.11 + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -3384,6 +3476,11 @@ packages: es-abstract: 1.22.3 dev: true + /on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -3513,6 +3610,54 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} + /pino-abstract-transport@1.1.0: + resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} + dependencies: + readable-stream: 4.4.2 + split2: 4.2.0 + dev: false + + /pino-pretty@10.2.3: + resolution: {integrity: sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw==} + hasBin: true + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.1 + fast-safe-stringify: 2.1.1 + help-me: 4.2.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pump: 3.0.0 + readable-stream: 4.4.2 + secure-json-parse: 2.7.0 + sonic-boom: 3.7.0 + strip-json-comments: 3.1.1 + dev: false + + /pino-std-serializers@6.2.2: + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + dev: false + + /pino@8.16.1: + resolution: {integrity: sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.3.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pino-std-serializers: 6.2.2 + process-warning: 2.3.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 3.7.0 + thread-stream: 2.4.1 + dev: false + /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -3673,6 +3818,15 @@ packages: hasBin: true dev: true + /process-warning@2.3.0: + resolution: {integrity: sha512-N6mp1+2jpQr3oCFMz6SeHRGbv6Slb20bRhj4v3xR99HqNToAcOe1MFOp4tytyzOfJn+QtN8Rf7U/h2KAn4kC6g==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: false + /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -3700,6 +3854,10 @@ packages: resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} dev: false + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -3834,12 +3992,28 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readable-stream@4.4.2: + resolution: {integrity: sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: false + /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -3936,6 +4110,11 @@ packages: glob: 7.2.3 dev: true + /rotating-file-stream@3.1.1: + resolution: {integrity: sha512-PNF1iDkxcZG+T87uUzLlcO4aquTCyY8yl+Q/OTK4dMwhwWDYWU4ZATYeIXHmYVGIzqZ2MrpY4WIkYc9Bsc3Nzw==} + engines: {node: '>=14.0'} + dev: false + /run-applescript@5.0.0: resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} engines: {node: '>=12'} @@ -3975,12 +4154,21 @@ packages: regexp-tree: 0.1.27 dev: true + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + /scheduler@0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 dev: false + /secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + dev: false + /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -4079,6 +4267,12 @@ packages: engines: {node: '>=8'} dev: true + /sonic-boom@3.7.0: + resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -4114,7 +4308,6 @@ packages: /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: true /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} @@ -4218,7 +4411,6 @@ packages: /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - dev: true /styled-jsx@5.1.1(react@18.2.0): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} @@ -4371,6 +4563,12 @@ packages: dependencies: any-promise: 1.3.0 + /thread-stream@2.4.1: + resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} + dependencies: + real-require: 0.2.0 + dev: false + /through2@4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} dependencies: diff --git a/src/helpers/server/FileSystemHelper.ts b/src/helpers/server/FileSystemHelper.ts index 43b8691..e09632d 100644 --- a/src/helpers/server/FileSystemHelper.ts +++ b/src/helpers/server/FileSystemHelper.ts @@ -1,11 +1,34 @@ -import { promises as fs } from "fs"; +import logger from "@/src/helpers/server/Logger"; +import fs, { promises as fsAsync } from "fs"; -export const pathExists = async (path: string): Promise => { +export const fileExists = async (path: string): Promise => { try { - await fs.stat(path); + await fsAsync.stat(path); } catch (error) { + logger.critical(`Failed to check if file exists: ${JSON.stringify(error)}`); return false; } return true; }; + +export const createIfNotExists = (directory: string): void => { + if (!fs.existsSync(directory)) { + fs.mkdirSync(directory, { recursive: true }); + } +}; + +export const checkFileSize = (filePath: string): number => { + try { + const stats = fs.statSync(filePath); + return stats.size; + } catch (error) { + return -1; + } +}; + +export const deleteFile = (filePath: string): void => { + try { + fs.unlinkSync(filePath); + } catch (error) {} +}; diff --git a/src/helpers/server/JournalHelper.ts b/src/helpers/server/JournalHelper.ts index 6dc321a..e34a97e 100644 --- a/src/helpers/server/JournalHelper.ts +++ b/src/helpers/server/JournalHelper.ts @@ -1,6 +1,6 @@ import Config from "@/src/helpers/Config"; -import { pathExists } from "@/src/helpers/server/FileSystemHelper"; -import { Logger } from "@/src/helpers/server/Logger"; +import { fileExists } from "@/src/helpers/server/FileSystemHelper"; +import logger from "@/src/helpers/server/Logger"; import { compareStrings } from "@/src/helpers/server/StringHelper"; import { getYYYYMMDD } from "@/src/helpers/shared/DateFormatter"; import { promises as fs } from "fs"; @@ -11,14 +11,14 @@ export function isJournalAuthenticated(): boolean { const password = cookieStore.get(Config.journal.cookieName)?.value; if (!password) { - Logger.critical("No password cookie found"); + logger.critical("No password cookie found"); return false; } const journalPassword = Config.journal.password; if (!compareStrings(password, journalPassword)) { - Logger.critical("Password cookie does not match"); + logger.critical("Password cookie does not match"); return false; } @@ -38,7 +38,7 @@ function getEntryPath(date: Date): string { export async function getJournalEntry(date: Date): Promise { const path = getEntryPath(date); - const entryExists = await pathExists(path); + const entryExists = await fileExists(path); if (entryExists) { return await fs.readFile(path, "utf-8"); @@ -52,14 +52,14 @@ export async function saveJournalEntry(date: Date, entry: string): Promise { + return (time: number | Date): string => { + let directory = `${base}${prefix}/${level}`; - public static debug(message: string, id: string | null = null): void { - const color = magenta; - this.print(message, color); - this.writeToFile("debug", message, id); - } + if (!time) { + createIfNotExists(directory); - private static print(message: string, color: Formatter): void { - console.log(`${color(message)}`); - this.writeToFile("all", message); - } + return `${directory}/${level}.log`; + } - private static async writeToFile(type: string, message: string, id: string | null = null): Promise { - const now = new Date(); + const now = new Date(time); const timestamp = now.toISOString().split("T")[0]; const [year, month] = [...timestamp.split("-")]; - const timestampReadable = formatTimestamp(now); - const log = `[${timestampReadable}]: ${message}\r\n`; + directory += `/${year}/${month}`; - await this.write(`logs/${type}/${year}/${month}`, timestamp, log); + createIfNotExists(directory); - if (id) { - await this.write(`logs/users/${id}/${type}/${year}/${month}`, timestamp, log); - } - } + return `${directory}/${timestamp}.log`; + }; +}; - private static async write(directory: string, timestamp: string, log: string): Promise { - const path = `${directory}/${timestamp}.log`; +function getStreams(prefix: string): StreamEntry[] { + return [ + ...levels.map(level => { + const stream = createStream(getGenerator(prefix, level), { + interval: "1d" + }); - const exists = await pathExists(directory); + stream.addListener("rotated", (filename: string) => { + const size = checkFileSize(filename); - if (!exists) { - await fs.mkdir(directory, { recursive: true }); + if (size === 0) { + deleteFile(filename); + } + }); + + return { + level, + stream: stream + }; + }), + { + stream: pretty({ + colorize: true, + translateTime: "SYS:dd-mm-yyyy HH:MM:ss TT" + }) } + ]; +} - await fs.appendFile(path, log); +const pinoOptions = { + level: "debug", + safe: true, + redact: { + paths: ["pid", "hostname"], + remove: true } +}; + +function createPinoLogger(prefix: string): Logger { + return pino(pinoOptions, multistream(getStreams(prefix))); } + +const pinoLogger = createPinoLogger(""); + +const logger = { + log: (message: string): void => { + pinoLogger.info(message); + }, + error: (error: string): void => { + pinoLogger.error(error); + }, + critical: (error: string): void => { + pinoLogger.error(error); + pinoLogger.fatal(error); + } +}; + +export default logger; diff --git a/src/helpers/server/ResultHelper.ts b/src/helpers/server/ResultHelper.ts index 191de1c..422aa08 100644 --- a/src/helpers/server/ResultHelper.ts +++ b/src/helpers/server/ResultHelper.ts @@ -1,4 +1,4 @@ -import { Logger } from "@/src/helpers/server/Logger"; +import logger from "@/src/helpers/server/Logger"; import { NextResponse } from "next/server"; export type Result = ResultSuccess | ResultFailure; @@ -29,7 +29,7 @@ export function sendFailure(error: string = ""): NextResponse { } as ResultFailure; if (error.length) { - Logger.error(error); + logger.error(error); } return NextResponse.json(data);