fix: warning about passed level property
refactor!: passed arguments separated into bindings and options feat: bound properties under meta: key in log feat: pino key of options argument for pino settings feat: in dev/pretty can (un)hide properties feat: add a unique id to each log line (can be loaded by nedb and such) feat: locate method to easily add line number and file to a log line BREAKING CHANGE: logger/pino options in second separate argument from bindingsmaster
parent
e776937738
commit
2bb6b65e63
33
.eslintrc.js
33
.eslintrc.js
|
@ -1,33 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"modules": true,
|
|
||||||
"spread" : true,
|
|
||||||
"restParams" : true
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"es6": true,
|
|
||||||
"node": true,
|
|
||||||
"mocha": true
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2017,
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"rules": {
|
|
||||||
"indent": [
|
|
||||||
"error",
|
|
||||||
2
|
|
||||||
],
|
|
||||||
"no-console": 0,
|
|
||||||
"semi": ["error", "never"],
|
|
||||||
"linebreak-style": [
|
|
||||||
"error",
|
|
||||||
"unix"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
"error",
|
|
||||||
"single"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
env:
|
||||||
|
node: true
|
||||||
|
es2021: true
|
||||||
|
mocha: true
|
||||||
|
extends:
|
||||||
|
- standard
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: 12
|
||||||
|
sourceType: module
|
||||||
|
rules:
|
||||||
|
indent: ["error", 2]
|
||||||
|
no-console: 0
|
||||||
|
semi: ["error", "never"]
|
||||||
|
# linebreak-style: ["error", "unix"]
|
||||||
|
quotes: ["error", "single"]
|
|
@ -1,3 +1,4 @@
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/coverage/
|
/coverage/
|
||||||
*.yaml
|
*.yaml
|
||||||
|
/example/example.log
|
||||||
|
|
12
.travis.yml
12
.travis.yml
|
@ -1,12 +0,0 @@
|
||||||
language: node_js
|
|
||||||
|
|
||||||
node_js:
|
|
||||||
- '7.10'
|
|
||||||
- 'node'
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
script: npm test
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
|
|
|
@ -1,47 +1,69 @@
|
||||||
import logger from '../src/logger.js'
|
import logger from '../src/logger.js'
|
||||||
|
import testsrc from './test.js'
|
||||||
|
|
||||||
let log = {}
|
let log = {}
|
||||||
|
|
||||||
class LogTest {
|
const options = {
|
||||||
constructor(opts) {
|
// custom UCI logger options
|
||||||
log = logger(
|
// noID: true,
|
||||||
Object.assign({
|
// IDKey: '_id' // default
|
||||||
|
hide: ['meta', 'machine'], // array of properties to hide
|
||||||
// pretty: {translateTime:true, colorize:true, levelFirst:true } // options for pino pretty printer
|
// pretty: {translateTime:true, colorize:true, levelFirst:true } // options for pino pretty printer
|
||||||
// env:'', // 'dev' or 'pro' -- can be use to set/override UCI_ENV environment variable
|
// env:'', // 'dev' or 'pro' -- can be use to set/override UCI_ENV environment variable
|
||||||
// enForce: false, // only used with .evn. if true will override UCI_ENV if it is set, otherwise no
|
// enForce: false, // only used with .evn. if true will override UCI_ENV if it is set, otherwise no
|
||||||
// level:'debug', // info is default level, set level to lowest visible
|
|
||||||
// clear: false, // true for log files will clear the current log file on restart
|
// clear: false, // true for log files will clear the current log file on restart
|
||||||
// logFileName:'test', // if not supplied log filename will be generated from timestamp
|
// logFileName:'test', // if not supplied log filename will be generated from timestamp
|
||||||
// below are BASE properties which are optional and are passed to child logger instance and will be part of json log entry
|
//
|
||||||
// libraryName: 'UCI', // will be logged as name: can be used to identify logs of related packages, can be set via UCI_LOG_NAME env variable
|
// override logger default and or add any pino options
|
||||||
appName:'uci-example-logger', //will be used for logging directory name if supplied and will be logged as well
|
pino: {
|
||||||
package: '@uci/test', // name of package with scope per package.json
|
// level:'info', // info is default level, overrides UCI_LOG_LEVEL, can be changed at runtime with .level method
|
||||||
// repo: // will use scope-name from package prop if not supplied
|
// name: either libraryName above or UCI_LOG_NAME or default 'UCI',
|
||||||
id: 'id set in package', // can pass a unique if for easy later search/filtering
|
// enabled: only if UCI_ENV is set
|
||||||
file: 'example/example.js', // path (to repo root) of actual file running this logger, default is ./src/<package without scope>.js
|
// nestedKey: 'props' // nest the runtime custom log properties
|
||||||
class: 'LogTest', // The class that created this logger if any
|
// safe: true,
|
||||||
|
// timestamp: pino.stdTimeFunctions.epochTime,
|
||||||
/*----------------
|
// serializers: {
|
||||||
Can pass through additional props for every log by including this `additional` property object
|
// req: pino.stdSerializers.req,
|
||||||
should not use any keys above or level,time,msg,pid,hostname,
|
// res: pino.stdSerializers.res
|
||||||
logPath,instanceCreatedHR,instanceCreated as keys in this object will be merged
|
// },
|
||||||
------------------*/
|
// prettyPrint: pretty,
|
||||||
// additional: {anotherprop:'test'}
|
// prettifier: filter // only call prefilter if some filter is supplied, otherwise see line 53
|
||||||
},opts)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
// meta properties added to all log output
|
||||||
|
// the following base meta props and will be generated with defaults if not set
|
||||||
|
appName: 'uci-example-logger', // will be used for logging directory name if supplied and will be logged as well
|
||||||
|
package: '@uci/test' // name of package with scope per package.json
|
||||||
|
// library: 'uci', // will be stripped from @ organization of package if not supplied
|
||||||
|
// repo: // will use scope-name from package prop if not supplied
|
||||||
|
// file: 'example/example.js', // path (to repo root) of actual file running this logger, default is ./src/<package without scope>.js
|
||||||
|
// file: import.meta.url // use this to get a dynmic absolute path to the file where logger is created
|
||||||
|
// class: 'LogTest' // otherwise will be generated from package
|
||||||
|
// class: false // set to false to disable meta class property
|
||||||
|
// add any additional properties to meta data here
|
||||||
|
// an example
|
||||||
|
// id: // maybe a unique id to make is easier to search and/or filter these logs
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogTest {
|
||||||
|
constructor () {
|
||||||
|
log = logger(meta, options)
|
||||||
|
} // end constructor
|
||||||
|
|
||||||
logit () {
|
logit () {
|
||||||
log.trace('this is a trace level logged message')
|
log.trace('this is a trace level logged message')
|
||||||
log.debug({line:343,msg:'this is a debug level logged message with a line number'})
|
log.debug({ line: log.locate(), msg: 'this is a debug level logged message with a line number' })
|
||||||
log.info({runtimeprop:'some propetery in context', msg:'this is a info level logged message'})
|
log.info({ runtimeprop: 'some propertey in context', msg: 'this is a info level logged message' })
|
||||||
log.warn('this is a warn level logged message')
|
log.warn('this is a warn level logged message')
|
||||||
log.error('this is a error level logged message')
|
log.error('this is a error level logged message')
|
||||||
log.fatal('this is a fatal level logged message')
|
// log.fatal('this is a fatal level logged message')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let test = new LogTest({id:'id-via new instance', pretty:{include:'all'}})
|
// let test = new LogTest({id:'id-via new instance', pretty:{include:'all'}})
|
||||||
let test = new LogTest()
|
const test = new LogTest()
|
||||||
|
|
||||||
log.div(`the default log level based on option or UCI_LOG_LEVEL ${log.level}`)
|
log.div(`the default log level based on option or UCI_LOG_LEVEL ${log.level}`)
|
||||||
test.logit()
|
test.logit()
|
||||||
|
@ -54,4 +76,22 @@ test.logit()
|
||||||
log.lvlset()
|
log.lvlset()
|
||||||
log.div(`reset level back current default ${log.level}`)
|
log.div(`reset level back current default ${log.level}`)
|
||||||
test.logit()
|
test.logit()
|
||||||
log.clear('This call to log.clear could clear the file log when implemented')
|
|
||||||
|
console.log('\n-------- hide props------------')
|
||||||
|
log.info({ test1: 'test1', test2: 'test2' }, 'testing')
|
||||||
|
log.hide('test1')
|
||||||
|
console.log('hiding test1')
|
||||||
|
log.info({ test1: 'test1', test2: 'test2' }, 'hiding test1')
|
||||||
|
log.hide('test2')
|
||||||
|
console.log('hiding test2')
|
||||||
|
log.info({ test1: 'test1', test2: 'test2' }, 'hiding test2')
|
||||||
|
log.unhide(['test1', 'test2'])
|
||||||
|
console.log('unhiding both')
|
||||||
|
log.info({ test1: 'test1', test2: 'test2' }, 'hiding test2')
|
||||||
|
|
||||||
|
console.log('\n-------- include line and file ------------')
|
||||||
|
log.info({ loc: log.locate() }, 'log line:file')
|
||||||
|
log.info({ line: log.locate('n') }, 'log line')
|
||||||
|
log.info({ file: log.locate('f') }, 'log file')
|
||||||
|
log.info({ file: log.locate(1) }, 'log loc alternate stack')
|
||||||
|
testsrc(log)
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
{"level":30,"time":1549418336924,"pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"runtimeprop":"somevalue","msg":"this is a info level logged message","v":1}
|
|
||||||
{"level":40,"time":1549418336924,"msg":"this is a warn level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":50,"time":1549418336924,"msg":"this is a error level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":60,"time":1549418336924,"msg":"this is a fatal level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":60,"time":1549418336924,"msg":"this is a fatal level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":30,"time":1549418336924,"pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"runtimeprop":"somevalue","msg":"this is a info level logged message","v":1}
|
|
||||||
{"level":40,"time":1549418336924,"msg":"this is a warn level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":50,"time":1549418336924,"msg":"this is a error level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":60,"time":1549418336924,"msg":"this is a fatal level logged message","pid":12697,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-58-56-919Z","instanceCreated":1549418336923,"v":1}
|
|
||||||
{"level":30,"time":1549418345373,"pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"runtimeprop":"somevalue","msg":"this is a info level logged message","v":1}
|
|
||||||
{"level":40,"time":1549418345373,"msg":"this is a warn level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":50,"time":1549418345373,"msg":"this is a error level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":60,"time":1549418345373,"msg":"this is a fatal level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":60,"time":1549418345373,"msg":"this is a fatal level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":30,"time":1549418345373,"pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"runtimeprop":"somevalue","msg":"this is a info level logged message","v":1}
|
|
||||||
{"level":40,"time":1549418345373,"msg":"this is a warn level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":50,"time":1549418345373,"msg":"this is a error level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
||||||
{"level":60,"time":1549418345373,"msg":"this is a fatal level logged message","pid":12734,"hostname":"giskard","name":"UCI","logPath":"./example/example.log","appName":"uci-example-logger","repo":"uci-test","package":"@uci/test","file":"src/test.js","class":"Tuci/test","id":"logtest-via-new","instanceCreatedHR":"2019-02-06T01-59-05-370Z","instanceCreated":1549418345372,"v":1}
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default function test (log) {
|
||||||
|
log.info({ location: log.locate() }, 'testing line from another file')
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "@uci-utils/logger",
|
"name": "@uci-utils/logger",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"description": "Parent Logger for all UCI modules",
|
"description": "Parent Logger for all UCI modules",
|
||||||
"main": "./src/logger.js",
|
"main": "./src/logger.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"testd": "./node_modules/.bin/nodemon --exec './node_modules/.bin/mocha --timeout 30000' || exit 1",
|
"test:dev": "./node_modules/.bin/nodemon --trace-warnings --exec './node_modules/.bin/mocha --timeout 30000' || exit 1",
|
||||||
"test": "./node_modules/.bin/mocha --timeout 30000 || exit 0",
|
"test": "./node_modules/.bin/mocha --timeout 30000 || exit 0",
|
||||||
"dev": "UCI_ENV=dev ./node_modules/.bin/nodemon example/example",
|
"dev": "UCI_ENV=dev ./node_modules/.bin/nodemon example/example",
|
||||||
"dev:verbose": "UCI_LOG_PRETTY='verbose' npm run dev",
|
"dev:verbose": "UCI_LOG_PRETTY='verbose' npm run dev",
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
"dev:info:only": "UCI_LOG_SEARCH='level==`30`' npm run dev",
|
"dev:info:only": "UCI_LOG_SEARCH='level==`30`' npm run dev",
|
||||||
"dev:fatal:only": "UCI_LOG_SEARCH='level==`60`' npm run dev",
|
"dev:fatal:only": "UCI_LOG_SEARCH='level==`60`' npm run dev",
|
||||||
"dev:json": "UCI_LOG_LEVEL=trace UCI_LOG_JSON=true npm run dev",
|
"dev:json": "UCI_LOG_LEVEL=trace UCI_LOG_JSON=true npm run dev",
|
||||||
"pro": "UCI_ENV='pro' node example/example",
|
"pro": "UCI_ENV='pro' nodemon example/example",
|
||||||
"pro:path": "UCI_LOG_PATH=./example/example.log npm run pro"
|
"pro:path": "UCI_LOG_PATH=./example/example.log npm run pro"
|
||||||
},
|
},
|
||||||
"author": "David Kebler",
|
"author": "David Kebler",
|
||||||
|
@ -39,13 +39,19 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"env-paths": "^2.2.1",
|
"env-paths": "^2.2.1",
|
||||||
"make-dir": "^3.1.0",
|
"make-dir": "^3.1.0",
|
||||||
"pino": "^6.11.3",
|
"pino": "^6.13.0",
|
||||||
"pino-pretty": "^4.7.1"
|
"pino-pretty": "^5.1.2",
|
||||||
|
"uniqid": "^5.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^4.3.4",
|
"chai": "^4.3.4",
|
||||||
"mocha": "^8.3.2",
|
"eslint": "^7.31.0",
|
||||||
"nodemon": "^2.0.7",
|
"eslint-config-standard": "^16.0.3",
|
||||||
"test-console": "^1.1.0"
|
"eslint-plugin-import": "^2.23.4",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^5.1.0",
|
||||||
|
"mocha": "^9.0.3",
|
||||||
|
"nodemon": "^2.0.12",
|
||||||
|
"test-console": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
154
src/logger.js
154
src/logger.js
|
@ -3,30 +3,26 @@ import envPaths from 'env-paths'
|
||||||
import { sync as mkdir } from 'make-dir'
|
import { sync as mkdir } from 'make-dir'
|
||||||
import { dirname, basename } from 'path'
|
import { dirname, basename } from 'path'
|
||||||
import pinoPretty from 'pino-pretty'
|
import pinoPretty from 'pino-pretty'
|
||||||
|
import uniqid from 'uniqid'
|
||||||
|
|
||||||
function child (opts) {
|
// TODO add custom levels
|
||||||
|
// is pro log to file working???
|
||||||
|
|
||||||
|
function child (bindings = {}, options = {}) {
|
||||||
|
const pinoOpts = Object.assign({}, options.pino)
|
||||||
|
const opts = Object.assign({}, options)
|
||||||
|
delete opts.pino
|
||||||
|
|
||||||
const enabled = !!process.env.UCI_ENV
|
const enabled = !!process.env.UCI_ENV
|
||||||
|
|
||||||
let pretty; let filter; let LOG_PATH; let DATE_TIME
|
let pretty; let filter; let LOG_PATH; let DATE_TIME; let destination; let file
|
||||||
|
|
||||||
|
let hidden = Array.isArray(opts.hide) ? opts.hide : [opts.hide]
|
||||||
|
|
||||||
const PRETTY_DEFAULTS = { translateTime: true, colorize: true, levelFirst: true }
|
const PRETTY_DEFAULTS = { translateTime: true, colorize: true, levelFirst: true }
|
||||||
const DEFAULT_FILTER_PROPS = ['level', 'time', 'pid', 'msg']
|
const DEFAULT_FILTER_PROPS = ['level', 'time', 'pid', 'msg']
|
||||||
const WHERE_FILTER_PROPS = ['package', 'file', 'class', 'method', 'function', 'line']
|
const WHERE_FILTER_PROPS = ['package', 'file', 'class', 'method', 'function', 'line']
|
||||||
|
|
||||||
let logOpts = {
|
|
||||||
level:opts.level || process.env.UCI_LOG_LEVEL,
|
|
||||||
logPath: LOG_PATH, // if logging to file
|
|
||||||
appName: process.env.UCI_LOG_APP || opts.appName || opts.name,
|
|
||||||
package: opts.package,
|
|
||||||
repo: opts.repo || ((typeof opts.package==='string') ? opts.package.replace( /[@]+/g, '' ).replace( /[/]+/g, '-' ) : undefined),
|
|
||||||
file: opts.file || ((typeof opts.package==='string') ? `src/${basename(opts.package)}.js` : undefined),
|
|
||||||
class: opts.class || ( (typeof opts.package==='string') ? capitalize(basename(opts.package)) : undefined),
|
|
||||||
id: opts.id || opts.name || 'none',
|
|
||||||
instanceCreatedHR:DATE_TIME,
|
|
||||||
instanceCreated:Date.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (opts.env) (opts.envForce) ? (process.env.UCI_ENV = opts.env) : (process.env.UCI_ENV = process.env.UCI_ENV || opts.env)
|
if (opts.env) (opts.envForce) ? (process.env.UCI_ENV = opts.env) : (process.env.UCI_ENV = process.env.UCI_ENV || opts.env)
|
||||||
if (process.env.UCI_ENV === 'node') process.env.UCI_ENV = process.env.NODE_ENV
|
if (process.env.UCI_ENV === 'node') process.env.UCI_ENV = process.env.NODE_ENV
|
||||||
|
@ -34,8 +30,7 @@ function child (opts) {
|
||||||
// process UCI_LOG_PRETTY
|
// process UCI_LOG_PRETTY
|
||||||
try {
|
try {
|
||||||
pretty = JSON.parse(process.env.UCI_LOG_PRETTY)
|
pretty = JSON.parse(process.env.UCI_LOG_PRETTY)
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
// console.log('LOGGER: could not JSON parse',process.env.UCI_LOG_PRETTY )
|
// console.log('LOGGER: could not JSON parse',process.env.UCI_LOG_PRETTY )
|
||||||
}
|
}
|
||||||
if (process.env.UCI_LOG_PRETTY === 'verbose') pretty = { include: 'all' }
|
if (process.env.UCI_LOG_PRETTY === 'verbose') pretty = { include: 'all' }
|
||||||
|
@ -43,9 +38,7 @@ function child (opts) {
|
||||||
pretty = Object.assign({}, PRETTY_DEFAULTS, pretty)
|
pretty = Object.assign({}, PRETTY_DEFAULTS, pretty)
|
||||||
pretty.search = process.env.UCI_LOG_SEARCH
|
pretty.search = process.env.UCI_LOG_SEARCH
|
||||||
pretty.include = pretty.include === 'all' ? 'all' : `level${pretty.include ? ',' + pretty.include : ''}`
|
pretty.include = pretty.include === 'all' ? 'all' : `level${pretty.include ? ',' + pretty.include : ''}`
|
||||||
pretty.ignore = pretty.include === 'all' ? null : Object.keys(logOpts).filter(key => pretty.include.indexOf(key) === -1 ).join()
|
pretty.ignore = pretty.include === 'all' ? null : Object.keys(opts).filter(key => pretty.include.indexOf(key) === -1).join()
|
||||||
|
|
||||||
|
|
||||||
if (process.env.UCI_LOG_PRETTY === 'terse' || process.env.UCI_LOG_PRETTY === 'where' || pretty.filter) {
|
if (process.env.UCI_LOG_PRETTY === 'terse' || process.env.UCI_LOG_PRETTY === 'where' || pretty.filter) {
|
||||||
filter = filterPretty // only call prefilter if some filter is supplied, otherwise
|
filter = filterPretty // only call prefilter if some filter is supplied, otherwise
|
||||||
pretty.filter = [...DEFAULT_FILTER_PROPS, ...(process.env.UCI_LOG_PRETTY === 'where' ? WHERE_FILTER_PROPS : []), ...(pretty.filter || [])]
|
pretty.filter = [...DEFAULT_FILTER_PROPS, ...(process.env.UCI_LOG_PRETTY === 'where' ? WHERE_FILTER_PROPS : []), ...(pretty.filter || [])]
|
||||||
|
@ -53,70 +46,147 @@ function child (opts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DATE_TIME = new Date().toString()
|
DATE_TIME = new Date().toString()
|
||||||
LOG_PATH = (process.env.UCI_ENV.indexOf('pro') > -1 || process.env.UCI_ENV === 'logfile')
|
LOG_PATH = (process.env.UCI_ENV.indexOf('pro') > -1 || process.env.UCI_ENV === 'logfile')
|
||||||
? ( process.env.UCI_LOG_PATH || `${envPaths(opts.appName || opts.name || 'default').log}/${opts.logFileName || DATE_TIME}.log`) : undefined
|
? (process.env.UCI_LOG_PATH || `${envPaths(opts.appName || opts.name || 'default').log}/${opts.logFileName || DATE_TIME}.log`)
|
||||||
|
: undefined
|
||||||
if (LOG_PATH) {
|
if (LOG_PATH) {
|
||||||
try { mkdir(dirname(LOG_PATH)) } // makes recursively for any missing parent directories
|
mkdir(dirname(LOG_PATH)) // makes recursively for any missing parent directories
|
||||||
catch(err) { throw err }
|
destination = LOG_PATH
|
||||||
}
|
}
|
||||||
} // end enabled
|
} // end enabled
|
||||||
|
|
||||||
|
// default bindings
|
||||||
|
bindings.appName = process.env.UCI_LOG_APP || bindings.appName || bindings.name
|
||||||
|
bindings.library = bindings.library || typeof bindings.package === 'string' ? (bindings.package.includes('@') ? (bindings.package.replace(/[@]+/g, '')).split('/')[0] : undefined) : undefined
|
||||||
|
bindings.repo = bindings.repo || ((typeof bindings.package === 'string') ? bindings.package.replace(/[@]+/g, '').replace(/[/]+/g, '-') : undefined)
|
||||||
|
bindings.file = bindings.file || ((typeof bindings.package === 'string') ? `src/${basename(bindings.package)}.js` : undefined)
|
||||||
|
bindings.class = bindings.class || (bindings.class !== false && typeof bindings.package === 'string') ? capitalize(basename(bindings.package)) : undefined
|
||||||
|
bindings.instanceCreatedHR = DATE_TIME
|
||||||
|
bindings.instanceCreated = Date.now()
|
||||||
|
|
||||||
// console.dir(pretty)
|
// console.dir(pretty)
|
||||||
// console.dir(logOpts)
|
// console.dir(logOpts)
|
||||||
|
|
||||||
const logger = pino({
|
if (pinoOpts.destination) {
|
||||||
name: opts.libraryName || process.env.UCI_LOG_NAME || 'UCI',
|
destination = pinoOpts.destination
|
||||||
|
delete pinoOpts.destination
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultLevel = pinoOpts.level || opts.level || process.env.UCI_LOG_LEVEL || 'info'
|
||||||
|
|
||||||
|
const defaultOpts = {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
safe: true,
|
safe: true,
|
||||||
|
level: defaultLevel,
|
||||||
|
formatters: {
|
||||||
|
bindings (obj) {
|
||||||
|
return { machine: obj }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timestamp: pino.stdTimeFunctions.epochTime,
|
||||||
serializers: {
|
serializers: {
|
||||||
req: pino.stdSerializers.req,
|
req: pino.stdSerializers.req,
|
||||||
res: pino.stdSerializers.res
|
res: pino.stdSerializers.res
|
||||||
},
|
},
|
||||||
prettyPrint: pretty,
|
prettyPrint: pretty,
|
||||||
prettifier: filter // only call prefilter if some filter is supplied, otherwise see line 53
|
prettifier: filter // only call prefilter if some filter is supplied, otherwise see line 53
|
||||||
},
|
}
|
||||||
|
|
||||||
|
const logger = pino(
|
||||||
|
Object.assign({}, defaultOpts, pinoOpts),
|
||||||
// if production not enabled then LOG_PATH is empty and logs go to stdout/stderr and can be piped from there
|
// if production not enabled then LOG_PATH is empty and logs go to stdout/stderr and can be piped from there
|
||||||
LOG_PATH
|
destination
|
||||||
)
|
)
|
||||||
|
|
||||||
let child = logger.child(logOpts)
|
const child = logger.child({ meta: bindings }, {
|
||||||
|
formatters: {
|
||||||
|
log (obj) {
|
||||||
|
// console.log('formatter', obj.level, child.level)
|
||||||
|
obj.dateTime = new Date().toString()
|
||||||
|
if (!pretty) {
|
||||||
|
obj.label = child.level
|
||||||
|
if (!opts.noID) obj[opts.keyID || '_id'] = uniqid()
|
||||||
|
} else {
|
||||||
|
obj.file = obj.file || file
|
||||||
|
hidden.forEach(prop => {
|
||||||
|
// console.log('hiding', prop, obj[prop])
|
||||||
|
obj[prop] = undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
child.default = process.env.UCI_LOG_LEVEL || opts.level || 'info'
|
child.default = defaultLevel
|
||||||
child.clear = () => {
|
child.clear = () => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (process.env.UCI_ENV.indexOf('pro') > -1) return null } // enable feature here
|
if (process.env.UCI_ENV.indexOf('pro') > -1) return null
|
||||||
|
} // enable feature here
|
||||||
}
|
}
|
||||||
child.div = value => {
|
child.div = value => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (process.env.UCI_ENV.indexOf('dev') > -1) console.log(`===== ${value} ========`)}
|
if (process.env.UCI_ENV.indexOf('dev') > -1) console.log(`===== ${value} ========`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
child.lvlset = (level) => { if (enabled) child.level = level || child.default }
|
child.lvlset = (level) => { if (enabled) child.level = level || child.default }
|
||||||
|
|
||||||
|
child.hide = (props) => {
|
||||||
|
hidden = arraysMerge(props, hidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
child.unhide = (props) => {
|
||||||
|
hidden = arraysFilter(props, hidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
child.locate = locate
|
||||||
|
|
||||||
return child
|
return child
|
||||||
}
|
}
|
||||||
|
|
||||||
export default child
|
export default child
|
||||||
const levels = pino.levels
|
const levels = pino.levels
|
||||||
export {child as logger, levels}
|
export { child as logger, levels, locate, arraysMerge }
|
||||||
|
|
||||||
function capitalize (s) { return s.charAt(0).toUpperCase() + s.slice(1)}
|
|
||||||
|
|
||||||
function filterPretty (options) {
|
function filterPretty (options) {
|
||||||
// console.log('filter options',options)
|
// console.log('filter options',options)
|
||||||
return function prettifier (inputData) {
|
return function prettifier (inputData) {
|
||||||
// console.log('calling filter',inputData)
|
// console.log('calling filter',inputData)
|
||||||
let log
|
let log
|
||||||
let parsedData
|
// let parsedData
|
||||||
if (typeof inputData === 'string') {
|
if (typeof inputData === 'string') {
|
||||||
try { log = JSON.Parse(inputData)}
|
try { log = JSON.Parse(inputData) } catch (err) { return inputData }
|
||||||
catch(err){ return inputData }
|
} else log = inputData
|
||||||
}
|
const filteredLog = {}
|
||||||
else log = inputData
|
options.filter.forEach(prop => { filteredLog[prop] = log[prop] })
|
||||||
let filteredLog = {}
|
|
||||||
options.filter.forEach(prop => filteredLog[prop]= log[prop])
|
|
||||||
// console.log('filtered',options.filter, filteredLog)
|
// console.log('filtered',options.filter, filteredLog)
|
||||||
return pinoPretty(options)(filteredLog)
|
return pinoPretty(options)(filteredLog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move these to @uci-utils/helpers
|
||||||
|
|
||||||
|
function capitalize (s) { return s.charAt(0).toUpperCase() + s.slice(1) }
|
||||||
|
|
||||||
|
function locate (frame = 2, ret) {
|
||||||
|
if (typeof frame === 'string') { ret = frame; frame = 2 }
|
||||||
|
const e = new Error()
|
||||||
|
const stack = e.stack.toString().split(/\r\n|\n/)
|
||||||
|
const RE = /file:\/\/(.*):(\d+):(?:\d+)[^\d]*$/
|
||||||
|
const reg = RE.exec(stack[frame])
|
||||||
|
const str = ret ? (ret === 'n' ? reg[2] : reg[1]) : `${reg[2]}:${reg[1]}`
|
||||||
|
return str // return line#:path
|
||||||
|
}
|
||||||
|
|
||||||
|
function arraysMerge (els, arr) {
|
||||||
|
els = Array.isArray(els) ? els : [els]
|
||||||
|
return [...new Set([...arr, ...els])].filter(el => el != null)
|
||||||
|
}
|
||||||
|
|
||||||
|
function arraysFilter (els, arr) {
|
||||||
|
els = Array.isArray(els) ? els : [els]
|
||||||
|
return arr.filter(function (item) {
|
||||||
|
return !els.includes(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue