[READ-ONLY] Mirror of https://github.com/FoxxMD/logging. A typed, opinionated, batteries-included, Pino-based logging solution for backend TS/JS projects foxxmd.github.io/logging
child-logger logging logging-library nodejs pinojs typescript-library
0

Configure Feed

Select the types of activity you want to include in your feed.

docs: Refactor logging dir build logic to handle dynamic CWD

FoxxMD (Mar 11, 2024, 1:18 PM EDT) 3c12d2aa b2db83eb

+54 -30
+2 -2
src/constants.ts
··· 3 3 4 4 const projectDir = process.cwd(); 5 5 6 - let logPath = path.resolve(projectDir, `./logs/app.log`); 6 + const logPathRelative = './logs/app.log'; 7 7 8 8 export { 9 - logPath, 9 + logPathRelative, 10 10 projectDir 11 11 }
+7 -7
src/funcs.ts
··· 1 1 import process from "process"; 2 2 import {FileLogOptions, FileLogOptionsParsed, LOG_LEVEL_NAMES, LogLevel, LogOptions, LogOptionsParsed} from "./types.js"; 3 - import {logPath, projectDir} from "./constants.js"; 3 + import {projectDir, logPathRelative} from "./constants.js"; 4 4 import {isAbsolute, resolve} from 'node:path'; 5 5 6 6 export const isLogOptions = (obj: object = {}): obj is LogOptions => { ··· 36 36 /** 37 37 * Takes an object and parses it into a fully-populated LogOptions object based on opinionated defaults 38 38 * */ 39 - export const parseLogOptions = (config: LogOptions = {}): LogOptionsParsed => { 39 + export const parseLogOptions = (config: LogOptions = {}, baseDir?: string): LogOptionsParsed => { 40 40 if (!isLogOptions(config)) { 41 41 throw new Error(`Logging levels were not valid. Must be one of: 'silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug', -- 'file' may be false.`) 42 42 } ··· 55 55 if (file.level === false) { 56 56 fileObj = {level: false}; 57 57 } else { 58 - const path = typeof file.path === 'function' ? file.path : getLogPath(file.path); 58 + const path = typeof file.path === 'function' ? file.path : getLogPath(file.path, baseDir); 59 59 fileObj = { 60 60 level: configLevel || defaultLevel, 61 61 ...file, ··· 67 67 } else { 68 68 fileObj = { 69 69 level: file, 70 - path: getLogPath() 70 + path: getLogPath(undefined, baseDir) 71 71 }; 72 72 } 73 73 ··· 83 83 }; 84 84 } 85 85 86 - export const getLogPath = (path?: string) => { 86 + export const getLogPath = (path?: string, baseDir = projectDir) => { 87 87 let pathVal: string; 88 88 if (path !== undefined) { 89 89 pathVal = path; 90 90 } else if (typeof process.env.LOG_PATH === 'string') { 91 91 pathVal = process.env.LOG_PATH; 92 92 } else { 93 - pathVal = logPath; 93 + pathVal = logPathRelative; 94 94 } 95 95 96 96 if (isAbsolute(pathVal)) { 97 97 return pathVal; 98 98 } 99 99 100 - return resolve(projectDir, pathVal); 100 + return resolve(baseDir, pathVal); 101 101 }
+45 -21
tests/index.test.ts
··· 14 14 15 15 16 16 const testConsoleLogger = (config?: object): [Logger, Transform, Transform] => { 17 - const opts = parseLogOptions(config); 17 + const opts = parseLogOptions(config, process.cwd()); 18 18 const testStream = new PassThrough(); 19 19 const rawStream = new PassThrough(); 20 20 const logger = buildLogger('debug', [ ··· 34 34 return [logger, testStream, rawStream]; 35 35 } 36 36 37 - const testFileRollingLogger = async (config?: object, logPath: string = '.') => { 38 - const opts = parseLogOptions(config); 37 + const testFileRollingLogger = async (config?: object) => { 38 + const opts = parseLogOptions(config, process.cwd()); 39 + const { 40 + file: { 41 + level, 42 + path: logPath, 43 + frequency 44 + } = {} 45 + } = opts; 39 46 const streamEntry = await buildDestinationRollingFile( 40 - opts.file.level, 47 + level, 41 48 { 42 - frequency: 'daily', 49 + frequency, 43 50 path: logPath, 44 51 ...opts 45 52 } ··· 49 56 ]); 50 57 }; 51 58 52 - const testFileLogger = async (config?: object, logPath: string = './app.log') => { 53 - const opts = parseLogOptions(config); 59 + const testFileLogger = async (config?: object) => { 60 + const opts = parseLogOptions(config, process.cwd()); 61 + const { 62 + file: { 63 + path: logPath, 64 + level, 65 + } = {} 66 + } = opts; 54 67 const streamEntry = buildDestinationFile( 55 - opts.file.level, 68 + level, 56 69 { 57 70 path: logPath, 58 71 ...opts ··· 63 76 ]); 64 77 }; 65 78 66 - const testRollingAppLogger = async (config?: object, logPath: string = '.'): Promise<[Logger, Transform, Transform]> => { 67 - const opts = parseLogOptions(config); 79 + const testRollingAppLogger = async (config?: object): Promise<[Logger, Transform, Transform]> => { 80 + const opts = parseLogOptions(config, process.cwd()); 81 + const { 82 + file: { 83 + path: logPath, 84 + level, 85 + frequency 86 + } = {} 87 + } = opts; 68 88 const testStream = new PassThrough(); 69 89 const rawStream = new PassThrough(); 70 90 const streamEntry = await buildDestinationRollingFile( 71 - opts.file.level, 91 + level, 72 92 { 73 - frequency: 'daily', 93 + frequency, 74 94 path: logPath, 75 95 ...opts 76 96 } ··· 94 114 return [logger, testStream, rawStream]; 95 115 } 96 116 97 - const testAppLogger = (config?: object, logPath: string = '.'): [Logger, Transform, Transform] => { 98 - const opts = parseLogOptions(config); 117 + const testAppLogger = (config?: object): [Logger, Transform, Transform] => { 118 + const opts = parseLogOptions(config, process.cwd()); 119 + const { 120 + file: { 121 + path: logPath, 122 + level, 123 + } = {} 124 + } = opts; 99 125 const testStream = new PassThrough(); 100 126 const rawStream = new PassThrough(); 101 127 const streamEntry = buildDestinationFile( 102 - opts.file.level, 128 + level, 103 129 { 104 130 path: logPath, 105 131 ...opts ··· 220 246 const logger = await testFileRollingLogger({file: 'debug'}); 221 247 logger.debug('Test'); 222 248 await sleep(20); 223 - expect(readdirSync('.').length).eq(1); 249 + expect(readdirSync('./logs').length).eq(1); 224 250 }, {unsafeCleanup: true}); 225 251 }); 226 252 }); ··· 241 267 const logger = await testFileLogger({file: 'debug'}); 242 268 logger.debug('Test'); 243 269 await sleep(20); 244 - expect(readdirSync('.').length).eq(1); 270 + expect(readdirSync('./logs').length).eq(1); 245 271 }, {unsafeCleanup: true}); 246 272 }); 247 273 }); ··· 249 275 describe('Combined', function() { 250 276 it('It writes to rolling file and console', async function () { 251 277 await withLocalTmpDir(async () => { 252 - const logPath = './logs/app.log'; 253 - const [logger, testStream, rawStream] = await testRollingAppLogger({file: 'debug'}, logPath); 278 + const [logger, testStream, rawStream] = await testRollingAppLogger({file: 'debug'}); 254 279 const race = Promise.race([ 255 280 pEvent(testStream, 'data'), 256 281 sleep(10) ··· 269 294 270 295 it('It writes to file and console', async function () { 271 296 await withLocalTmpDir(async () => { 272 - const logPath = './logs/app.log'; 273 - const [logger, testStream, rawStream] = testAppLogger({file: 'debug'}, logPath); 297 + const [logger, testStream, rawStream] = testAppLogger({file: 'debug'}); 274 298 const race = Promise.race([ 275 299 pEvent(testStream, 'data'), 276 300 sleep(10)