UNPKG

simpl-loggar

Version:

Simple node.js logger

350 lines (265 loc) 8.71 kB
# SimpleLogger This project is simple logger for node.js. It utilizes winston under the hood. > [!TIP] > This app is using new typescript decorators. That means, you need to disable experimental decorators in order to use it. > That makes this app incompatible with Nest.js. TLDR; 1. [Use this package](#1-use-package) 2. [Work on this project](#1-work-on-this-project) ## 1. Use this package ### 1.1 General introduction This package only supports node.js and will not work on frontend. You can modify it and exclude winston for it to work. This app has only 1 purpose, which is to log data. Most of logs require at least 2 params, where first param is 'target' and others are messages related to it. For example ```ts function doSomething() { const iCanDoMath = 1+1 Log.log('Something', 'I am doing something') return iCanDoMath } ``` Will output data in terminal like this ```log [18:05:03] Log.LOG: Something I am doing something ``` And save it in logs using winston: ```log [2024-11-08T18:05:03.311Z] info: Something - I am doing something ``` In addition to default logger, there is also contextLogger/clientLogger. This logger is used to log params with context. Its logs will look like this: ```log [18:05:03] Log.LOG: Something I am doing something - { contextParam: contextParamValue } ``` And save it in logs using winston: ```log [2024-11-08T18:05:03.311Z] info: Something - I am doing something - { "contextParam": "contextParamValue" } ``` ### Log types #### Basic There are multiple log types. In no particular order: - Log ```ts function doSomething() { const iCanDoMath = 1+1 Log.log('Something', 'I am doing something') return iCanDoMath } ``` Log is generic log, which is used to log everything - Error ```ts function doSomething() { try { throw new Error("test") } catch (err) { Log.error('Something', 'We got an error!', err.message, err.stack) } } ``` Error is used to mark errors. Currently pushing full error object does not log trace to files. Please make sure to log it the same way I did above - warn ```ts function dosomething(anothernumber) { const icandomath = 1+anothernumber if(icandomath > 2) log.warn('Number', 'Number is above 2. this can break in the future!') return icandomath } ``` warn is warning log, which is used to mark data that did not throw an error, but might be incorrect, or any other type of warning - Trace ```ts function doSomething() { const iCanDoMath = 1+1 Log.trace('Something', 'I am here') return iCanDoMath } ``` Trace log is just a simple trace, which marks flow of your code. - Debug ```ts function doSomething() { Log.debug('Something', 'I am here') const iCanDoMath = 1+1 Log.debug('Something', 'And now here') return iCanDoMath } ``` Debug is a debugging log, which is disabled in console and files, while your application is in production mode ( based on NODE_ENV === `production` ). This log is intended to show additional debugging data in development / tests - Time ```ts function doSomething() { Log.time('Doing something', 'Just started doing something') const iCanDoMath = 1+1 Log.endTime('Doing something', 'Finished doing something') return iCanDoMath } ``` Time will count time between `time` and `endTime` methods. Remember, that 'target' allows function to actually start and finish counters. #### Decorators There are multiple log types. In no particular order: > [!WARNING] > Decorators use async under the hood. In order to use them, make sure your function is async. They will work in sync, but on error will crash your app - Log ```ts @Log.decorateLog('I am logging data') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Error ```ts @Log.decorateError('Finished doSomethhing. This function should not run!') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Warn ```ts @Log.decorateWarn('Finished doSomething. This function might change in the future!') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Trace ```ts @Log.decorateTrace('I am here') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Debug ```ts @Log.decorateDebug('Debbuging that doSomething just finished') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Time ```ts @Log.decorateTime('Just finished doing something') async function doSomething() { return new Promise(resolve => { resolve(2) }) } ``` - Debug time ```ts @Log.decorateDebugTime('Just finished doing something. This will not show up in production') function doSomething() { const iCanDoMath = 1+1 return iCanDoMath } ``` - ClientLogger/ContextLogger This logger has to be initialized for each request / client, allowing you to "follow" user's actions. ```ts import { ClientLog } from 'simpleLogger' const log = new ClientLog() log.createContext({param: val, param2: val2, param3: val2}) ``` Now logging data will result with "context" being attached to each log. Example: ```ts log.debug('Something', "I am doing something") ``` ```log [18:05:03] Log.LOG: Something I am doing something - { "param": "val", "param2": "val2", "param3": "val2" } ``` Params can be overwritten on the run. Simply add another context param with the same key as before: ```ts log.createContext({param: val5}) ``` > [!TIP] > There is no way to overwrite nested keys. In order to do that, overwrite full parent ### 1.2 Saves logs location All logs are saved in files. #### On linux ```text ~/.cache/"package.json -> productName"/logs ``` #### On windows ```text ~/AppData/Roaming/"package.json -> productName"/logs ``` You can also trigger function ```js Log.setPrefix('test'); ``` ### 1.3 Prefix in saved logs Above function will group all logs from your app under folder `test`. Example: This app will prioritize env `APP_NAME`. If its not set, `name` in your package.json will be used as your log. Lets say that your `name` is "Authorizations" and APP_NAME is not set - No prefix set ``` ~/.cache/Authroizations/logs ``` - Prefix set to `test` ``` ~/.cache/test/Authroizations/logs ``` ### 1.4 Validation rules This logger includes validation rules, which can be used to disable certain logs. ```js const validateLog = (log) => { if(log.includes('test')) return false return true } Log.setLogRule(validateLog, ELogTypes.Error) ``` Above function is a basic example of disabling all error logs, which include 'test' in message. More realistic usage can be: ```js function doSomething() { Log.debug('I am doing something') try { doSomethingElse() } catch(err) { Log.error('DoSomething', `We got an error! ${err.message}, code: ${err.code}`) } } const validateLog = (log) => { if(/\d/.test(log)) return false return true } Log.setLogRule(validateLog, ELogTypes.Error) ``` In above example, I am using debug log, which will not show up in production, but I am also using error, which will show in production. Errors that I throw include additional field "code", which defines what kind of error was thrown. If I do not care to see errors thrown by me and I only want to see unexpected errors, I can disable errors logging for errors with code. Without above rule, I would get 2 logs ```log [2024-11-08T18:05:03.311Z] error: We got an error! Email was not provided, code: 22 [2024-11-08T18:05:03.311Z] error: We got an error! Cannot read property of undefined, reading 'something', code: ``` With above rule: ```log [2024-11-08T18:05:03.311Z] error: We got an error! Cannot read property of undefined, reading 'something', code: ``` ### 1.5 Memory only If you are not planning on not using winston, you can disable it by running ```ts Log.disableWinston(); ``` Above line will simply keep all logs in memory. ## 2. Work on this project ### 2.1 How to start #### Install dependencies ```shell npm install / yarn ``` ### 2.2. How to build ```shell npm run build / yarn build ``` If you even encounter strange build behavior, tsconfig is set to create build with cache. Set option `incremental` in tsConfig to false. In addition to that, remove `tsconfig.tsbuildinfo`, which contains cached information about build After compiling this code, you can also run ```shell npm run build:common / yarn build:common ``` Above command will transpile compiled code into commonJS files, which will work in non-esm projects. Make sure to run this after every build, unless you do not work with commonJS