Installations
npm install loggis
Developer Guide
Typescript
Yes
Module System
CommonJS, ESM
Min. Node Version
>=12.22.0
Node Version
16.17.0
NPM Version
8.15.0
Score
73.9
Supply Chain
99.4
Quality
76.1
Maintenance
100
Vulnerability
100
License
Releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (100%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
mekh
Download Statistics
Total Downloads
31,094
Last Day
30
Last Week
159
Last Month
611
Last Year
5,016
GitHub Statistics
4 Stars
79 Commits
2 Forks
2 Watching
7 Branches
2 Contributors
Bundle Size
10.13 kB
Minified
3.20 kB
Minified + Gzipped
Package Meta Information
Latest Version
3.0.1
Package Id
loggis@3.0.1
Unpacked Size
83.86 kB
Size
20.54 kB
File Count
45
NPM Version
8.15.0
Node Version
16.17.0
Total Downloads
Cumulative downloads
Total Downloads
31,094
Last day
11.1%
30
Compared to previous day
Last week
-4.2%
159
Compared to previous week
Last month
107.8%
611
Compared to previous month
Last year
36.7%
5,016
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
loggis
A simple, lightweight, console logger for Node.JS.
A perfect choice for Kubernetes, Docker, and other systems that collect logs directly from stdout.
Features
- no dependencies
- ready for usage right out of the box
- supports JSON
- global and individual configuration of loggers
- automatic objects serialization
- automatic circular structures handling
- robust configuration
- tracing information - caller's file and function name, and even line number where the log method has been called
- colored output
- safe for any kind of data - Express req/res, Sequelize models, Error objects, etc.
- both CommonJS and ESM are supported
- Typescript friendly
Installation
1$ npm install loggis
Quick start
The logger can be used right out of the box, i.e. it does not require any configuration by default. The default settings are:
- loglevel: info
- colorize: false
- logline: [ISO timestamp] [level] [process.pid] [category] [filename||functionName:lineNumber] message
- primitives
- Function => <Function ${function.name || 'anonymous'}>
- Date instance => Date.toISOString()
- Promise instance => '
' - Buffer instance - Buffer.toString()
- Error instance => error properties/values concatenated by a new line
1// /app/test_log.js 2const logger = require('loggis'); 3 4const logFn = () => { 5 logger.info('its simple'); 6 logger.error('this', ['will', 'be'], { serialized: { into: 'a string' } }); 7 8 // won't be printed since the default loglevel is info 9 logger.trace('trace info'); 10}; 11 12logFn(); 13// [2022-09-03T08:17:26.549Z] [INFO] [123] [default] [/app/test_log.js||logFn:4] its simple 14// [2022-09-03T08:17:26.554Z] [ERROR] [123] [default] [/app/test_log.js||logFn:5] this ["will","be"] {"serialized":{"into":"a string"}} 15
Configuration
The default configuration can be set either through the configure
method or the environment variables.
Each logger instance can be configured individually by setting an instance properties like level
, colorize
, etc.
Environment variables
The default configuration can be set through the environment variables.
Name | Type | Default value | Description |
---|---|---|---|
LOG_LEVEL | String | info | The default logging level |
LOG_JSON | Boolean | false | Turns on/off JSON output |
LOG_COLORS | Boolean | false | Turns on/off the colorized output |
Configure options
The default configuration can be passed to the configure
method.
It accepts the following parameters:
- loglevel - the default logging level, valid values are
error
,warn
,info
,debug
, andtrace
- json - use json output
- colorize - use colored output
- format - custom message formatter (DEPRECATED)
- logline - the Logline instance
- primitives - the Primitives instance
The same parameters can be used for an individual configuration of a logger.
Circulars
It's safe to pass any kind of arguments to the log functions, including Express requests, Sequelize models, etc. The logger automatically detects circular structures and replaces them by string references. The reference is a path within an object.
1const logger = require('loggis'); 2 3const a = { a: 1 }; 4a.b = a; // circular reference 5a.c = [1, { d: 2, e: { f: 'abc' } }] 6a.g = a.c[1].e; // circular reference 7 8logger.info(a); 9// ...{"a":1,"b":"[REF => .]","c":[1,{"d":2,"e":{"f":"abc"}}],"g":"[REF => c[1].e]"}
Custom formatter (deprecated)
The formatter function accepts an object with the following properties:
- args - an array of arguments that was passed to a log method
- level - logging level
- logger - logger instance
It might be convenient to set the default message format for a particular application.
For example, if you want to:
- log message in JSON format
- define and log the module name from which the log method is called
- set your own dataset that should be logged
- etc
You can do it like this:
1// ./src/logger/index.js 2const loggis = require('loggis'); 3 4const customFormatter = ({ args, level, logger }) => JSON.stringify({ 5 date: new Date(), 6 module: module.parent.filename.replace(process.cwd(), ''), 7 category: logger.category, 8 level, 9 data: args, // be careful, it might crash if data is not compatible with JSON.stringify 10}); 11 12loggis.configure({ format: customFormatter }); 13 14module.exports = loggis; 15 16// ./src/app.js 17const logger = require('./logger'); 18 19const log = logger.getLogger('MY_APP'); 20 21log.info('the configuration is =>', { 22 level: logger.loglevel, 23 color: logger.colorize, 24 json: logger.json, 25}); 26 27// ./index.js 28require('./src/app'); 29 30// {"date":"2022-09-03T08:17:26.549Z","module":"/app.js","category":"MY_APP","level":"info","data":["the configuration is =>",{"level":"info","color":false,"json":false}]}
Usage examples
Set the default configuration, get a logger, use it
1const logger = require('loggis') 2 3const log = logger.configure({ loglevel: 'debug' }).getLogger('MY_APP'); 4 5log.error('easy to log error') 6log.debug('easy to log debug'); 7log.trace('will not be printed, since the log level is DEBUG'); 8// [2022-09-03T08:17:26.549Z] [ERROR] [123] [MY_APP] [/app/test_log.js||-:5] easy to log error 9// [2022-09-03T08:17:26.554Z] [DEBUG] [123] [MY_APP] [/app/test_log.js||-:6] easy to log debug 10
JSON format
1const logger = require('loggis'); 2 3logger.configure({ json: true }); 4 5logger.info('user info =>', { id: 1, name: 'John', email: 'mail@g.co' }); 6 7// {"date":"2022-09-03T08:17:26.549Z","level":"info","pid":123,"category":"json","filename":"/app/test_log.js","function":"-","line":5,"data":["user info =>",{"id":1,"name":"John","email":"mail@g.co"}]} 8
The default and an individual configuration
1const logger = require('loggis'); 2 3logger.configure({ loglevel: 'warn', colorize: true }); 4 5const logLine = logger.getLogger('line'); // the default configuration will be applied 6const logJson = logger.getLogger('json'); 7 8// configure an instance 9logJson.loglevel = 'trace'; 10logJson.json = true; 11logJson.colorize = false; 12 13logLine.info('the configuration is =>', { 14 level: logLine.loglevel, 15 color: logLine.colorize, 16 json: logLine.json, 17}); 18 19logJson.trace('the configuration is =>', { 20 level: logJson.loglevel, 21 color: logJson.colorize, 22 json: logJson.json, 23}); 24 25 26// [2022-09-03T08:17:26.549Z] [WARN] [123] [line] [/app/test_log.js||-:13] the configuration is => {"level":"warn","color":true,"json":false} 27// {"date":"2022-09-03T08:17:26.554Z","level":"trace","pid":123,"category":"json","filename":"/app/test_log.js","function":"-","line":19,"data":["the configuration is =>",{"level":"trace","color":false,"json":true}]}
ESM
1import logger from 'loggis'; 2 3const log = logger.getLogger('MY_APP');
1import { getLogger } from 'loggis'; 2 3const log = getLogger('MY_APP')
Advance configuration
Primitives
Data processing includes two stages:
- parsing each argument passed to the logger function
- formatting the string that will be printed
The parsing of each argument looks like this:
- the parser checks if the formatting rules are defined for the given element
- if such rules were found, they are sequentially applied to the element
- if the element is an object, then for each nested element (array item, object key value), the entire chain is repeated
This way it's possible to format any element at any level of nesting.
An element for which one or more formatting rules are specified is called a primitive
.
The formatting rules for primitives are set by an instance of the Primitives
class, the add
method.
This method takes two arguments:
- the first one is a function that takes an element as an argument and returns a boolean if the element is the given primitive
- the second one is a function that takes an element as an argument and returns the modified element
The add
method returns the instance itself, so the method can be chained.
The Primitives
class is available in the formatters
property of the logger.
An instance of the Primitives
class can be passed to the configure
method of the logger as the primitives
parameter.
Example:
1const logger = require('loggis'); 2 3const primitives = new logger.formatters.Primitives() 4 .add( 5 (item) => typeof item === 'number', // for any number 6 (item) => item.toFixed(2), // apply this function 7 ); 8 9logger.configure({ primitives }); 10 11logger.info(10.987654, '123.1589', { float: 1.5499, int: 1, str: '9.98765' }); 12// ... 10.99 123.1589 {"float":"1.55","int":"1.00","str":"9.98765"}
For convenience, the Primitives
class has two static methods - typeof
and instanceof
with the following definitions:
1 interface Cls<T, A extends any[] = any[]> extends Function { new(...args: A): T; } 2 3 static typeof<T = any>(type: string): ((data: T) => boolean); 4 static instanceof<T, V = any>(cls: Cls<T>): ((data: V) => boolean);
Primitives default configuration
1primitives 2 .add(Primitives.typeof('function'), (data) => `<Function ${data.name || 'anonymous'}>`) 3 .add(Primitives.instanceof(Date), (date) => date.toISOString()) 4 .add(Primitives.instanceof(Buffer), (data) => data.toString()) 5 .add(Primitives.instanceof(Promise), () => '<Promise>') 6 .add(Primitives.instanceof(Error), (error) => Object 7 .getOwnPropertyNames(error) 8 .reduce((acc, prop) => `${acc}\n${prop}: ${error[prop]}`, '')); 9
Primitives usage examples
Filter sensitive data:
1const logger = require('loggis'); 2const { Primitives } = logger.formatters; 3 4const isObject = (obj) => typeof obj === 'object' && obj !== null && !Array.isArray(obj); 5const hide = (obj, prop) => (Object.hasOwn(obj, prop) ? ({ ...obj, [prop]: '***' }) : obj); 6 7const primitives = new Primitives() 8 .add(isObject, (obj) => hide(obj, 'password')) 9 .add(isObject, (obj) => hide(obj, 'card_number')) 10 .add(isObject, (obj) => hide(obj, 'card_cvv')); 11 12logger.configure({ primitives }); 13 14logger.info({ user: { id: 1, name: 'John', password: 'secret', card: { card_cvv: 321, card_number: 4111111111111111 } } }); 15// ... {"user":{"id":1,"name":"John","password":"***","card":{"card_cvv":"***","card_number":"***"}}}
Sequelize models serialization
1const { Model } = require('sequelize'); 2const logger = require('loggis'); 3 4const primitives = new logger.formatters.Primitives() 5 .add(Primitives.instanceof(Model), (model) => model.toJSON())
Logline
The elements to be printed are specified by calling the add
method of an instance of the Logline
class.
The add
method accepts a Message
instance and returns any type of data.
The Message
instance has the following properties:
- date - new Date()
- pid - process.pid
- data - an array of items returned by the Parser (see Primitives)
- level - message level, i.e. for log.error it will be error
- category - logger category (logger.getLogger('myapp') => the category is myapp);
- fileName - the name of the file where the logger function was called
- lineNumber - line number where the logger method was called
- functionName - name of the function from which the logger method was called
- text - could be a string or an array depending on
json
option of the logger
The Logline
class is available in the formatters
property of the logger.
The join
method of the logline instance defines a separator that is used while joining all the logline elements. It does not work for JSON format.
1const logger = require('loggis'); 2const { Logline } = logger.formatters; 3 4// --- Simplest format --- 5const logline = new Logline().add(message => message.text); 6logger.configure({ logline }).info(1, [2, 3], { 4: 5 }); // 1 [2,3] {"4":5} 7 8// --- Static text --- 9const logline = new Logline() 10 .add(() => '[static_text]') 11 .add(message => `[${message.text}]`); 12logger.configure({ logline }).info('log message'); // [static_text] [log message] 13 14// --- JOIN --- 15const logline = new Logline() 16 .add(message => message.date.valueOf()) 17 .add(message => message.level.toUpperCase()) 18 .add(message => message.pid) 19 .add(message => message.text) 20 .join(' | '); 21logger.configure({ logline }).info('log message'); // 1662193046549 | INFO | 123 | log message 22 23// --- JSON format --- 24const logline = new Logline() 25 .add(message => ({ date: message.date })) 26 .add(message => ({ message: message.text })); 27logger.configure({ json: true, logline }).info('user =>', { id: 1, name: 'John' }); // {"date":"2022-09-03T08:17:26.549Z","message":["user =>",{"id":1,"name":"John"}]}
Default logline
1const wrap = data => `[${data}]`; 2 3logline 4 .add(message => wrap(message.date.toISOString())) 5 .add(message => wrap(message.level.toUpperCase())) 6 .add(message => wrap(message.pid)) 7 .add(message => wrap(message.category)) 8 .add(message => wrap(`${message.fileName}||${message.functionName || '-'}:${message.lineNumber || -1}`)) 9 .add(message => message.text); 10
Default json logline
1loglineJson 2 .add(message => ({ date: message.date.toISOString() })) 3 .add(message => ({ level: message.level })) 4 .add(message => ({ pid: message.pid })) 5 .add(message => ({ category: message.category })) 6 .add(message => ({ filename: message.fileName })) 7 .add(message => ({ function: message.functionName || '-' })) 8 .add(message => ({ line: message.lineNumber || -1 })) 9 .add(message => ({ data: message.text }));
License
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
Found 0/5 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/test.yml:1
- Info: no jobLevel write permissions found
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/mekh/logis/test.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/mekh/logis/test.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/mekh/logis/test.yml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/mekh/logis/test.yml/main?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/test.yml:28
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 2 third-party GitHubAction dependencies pinned
- Info: 0 out of 1 npmCommand dependencies pinned
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
license file not detected
Details
- Warn: project does not have a license file
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 29 are checked with a SAST tool
Score
3.4
/10
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to loggis
@loggists/logger
The best solution for logging in React applications.
loggish
Universal logger is a library designed for collect and process logs in apps
@loggists/event-tracker
The best solution for event tracking in React applications.
loggisch
Tiny JS logging library for NodeJS and the browser (ES6/UMD).