123 lines
4.7 KiB
JavaScript
123 lines
4.7 KiB
JavaScript
import pino from 'pino'
|
|
import envPaths from 'env-paths'
|
|
import { sync as mkdir } from 'make-dir'
|
|
import { dirname, basename } from 'path'
|
|
import pinoPretty from 'pino-pretty'
|
|
|
|
function child (opts) {
|
|
|
|
const enabled = !!process.env.UCI_ENV
|
|
|
|
let pretty; let filter; let LOG_PATH; let DATE_TIME
|
|
|
|
const PRETTY_DEFAULTS = {translateTime:true, colorize:true, levelFirst:true}
|
|
const DEFAULT_FILTER_PROPS = ['level','time','pid','msg']
|
|
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 (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.indexOf('dev')>-1 || process.env.UCI_LOG_PRETTY) && process.env.UCI_LOG_JSON !=='true' ) { // pretty is on
|
|
// process UCI_LOG_PRETTY
|
|
try {
|
|
pretty = JSON.parse(process.env.UCI_LOG_PRETTY)
|
|
}
|
|
catch (error) {
|
|
// console.log('LOGGER: could not JSON parse',process.env.UCI_LOG_PRETTY )
|
|
}
|
|
if (process.env.UCI_LOG_PRETTY==='verbose') pretty ={include:'all'}
|
|
pretty = pretty || opts.pretty || {}
|
|
pretty = Object.assign({},PRETTY_DEFAULTS,pretty)
|
|
pretty.search = process.env.UCI_LOG_SEARCH
|
|
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()
|
|
|
|
|
|
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
|
|
pretty.filter = [...DEFAULT_FILTER_PROPS,...(process.env.UCI_LOG_PRETTY === 'where' ? WHERE_FILTER_PROPS : []),...(pretty.filter||[])]
|
|
pretty.ignore = null
|
|
}
|
|
}
|
|
|
|
|
|
DATE_TIME = new Date().toString()
|
|
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
|
|
if (LOG_PATH) {
|
|
try { mkdir(dirname(LOG_PATH)) } // makes recursively for any missing parent directories
|
|
catch(err) { throw err }
|
|
}
|
|
} // end enabled
|
|
|
|
// console.dir(pretty)
|
|
// console.dir(logOpts)
|
|
|
|
const logger = pino({
|
|
name: opts.libraryName || process.env.UCI_LOG_NAME || 'UCI',
|
|
enabled: enabled,
|
|
safe: true,
|
|
serializers: {
|
|
req: pino.stdSerializers.req,
|
|
res: pino.stdSerializers.res
|
|
},
|
|
prettyPrint: pretty,
|
|
prettifier: filter // only call prefilter if some filter is supplied, otherwise see line 53
|
|
},
|
|
// if production not enabled then LOG_PATH is empty and logs go to stdout/stderr and can be piped from there
|
|
LOG_PATH
|
|
)
|
|
|
|
let child = logger.child(logOpts)
|
|
|
|
child.default = process.env.UCI_LOG_LEVEL || opts.level || 'info'
|
|
child.clear = () => {
|
|
if (enabled) {
|
|
if (process.env.UCI_ENV.indexOf('pro') > -1) return null } // enable feature here
|
|
}
|
|
child.div = value => {
|
|
if (enabled) {
|
|
if (process.env.UCI_ENV.indexOf('dev') > -1) console.log(`===== ${value} ========`)}
|
|
}
|
|
child.lvlset = (level) => { if (enabled) child.level = level || child.default }
|
|
|
|
return child
|
|
}
|
|
|
|
export default child
|
|
const levels = pino.levels
|
|
export {child as logger, levels}
|
|
|
|
function capitalize (s) { return s.charAt(0).toUpperCase() + s.slice(1)}
|
|
|
|
function filterPretty (options) {
|
|
// console.log('filter options',options)
|
|
return function prettifier (inputData) {
|
|
// console.log('calling filter',inputData)
|
|
let log
|
|
let parsedData
|
|
if (typeof inputData === 'string') {
|
|
try { log = JSON.Parse(inputData)}
|
|
catch(err){ return inputData }
|
|
}
|
|
else log = inputData
|
|
let filteredLog = {}
|
|
options.filter.forEach(prop => filteredLog[prop]= log[prop])
|
|
// console.log('filtered',options.filter, filteredLog)
|
|
return pinoPretty(options)(filteredLog)
|
|
}
|
|
}
|