Comparing version 0.2.0 to 1.0.0
@@ -17,3 +17,8 @@ 'use strict' | ||
handler: function (request, reply) { | ||
// request.log is HAPI standard way of logging | ||
request.log(['a', 'b'], 'Request into hello world') | ||
// you can also use a pino instance, which will be faster | ||
request.logger.info('In handler %s', request.path) | ||
return reply('hello world') | ||
@@ -23,8 +28,3 @@ } | ||
server.register({ | ||
register: require('.').register, | ||
options: { | ||
extreme: false | ||
} | ||
}, (err) => { | ||
server.register(require('.'), (err) => { | ||
if (err) { | ||
@@ -35,5 +35,11 @@ console.error(err) | ||
// the logger is available in server.app | ||
server.app.logger.warn('Pino is registered') | ||
// also as a decorated API | ||
server.logger().info('another way for accessing it') | ||
// and through Hapi standard logging system | ||
server.log(['subsystem'], 'third way for accessing it') | ||
// Start the server | ||
@@ -40,0 +46,0 @@ server.start((err) => { |
33
index.js
@@ -5,2 +5,4 @@ 'use strict' | ||
const levels = ['trace', 'debug', 'info', 'warn', 'error'] | ||
function register (server, options, next) { | ||
@@ -13,2 +15,10 @@ options.stream = options.stream || process.stdout | ||
const tagToLevels = options.tags || {} | ||
const allTags = options.allTags || 'info' | ||
const validTags = Object.keys(tagToLevels).filter((key) => levels.indexOf(tagToLevels[key]) < 0).length === 0 | ||
if (!validTags || allTags && levels.indexOf(allTags) < 0) { | ||
return next(new Error('invalid tag levels')) | ||
} | ||
const logger = pino(options, options.stream) | ||
@@ -28,2 +38,10 @@ | ||
server.on('log', (event) => { | ||
logEvent(logger, event) | ||
}) | ||
server.on('request', (request, event) => { | ||
logEvent(request.logger, event) | ||
}) | ||
// log when a request completes with an error | ||
@@ -55,2 +73,17 @@ server.on('request-error', (request, err) => { | ||
next() | ||
function logEvent (current, event) { | ||
const tags = event.tags | ||
const data = event.data | ||
for (var i = 0; i < tags.length; i++) { | ||
let level = tagToLevels[tags[i]] | ||
if (level) { | ||
current[level]({ tags, data }) | ||
return | ||
} | ||
} | ||
if (allTags) { | ||
current[allTags]({ tags, data }) | ||
} | ||
} | ||
} | ||
@@ -57,0 +90,0 @@ |
{ | ||
"name": "hapi-pino", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "Hapi plugin for the Pino logger ", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -36,3 +36,8 @@ # hapi-pino | ||
handler: function (request, reply) { | ||
// request.log is HAPI standard way of logging | ||
request.log(['a', 'b'], 'Request into hello world') | ||
// you can also use a pino instance, which will be faster | ||
request.logger.info('In handler %s', request.path) | ||
return reply('hello world') | ||
@@ -42,8 +47,3 @@ } | ||
server.register({ | ||
register: require('.').register, | ||
options: { | ||
extreme: false | ||
} | ||
}, (err) => { | ||
server.register(require('hapi-pino'), (err) => { | ||
if (err) { | ||
@@ -54,5 +54,11 @@ console.error(err) | ||
// the logger is available in server.app | ||
server.app.logger.warn('Pino is registered') | ||
// also as a decorated API | ||
server.logger().info('another way for accessing it') | ||
// and through Hapi standard logging system | ||
server.log(['subsystem'], 'third way for accessing it') | ||
// Start the server | ||
@@ -68,2 +74,52 @@ server.start((err) => { | ||
## API | ||
- [Options](#options) | ||
- [Server decorations](#serverdecorations) | ||
- [Request decorations](#requestdecorations) | ||
- [Hapi Events](#hapievents) | ||
**hapi-pino** goal is to enable Hapi applications to log via [pino][pino]. To enable this, it decorates both the [server](#serverdecorations) and the [request](#requestadditions). Moreover, **hapi-pino** | ||
binds to the Hapi events system as described in the ["Hapi | ||
events"](#hapievents) section. | ||
### Options | ||
- `[stream]` - the binary stream to write stuff to, defaults to | ||
`process.stdout`. | ||
- `[tags]` - a map to specify pairs of Hapi log tags and levels. | ||
- `[allTags]` - the logging level to apply to all tags not matched by | ||
`tags`, defaults to `'info'`. | ||
<a name="serverdecorations"></a> | ||
### Server Decorations | ||
**hapi-pino** decorates the Hapi server with: | ||
* `server.logger()`, which is a function that returns the current instance of | ||
[pino][pino], see its doc for the way to actual log. | ||
* `server.app.logger`, same as before, but the logger it is also | ||
attached to the `server.app` object. | ||
<a name="requestdecorations"></a> | ||
### Request Decorations | ||
**hapi-pino** decorates the Hapi request with: | ||
* `request.logger`, which is an instance of [pino][pino] bound to the current request, so you can trace all the logs of a given request. See [pino][pino] doc for the way to actual log. | ||
<a name="hapievents"></a> | ||
### Hapi Events | ||
**hapi-pino** listens to some Hapi events: | ||
* `'onRequest'`, to create a request-specific child logger | ||
* `'response'`, to log at `'info'` level when a request is completed | ||
* `'response-error'`, to log at `'warn'` level when a request errors | ||
* `'log'`, to support logging via the Hapi `server.log()` and | ||
`request.log()` methods, see `tags` and `allTags` options. | ||
* `'onPostStart'`, to log when the server is started | ||
* `'onPostStopt'`, to log when the server is stopped | ||
## Acknowledgements | ||
@@ -76,1 +132,3 @@ | ||
MIT | ||
[pino]: https://github.com/mcollina/pino |
129
test.js
@@ -41,2 +41,16 @@ 'use strict' | ||
function tagsWithSink (server, tags, func, registered) { | ||
const stream = sink(func) | ||
const plugin = { | ||
register: Pino.register, | ||
options: { | ||
stream: stream, | ||
level: 'trace', | ||
tags: tags | ||
} | ||
} | ||
server.register(plugin, registered) | ||
} | ||
function onHelloWorld (data) { | ||
@@ -201,1 +215,116 @@ expect(data.msg).to.equal('hello world') | ||
}) | ||
experiment('logs through server.log', () => { | ||
ltest((level, done) => { | ||
const server = getServer() | ||
tagsWithSink(server, { | ||
aaa: 'info' | ||
}, (data) => { | ||
expect(data.data).to.equal('hello world') | ||
expect(data.level).to.equal(30) | ||
done() | ||
}, (err) => { | ||
expect(err).to.be.undefined() | ||
server.log(['aaa'], 'hello world') | ||
}) | ||
}) | ||
test('one log for multiple tags', (done) => { | ||
const server = getServer() | ||
tagsWithSink(server, { | ||
aaa: 'info', | ||
bbb: 'warn' | ||
}, (data) => { | ||
expect(data.data).to.equal('hello world') | ||
// first matching tag | ||
expect(data.level).to.equal(30) | ||
done() | ||
}, (err) => { | ||
expect(err).to.be.undefined() | ||
server.log(['aaa', 'bbb'], 'hello world') | ||
}) | ||
}) | ||
test('explode with a wrong level', (done) => { | ||
const server = getServer() | ||
server.register({ | ||
register: Pino.register, | ||
options: { | ||
tags: { | ||
bbb: 'not a level' | ||
} | ||
} | ||
}, (err) => { | ||
expect(err).to.be.error() | ||
done() | ||
}) | ||
}) | ||
test('with tag catchall', (done) => { | ||
const server = getServer() | ||
const stream = sink((data) => { | ||
expect(data.data).to.equal('hello world') | ||
expect(data.level).to.equal(20) | ||
done() | ||
}) | ||
const plugin = { | ||
register: Pino.register, | ||
options: { | ||
stream: stream, | ||
level: 'debug', | ||
allTags: 'debug' | ||
} | ||
} | ||
server.register(plugin, (err) => { | ||
expect(err).to.be.undefined() | ||
server.log(['something'], 'hello world') | ||
}) | ||
}) | ||
test('default tag catchall', (done) => { | ||
const server = getServer() | ||
const stream = sink((data) => { | ||
expect(data.data).to.equal('hello world') | ||
expect(data.level).to.equal(30) | ||
done() | ||
}) | ||
const plugin = { | ||
register: Pino.register, | ||
options: { | ||
stream: stream | ||
} | ||
} | ||
server.register(plugin, (err) => { | ||
expect(err).to.be.undefined() | ||
server.log(['something'], 'hello world') | ||
}) | ||
}) | ||
}) | ||
experiment('logs through request.log', () => { | ||
ltest((level, done) => { | ||
const server = getServer() | ||
server.route({ | ||
path: '/', | ||
method: 'GET', | ||
handler: (req, reply) => { | ||
req.log(['aaa'], 'hello logger') | ||
reply('hello world') | ||
} | ||
}) | ||
tagsWithSink(server, { | ||
aaa: level | ||
}, (data, enc, cb) => { | ||
if (data.tags) { | ||
expect(data.data).to.equal('hello logger') | ||
done() | ||
} | ||
cb() | ||
}, (err) => { | ||
expect(err).to.be.undefined() | ||
server.inject('/') | ||
}) | ||
}) | ||
}) |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
17441
423
0
130