Repository: pinojs/pino (js)

Issue:
Pino always show custom levels if they were added after the logging level is set
**Here's a test code**

```javascript
const pino = require('pino')({
  level: 'info'
})
pino.addLevel('verbose', 25)
pino.addLevel('silly', 5)

pino.fatal('fatal')
pino.error('error')
pino.warn('warn')
pino.info('info')
pino.verbose('verbose')
pino.debug('debug')
pino.trace('trace')
pino.silly('silly')
```

**Output**
```
{"pid":5484,"hostname":"bruno-All-Series","level":60,"time":1495832557805,"msg":"fatal","v":1}
{"pid":5484,"hostname":"bruno-All-Series","level":50,"time":1495832557806,"msg":"error","v":1}
{"pid":5484,"hostname":"bruno-All-Series","level":40,"time":1495832557807,"msg":"warn","v":1}
{"pid":5484,"hostname":"bruno-All-Series","level":30,"time":1495832557807,"msg":"info","v":1}
{"pid":5484,"hostname":"bruno-All-Series","level":25,"time":1495832557807,"msg":"verbose","v":1}
{"pid":5484,"hostname":"bruno-All-Series","level":5,"time":1495832557807,"msg":"silly","v":1}
```

**Ther last two lines shouldn't be printed.**

The workaround we found is to set the logging level after the addLevel calls:

```javascript
const pino = require('pino')()
pino.addLevel('verbose', 25)
pino.addLevel('silly', 5)
pino.level = 'info'

pino.fatal('fatal')
pino.error('error')
pino.warn('warn')
pino.info('info')
pino.verbose('verbose')
pino.debug('debug')
pino.trace('trace')
pino.silly('silly')
```

I'm not sure whether it is an undocumented requirement or a bug. Either way it would be nice do document or fix it. I wasted a few hours trying to fix it.

Pull request description:
added levelVal check to addLevel function
Fixes #246 

Patch:
diff --git a/pino.js b/pino.js
index aef3b1e..323e033 100644
--- a/pino.js
+++ b/pino.js
@@ -233,7 +233,12 @@ function addLevel (name, lvl) {
   this.levels.values[name] = lvl
   this.levels.labels[lvl] = name
   this._lscache[lvl] = flatstr('"level":' + Number(lvl))
-  this[name] = tools.genLog(lvl)
+  Object.defineProperty(this, name, {
+    value: lvl < this._levelVal ? tools.noop : tools.genLog(lvl),
+    enumerable: true,
+    writable: true
+  })
+
   return true
 }
 Object.defineProperty(pinoPrototype, 'addLevel', {


Test patch:
diff --git a/test/addlevel.test.js b/test/addlevel.test.js
index fd9ceab..4cf1b7d 100644
--- a/test/addlevel.test.js
+++ b/test/addlevel.test.js
@@ -73,6 +73,20 @@ test('after the fact add level does not include lower levels', function (t) {
   log.foo('bar')
 })
 
+test('after the fact add of a lower level does not include it', function (t) {
+  t.plan(1)
+
+  var log = pino(sink(function (chunk, enc, cb) {
+    t.is(chunk.msg, 'bar')
+    cb()
+  }))
+
+  log.level = 'info'
+  log.addLevel('foo', 15)
+  log.info('bar')
+  log.foo('nope')
+})
+
 test('children can be set to custom level', function (t) {
   t.plan(2)