bunyan-logger
Advanced tools
Comparing version 0.0.3 to 0.1.0
@@ -1,1 +0,1 @@ | ||
module.exports = require('./lib'); | ||
module.exports = require('./lib'); |
239
lib/index.js
'use strict'; | ||
const bunyan = require('bunyan'); | ||
const Joi = require('joi'); | ||
const streamFactory = require('./stream-factory'); | ||
const LOGGER = Symbol(); | ||
const Bunyan = require('bunyan'); | ||
const Register = require('file-register'); | ||
class BunyanLogger { | ||
//opt: streamType, name, format, filePath, syslogHost, syslogPort, buffer | ||
constructor(opt) { | ||
opt = opt || {}; | ||
this.streams = BunyanLogger.setStreams(opt); | ||
this._level = 'info'; | ||
this._format = opt.format || 'message'; | ||
class Logger extends Bunyan { | ||
this[LOGGER] = bunyan.createLogger({ | ||
name: opt.name || 'APP', | ||
streams: this.streams | ||
}); | ||
this[LOGGER].on('error', (err, stream)=> { | ||
// Handle stream write or create error here. | ||
console.error('create logger error :%s \t stream : %o ', err, stream); | ||
}); | ||
} | ||
constructor(options, _childOptions, _childSimple) { | ||
// Nothing special for child loggers. | ||
if (_childOptions) { | ||
return super(options, _childOptions, _childSimple); | ||
} | ||
//out function do not use template to format log data; | ||
out(payload) { | ||
return this[LOGGER][this.level](payload); | ||
} | ||
// Default options. | ||
options = Object.assign({ | ||
name: 'logger', | ||
serializers: Bunyan.stdSerializers | ||
}, options || {}); | ||
formated(payload) { | ||
let httpSchema = Joi.object().keys({ | ||
type: Joi.string(), | ||
direction: Joi.string(), | ||
actionType: Joi.string(), | ||
target: Joi.string().required(), | ||
targetModule: Joi.string(), | ||
transactionId: Joi.string(), | ||
appId: Joi.string(), | ||
statusCode: Joi.number().allow(null) | ||
}); | ||
let transactionSchema = Joi.object().keys({ | ||
transactionId: Joi.string(), | ||
msg: Joi.string() | ||
}); | ||
let errSchema = Joi.object().keys({ | ||
type: Joi.string(), | ||
targetModule: Joi.string(), | ||
message: Joi.string().required(), | ||
code: Joi.number().allow(null) | ||
}); | ||
let formatedLog = payload; | ||
switch (this.format) { | ||
case 'request': | ||
Joi.validate({ | ||
type: 'HTTP', | ||
direction: 'IN', | ||
actionType: 'REQ', | ||
target: payload.method + ':' + payload.originalUrl, | ||
targetModule: payload.targetModule.toUpperCase(), | ||
transactionId: payload.transactionId, | ||
appId: payload.appId, | ||
statusCode: payload.statusCode | ||
}, httpSchema, (err, value)=> { | ||
if (err) { | ||
throw err; | ||
} | ||
formatedLog = value; | ||
}); | ||
break; | ||
case 'response': | ||
Joi.validate({ | ||
type: 'HTTP', | ||
direction: 'OUT', | ||
actionType: 'RESP', | ||
target: payload.method + ':' + payload.originalUrl, | ||
targetModule: payload.targetModule.toUpperCase(), | ||
transactionId: payload.transactionId, | ||
appId: payload.appId, | ||
statusCode: payload.statusCode | ||
}, httpSchema, (err, value)=> { | ||
if (err) { | ||
throw err; | ||
} | ||
formatedLog = value; | ||
}); | ||
break; | ||
case 'transaction': | ||
Joi.validate({ | ||
transactionId: payload.transactionId, | ||
msg: payload.msg | ||
}, transactionSchema, (err, value)=> { | ||
if (err) { | ||
throw err; | ||
} | ||
formatedLog = value; | ||
}); | ||
break; | ||
case 'error': | ||
Joi.validate({ | ||
type: 'ERROR', | ||
targetModule: payload.targetModule.toUpperCase(), | ||
message: payload.message, | ||
code: payload.code | ||
}, errSchema, (err, value)=> { | ||
if (err) { | ||
throw err; | ||
} | ||
formatedLog = value; | ||
}); | ||
break; | ||
default: | ||
formatedLog = { | ||
type: 'MESSAGE', | ||
message: payload.message | ||
}; | ||
break; | ||
// Always use the streams option. Other ways are just confusing. | ||
if (!options.streams) { | ||
if (options.stream != null) { | ||
// This is a major change to the original Bunyan, where the original would use the stream as | ||
// `stream.stream`. | ||
options.streams = [options.stream]; | ||
delete options.stream; | ||
} else { | ||
// Default to RingBuffer. | ||
options.streams = ['ringbuffer']; | ||
} | ||
} | ||
return formatedLog; | ||
} | ||
trace(payload) { | ||
this.level = 20; | ||
return this[LOGGER].trace(this.formated(payload), payload.msg); | ||
} | ||
// Formatters. | ||
// TODO: needed? | ||
info(payload) { | ||
this.level = 30; | ||
return this[LOGGER].info(this.formated(payload), payload.msg); | ||
super(options, _childOptions, _childSimple); | ||
} | ||
warn(payload) { | ||
this.level = 40; | ||
return this[LOGGER].warn(this.formated(payload), payload.msg); | ||
} | ||
error(payload) { | ||
this.level = 50; | ||
return this[LOGGER].error(this.formated(payload), payload.msg); | ||
} | ||
static setStreams(opt) { | ||
opt = opt || {}; | ||
let streams; | ||
switch (opt.streamType) { | ||
case 'RINGBUFFER': | ||
streams = [streamFactory.ringbuffer(opt)]; | ||
break; | ||
case 'SYSLOG': | ||
streams = [streamFactory.syslog(opt)]; | ||
break; | ||
case 'FILE': | ||
streams = [streamFactory.file(opt)]; | ||
break; | ||
case 'STDOUT': | ||
streams = [streamFactory.stdout()]; | ||
break; | ||
case 'ALL': | ||
streams = [streamFactory.syslog(opt), streamFactory.file(opt), streamFactory.stdout()]; | ||
break; | ||
default: | ||
streams = [streamFactory.stdout()]; | ||
break; | ||
/** | ||
* Extend to support predefined streams. | ||
*/ | ||
addStream(stream, defaultLevel) { | ||
// Can be just a name. | ||
if (typeof stream === 'string') { | ||
return super.addStream(this.predefinedStream(stream), defaultLevel); | ||
} | ||
return streams; | ||
// Can be a name and the options. | ||
if (typeof stream === 'object' && typeof stream.name === 'string') { | ||
return super.addStream(this.predefinedStream(stream.name, stream), defaultLevel); | ||
} | ||
return super.addStream(stream, defaultLevel); | ||
} | ||
//TODO: check log buffer is not outride max size of stream handler; | ||
checkBuffer() { | ||
return true; | ||
} | ||
//Getter, Setter | ||
get format() { | ||
return this._format.toLowerCase(); | ||
} | ||
set format(val) { | ||
if (typeof val === "string") { | ||
this._format = val; | ||
/** | ||
* Get a predefined stream with a name and optional the options. | ||
*/ | ||
predefinedStream(name, options) { | ||
let streams = this.constructor.streams; | ||
if (streams == null) { | ||
throw new Error('no predefined streams'); | ||
} | ||
const stream = streams[name.toLowerCase()]; | ||
if (stream == null) { | ||
throw new Error('log stream not found'); | ||
} | ||
if (typeof stream === 'function') { | ||
return stream(options); | ||
} | ||
return stream; | ||
} | ||
get level() { | ||
return this._level; | ||
} | ||
set level(val) { | ||
if (typeof val === "string") { | ||
this._level = val; | ||
} | ||
} | ||
} | ||
module.exports = BunyanLogger; | ||
/** | ||
* Export all files with the class. | ||
*/ | ||
Object.assign(Logger, Register.proto); | ||
Logger.register(__dirname); | ||
module.exports = Logger; |
{ | ||
"name": "bunyan-logger", | ||
"version": "0.0.3", | ||
"description": "a simple wraped bunyan logger lib", | ||
"version": "0.1.0", | ||
"description": "Extend Bunyan to have default options and predefined streams etc.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha -R spec" | ||
"author": { | ||
"name": "Wiredcraft", | ||
"email": "info@wiredcraft.com", | ||
"url": "http://wiredcraft.com" | ||
}, | ||
"contributors": [ | ||
"Chopper Lee", | ||
"Makara Wang" | ||
], | ||
"keywords": [ | ||
"bunyan", | ||
"logger" | ||
], | ||
"license": "MIT", | ||
"repository": { | ||
@@ -13,25 +24,23 @@ "type": "git", | ||
}, | ||
"author": "Chopper Lee <lihengpro@gmail.com>", | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">= 4.2.1" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Wiredcraft/bunyan-logger/issues" | ||
}, | ||
"homepage": "https://github.com/Wiredcraft/bunyan-logger#readme", | ||
"keywords": [ | ||
"bunyan", | ||
"logger" | ||
], | ||
"homepage": "https://github.com/Wiredcraft/bunyan-logger", | ||
"dependencies": { | ||
"bunyan": "^1.5.1", | ||
"bunyan-syslog": "git+https://github.com/ChopperLee2011/node-bunyan-syslog.git", | ||
"joi": "^9.1.1" | ||
"bunyan": "^1.8.5", | ||
"bunyan-debug-stream": "^1.0.7", | ||
"file-register": "^0.1.0", | ||
"syslog-bunyan-logger": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"coveralls": "^2.11.16", | ||
"intercept-stdout": "^0.1.2", | ||
"mocha": "^2.3.4", | ||
"should": "^8.2.0" | ||
"istanbul": "^0.4.5", | ||
"jscs": "^3.0.7", | ||
"mocha": "^3.2.0", | ||
"should": "^11.2.0" | ||
}, | ||
"scripts": { | ||
"test": "make test" | ||
} | ||
} |
114
README.md
@@ -1,36 +0,106 @@ | ||
# bunyan-logger | ||
# Bunyan Logger | ||
bunyan-logger is a simple wrapper around bunyan logger library. | ||
[![Build Status](https://travis-ci.org/Wiredcraft/bunyan-logger.svg?branch=master)](https://travis-ci.org/Wiredcraft/bunyan-logger) [![Coverage Status](https://coveralls.io/repos/github/Wiredcraft/bunyan-logger/badge.svg?branch=master)](https://coveralls.io/github/Wiredcraft/bunyan-logger?branch=master) | ||
**Note**! Requires Node version 4.0 or later | ||
Extend Bunyan to have default options and predefined streams etc. | ||
## Introduction | ||
## Usage | ||
There are a lot of logger libraries, but if you want to log both request and server information, and you want to easily change logger streams then bunyan-logger can be useful for you. | ||
```sh | ||
npm install bunyan-logger | ||
``` | ||
Fields that are added automatically: "name", "pid", "hostname", "time" and "v". | ||
```js | ||
const Logger = require('bunyan-logger'); | ||
``` | ||
## Features | ||
## Examples | ||
* Log stream config: stdout, syslog, file | ||
* Log level: only allow trace, info, warn, error. | ||
* Log template: message, error, request, response. | ||
## Tests | ||
### Simple | ||
```bash | ||
npm i && npm test | ||
```js | ||
const Logger = require('bunyan-logger'); | ||
const logger = new Logger({ stream: 'debug' }); | ||
logger.error(new Error('Lorem')); | ||
``` | ||
## Install with npm | ||
### With Express | ||
```bash | ||
npm i bunyan-logger --save | ||
See [express-bunyan-logger](https://www.npmjs.com/package/express-bunyan-logger). | ||
```js | ||
const Logger = require('bunyan-logger'); | ||
const expressLogger = require('express-bunyan-logger'); | ||
app.use(expressLogger({ | ||
logger: new Logger({ stream: 'debug' }) | ||
})); | ||
``` | ||
## Example | ||
const BunyanLogger = require('bunyan-logger'); | ||
const data = {message: 'this is a test message'}; | ||
const logger = new BunyanLogger(); | ||
logger.info(data); | ||
## Predefined streams | ||
### Debug | ||
See [bunyan-debug-stream](https://www.npmjs.com/package/bunyan-debug-stream). | ||
```js | ||
// Simple. | ||
const logger = new Logger({ stream: 'debug' }); | ||
// With options. | ||
const logger = new Logger({ | ||
name: 'myLog', | ||
stream: { | ||
name: 'debug', | ||
basepath: path.resolve(__dirname, '../') | ||
}, | ||
serializers: require('bunyan-debug-stream').serializers | ||
}); | ||
``` | ||
### File | ||
```js | ||
// Simple. | ||
const logger = new Logger({ stream: 'file' }); | ||
// With options. | ||
const logger = new Logger({ | ||
name: 'myLog', | ||
stream: { | ||
name: 'file', | ||
path: './some.log' | ||
} | ||
}); | ||
``` | ||
### RingBuffer | ||
```js | ||
const logger = new Logger({ stream: 'ringbuffer' }); | ||
``` | ||
### Stdout | ||
```js | ||
const logger = new Logger({ stream: 'stdout' }); | ||
``` | ||
### Syslog | ||
```js | ||
// Simple. | ||
const logger = new Logger({ stream: 'syslog' }); | ||
// With options. | ||
const logger = new Logger({ | ||
name: 'myLog', | ||
stream: { | ||
name: 'syslog', | ||
host: '10.0.0.1' | ||
} | ||
}); | ||
``` | ||
## Extending/overriding predefined streams | ||
See `/example`. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Git dependency
Supply chain riskContains a dependency which resolves to a remote git URL. Dependencies fetched from git URLs are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
13
107
0
0
8345
4
6
123
2
+ Addedbunyan-debug-stream@^1.0.7
+ Addedfile-register@^0.1.0
+ Addedsyslog-bunyan-logger@^1.0.0
+ Addedassert-plus@0.1.5(transitive)
+ Addedbunyan-debug-stream@1.1.2(transitive)
+ Addedcolors@1.4.0(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addedexception-formatter@1.0.7(transitive)
+ Addedfile-register@0.1.0(transitive)
+ Addedmixable-object@0.1.1(transitive)
+ Addedms@2.0.0(transitive)
+ Addedsyslog-bunyan-logger@1.0.0(transitive)
- Removedbunyan-syslog@git+https://github.com/ChopperLee2011/node-bunyan-syslog.git
- Removedjoi@^9.1.1
- Removedhoek@4.3.1(transitive)
- Removedisemail@2.2.1(transitive)
- Removeditems@2.2.1(transitive)
- Removedjoi@9.2.0(transitive)
- Removedtopo@2.1.1(transitive)
Updatedbunyan@^1.8.5