Refactor entire project into ecmamodules, remove all dependencies, and use eltro as our test runner.
This commit is contained in:
parent
1260b89e48
commit
89429a34c1
58 changed files with 4734 additions and 5664 deletions
|
@ -1,7 +0,0 @@
|
|||
/tmp
|
||||
/node_modules
|
||||
*.log
|
||||
/examples
|
||||
/test
|
||||
/*.tgz
|
||||
/tools
|
1
.npmrc
Normal file
1
.npmrc
Normal file
|
@ -0,0 +1 @@
|
|||
package-lock=false
|
127
Makefile
127
Makefile
|
@ -1,127 +0,0 @@
|
|||
|
||||
#---- Tools
|
||||
|
||||
NODEUNIT := ./node_modules/.bin/nodeunit
|
||||
NODEOPT ?= $(HOME)/opt
|
||||
|
||||
|
||||
#---- Files
|
||||
|
||||
JSSTYLE_FILES := $(shell find lib test tools examples -name "*.js") bin/bunyan
|
||||
# All test files
|
||||
TEST_FILES := $(shell ls -1 test/*.test.js | xargs)
|
||||
|
||||
|
||||
#---- Targets
|
||||
|
||||
all $(NODEUNIT):
|
||||
npm install $(NPM_INSTALL_FLAGS)
|
||||
|
||||
# Ensure all version-carrying files have the same version.
|
||||
.PHONY: versioncheck
|
||||
versioncheck:
|
||||
@echo version is: $(shell cat package.json | json version)
|
||||
[[ `cat package.json | json version` == `grep '^## ' CHANGES.md | head -2 | tail -1 | awk '{print $$2}'` ]]
|
||||
@echo Version check ok.
|
||||
|
||||
.PHONY: cutarelease
|
||||
cutarelease: check
|
||||
[[ -z `git status --short` ]] # If this fails, the working dir is dirty.
|
||||
@which json 2>/dev/null 1>/dev/null && \
|
||||
ver=$(shell json -f package.json version) && \
|
||||
name=$(shell json -f package.json name) && \
|
||||
publishedVer=$(shell npm view -j $(shell json -f package.json name)@$(shell json -f package.json version) version 2>/dev/null) && \
|
||||
if [[ -n "$$publishedVer" ]]; then \
|
||||
echo "error: $$name@$$ver is already published to npm"; \
|
||||
exit 1; \
|
||||
fi && \
|
||||
echo "** Are you sure you want to tag and publish $$name@$$ver to npm?" && \
|
||||
echo "** Enter to continue, Ctrl+C to abort." && \
|
||||
read
|
||||
ver=$(shell cat package.json | json version) && \
|
||||
date=$(shell date -u "+%Y-%m-%d") && \
|
||||
git tag -a "$$ver" -m "version $$ver ($$date) beta" && \
|
||||
git push --tags origin && \
|
||||
npm publish --tag beta
|
||||
|
||||
.PHONY: docs
|
||||
docs: toc
|
||||
@[[ `which ronn` ]] || (echo "No 'ronn' on your PATH. Install with 'gem install ronn'" && exit 2)
|
||||
mkdir -p man/man1
|
||||
ronn --style=toc --manual="bunyan manual" --date=$(shell git log -1 --pretty=format:%cd --date=short) --roff --html docs/bunyan.1.ronn
|
||||
python -c 'import sys; h = open("docs/bunyan.1.html").read(); h = h.replace(".mp dt.flush {float:left;width:8ex}", ""); open("docs/bunyan.1.html", "w").write(h)'
|
||||
python -c 'import sys; h = open("docs/bunyan.1.html").read(); h = h.replace("</body>", """<a href="https://github.com/trentm/node-bunyan"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a></body>"""); open("docs/bunyan.1.html", "w").write(h)'
|
||||
@echo "# test with 'man ./docs/bunyan.1' and 'open ./docs/bunyan.1.html'"
|
||||
|
||||
# Re-generate the README.md table of contents.
|
||||
toc:
|
||||
./node_modules/.bin/markdown-toc -i README.md
|
||||
|
||||
|
||||
.PHONY: publish
|
||||
publish:
|
||||
mkdir -p tmp
|
||||
[[ -d tmp/bunyan-gh-pages ]] || git clone git@github.com:trentm/node-bunyan.git tmp/bunyan-gh-pages
|
||||
cd tmp/bunyan-gh-pages && git checkout gh-pages && git pull --rebase origin gh-pages
|
||||
cp docs/index.html tmp/bunyan-gh-pages/index.html
|
||||
cp docs/bunyan.1.html tmp/bunyan-gh-pages/bunyan.1.html
|
||||
(cd tmp/bunyan-gh-pages \
|
||||
&& git commit -a -m "publish latest docs" \
|
||||
&& git push origin gh-pages || true)
|
||||
|
||||
.PHONY: distclean
|
||||
distclean:
|
||||
rm -rf node_modules
|
||||
|
||||
|
||||
#---- test
|
||||
|
||||
.PHONY: test
|
||||
test: $(NODEUNIT)
|
||||
$(NODEUNIT) $(TEST_FILES)
|
||||
|
||||
# Test with all node supported versions (presumes install locations I use on
|
||||
# my machine -- "~/opt/node-VER"):
|
||||
.PHONY: testall
|
||||
testall: test7 test6 test012 test010 test4
|
||||
|
||||
.PHONY: test7
|
||||
test7:
|
||||
@echo "# Test node 7.x (with node `$(NODEOPT)/node-7/bin/node --version`)"
|
||||
@$(NODEOPT)/node-7/bin/node --version | grep '^v7\.'
|
||||
PATH="$(NODEOPT)/node-7/bin:$(PATH)" make distclean all test
|
||||
.PHONY: test6
|
||||
test6:
|
||||
@echo "# Test node 6.x (with node `$(NODEOPT)/node-6/bin/node --version`)"
|
||||
@$(NODEOPT)/node-6/bin/node --version | grep '^v6\.'
|
||||
PATH="$(NODEOPT)/node-6/bin:$(PATH)" make distclean all test
|
||||
.PHONY: test4
|
||||
test4:
|
||||
@echo "# Test node 4.x (with node `$(NODEOPT)/node-4/bin/node --version`)"
|
||||
@$(NODEOPT)/node-4/bin/node --version | grep '^v4\.'
|
||||
PATH="$(NODEOPT)/node-4/bin:$(PATH)" make distclean all test
|
||||
.PHONY: test012
|
||||
test012:
|
||||
@echo "# Test node 0.12.x (with node `$(NODEOPT)/node-0.12/bin/node --version`)"
|
||||
@$(NODEOPT)/node-0.12/bin/node --version | grep '^v0\.12\.'
|
||||
PATH="$(NODEOPT)/node-0.12/bin:$(PATH)" make distclean all test
|
||||
.PHONY: test010
|
||||
test010:
|
||||
@echo "# Test node 0.10.x (with node `$(NODEOPT)/node-0.10/bin/node --version`)"
|
||||
@$(NODEOPT)/node-0.10/bin/node --version | grep '^v0\.10\.'
|
||||
PATH="$(NODEOPT)/node-0.10/bin:$(PATH)" make distclean all test
|
||||
|
||||
|
||||
#---- check
|
||||
|
||||
.PHONY: check-jsstyle
|
||||
check-jsstyle: $(JSSTYLE_FILES)
|
||||
./tools/jsstyle -o indent=4,doxygen,unparenthesized-return=0,blank-after-start-comment=0,leading-right-paren-ok=1 $(JSSTYLE_FILES)
|
||||
|
||||
.PHONY: check
|
||||
check: check-jsstyle versioncheck
|
||||
@echo "Check ok."
|
||||
|
||||
.PHONY: prepush
|
||||
prepush: check testall
|
||||
@echo "Okay to push."
|
1407
bin/bunyan
1407
bin/bunyan
File diff suppressed because it is too large
Load diff
1397
bin/bunyan.mjs
Normal file
1397
bin/bunyan.mjs
Normal file
File diff suppressed because it is too large
Load diff
1585
lib/bunyan.js
1585
lib/bunyan.js
File diff suppressed because it is too large
Load diff
1128
lib/bunyan.mjs
Normal file
1128
lib/bunyan.mjs
Normal file
File diff suppressed because it is too large
Load diff
69
lib/safe-json.mjs
Normal file
69
lib/safe-json.mjs
Normal file
|
@ -0,0 +1,69 @@
|
|||
var hasProp = Object.prototype.hasOwnProperty
|
||||
|
||||
function throwsMessage(err) {
|
||||
return '[Throws: ' + (err ? err.message : '?') + ']'
|
||||
}
|
||||
|
||||
function safeGetValueFromPropertyOnObject(obj, property) {
|
||||
if (hasProp.call(obj, property)) {
|
||||
try {
|
||||
return obj[property]
|
||||
}
|
||||
catch (err) {
|
||||
return throwsMessage(err)
|
||||
}
|
||||
}
|
||||
|
||||
return obj[property]
|
||||
}
|
||||
|
||||
function ensureProperties(obj) {
|
||||
var seen = new WeakMap()
|
||||
|
||||
function visit(obj) {
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
return obj
|
||||
}
|
||||
|
||||
if (seen.has(obj)) {
|
||||
return '[Circular]'
|
||||
}
|
||||
|
||||
seen.set(obj, true)
|
||||
|
||||
if (typeof obj.toJSON === 'function') {
|
||||
try {
|
||||
var fResult = visit(obj.toJSON())
|
||||
seen.delete(obj)
|
||||
return fResult
|
||||
} catch(err) {
|
||||
seen.delete(obj)
|
||||
return throwsMessage(err)
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
var aResult = obj.map(visit)
|
||||
seen.delete(obj)
|
||||
return aResult
|
||||
}
|
||||
|
||||
var result = Object.keys(obj).reduce(function(result, prop) {
|
||||
// prevent faulty defined getter properties
|
||||
result[prop] = visit(safeGetValueFromPropertyOnObject(obj, prop))
|
||||
return result
|
||||
}, {})
|
||||
seen.delete(obj)
|
||||
return result
|
||||
}
|
||||
|
||||
return visit(obj)
|
||||
}
|
||||
|
||||
function safeJson(data, replacer, space) {
|
||||
return JSON.stringify(ensureProperties(data), replacer, space)
|
||||
}
|
||||
|
||||
safeJson.ensureProperties = ensureProperties
|
||||
|
||||
export default safeJson
|
28
package.json
28
package.json
|
@ -1,19 +1,16 @@
|
|||
{
|
||||
"name": "bunyan-lite",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"description": "a lite version of bunyan, a JSON logging library for node.js services without dtrace or moment",
|
||||
"author": "Jonatan Nilsson <jonatan@nilsson.is> (https://nfp.is)",
|
||||
"main": "./lib/bunyan.js",
|
||||
"bin": {
|
||||
"bunyan": "./bin/bunyan"
|
||||
"bunyan": "./bin/bunyan.mjs"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/nfp-projects/node-bunyan-lite.git"
|
||||
},
|
||||
"engines": [
|
||||
"node >=0.10.0"
|
||||
],
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
|
@ -23,19 +20,16 @@
|
|||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {},
|
||||
"// mv": "required for RotatingFileStream",
|
||||
"optionalDependencies": {
|
||||
"mv-lite": "~1",
|
||||
"safe-json-stringify": "~1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodeunit": "0.9",
|
||||
"ben": "0.0.0",
|
||||
"markdown-toc": "0.12.x",
|
||||
"verror": "1.3.3",
|
||||
"vasync": "1.4.3"
|
||||
"eltro": "^1.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
}
|
||||
"test": "eltro test/**/*.test.mjs -r dot"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE.txt",
|
||||
"README.md",
|
||||
"bin",
|
||||
"lib"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test stream adding.
|
||||
*/
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
test('non-writables passed as stream', function (t) {
|
||||
var things = ['process.stdout', {}];
|
||||
things.forEach(function (thing) {
|
||||
function createLogger() {
|
||||
bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: thing
|
||||
});
|
||||
}
|
||||
t.throws(createLogger,
|
||||
/stream is not writable/,
|
||||
'"stream" stream is not writable');
|
||||
})
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proper stream', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: process.stdout
|
||||
});
|
||||
t.ok('should not throw');
|
||||
t.end();
|
||||
});
|
28
test/add-stream.test.mjs
Normal file
28
test/add-stream.test.mjs
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test stream adding.
|
||||
*/
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
t.test('non-writables passed as stream', function () {
|
||||
var things = ['process.stdout', {}];
|
||||
things.forEach(function (thing) {
|
||||
function createLogger() {
|
||||
bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: thing
|
||||
});
|
||||
}
|
||||
assert.throws(createLogger,
|
||||
/stream is not writable/);
|
||||
})
|
||||
});
|
||||
|
||||
t.test('proper stream', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: process.stdout
|
||||
});
|
||||
});
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
* Copyright (c) 2012 Joyent Inc. All rights reserved.
|
||||
*
|
||||
* Test logging with (accidental) usage of buffers.
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
inspect = util.inspect,
|
||||
format = util.format;
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
|
||||
function Catcher() {
|
||||
this.records = [];
|
||||
}
|
||||
Catcher.prototype.write = function (record) {
|
||||
this.records.push(record);
|
||||
}
|
||||
|
||||
var catcher = new Catcher();
|
||||
var log = new bunyan.createLogger({
|
||||
name: 'buffer.test',
|
||||
streams: [
|
||||
{
|
||||
type: 'raw',
|
||||
stream: catcher,
|
||||
level: 'trace'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
test('log.info(BUFFER)', function (t) {
|
||||
var b = new Buffer('foo');
|
||||
|
||||
['trace',
|
||||
'debug',
|
||||
'info',
|
||||
'warn',
|
||||
'error',
|
||||
'fatal'].forEach(function (lvl) {
|
||||
log[lvl].call(log, b);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, inspect(b),
|
||||
format('log.%s msg is inspect(BUFFER)', lvl));
|
||||
t.ok(rec['0'] === undefined,
|
||||
'no "0" array index key in record: ' + inspect(rec['0']));
|
||||
t.ok(rec['parent'] === undefined,
|
||||
'no "parent" array index key in record: ' + inspect(rec['parent']));
|
||||
|
||||
log[lvl].call(log, b, 'bar');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, inspect(b) + ' bar', format(
|
||||
'log.%s(BUFFER, "bar") msg is inspect(BUFFER) + " bar"', lvl));
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
//test('log.info({buf: BUFFER})', function (t) {
|
||||
// var b = new Buffer('foo');
|
||||
//
|
||||
// // Really there isn't much Bunyan can do here. See
|
||||
// // <https://github.com/joyent/node/issues/3905>. An unwelcome hack would
|
||||
// // be to monkey-patch in Buffer.toJSON. Bletch.
|
||||
// log.info({buf: b}, 'my message');
|
||||
// var rec = catcher.records[catcher.records.length - 1];
|
||||
//
|
||||
// t.end();
|
||||
//});
|
74
test/buffer.test.mjs
Normal file
74
test/buffer.test.mjs
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
* Copyright (c) 2012 Joyent Inc. All rights reserved.
|
||||
*
|
||||
* Test logging with (accidental) usage of buffers.
|
||||
*/
|
||||
|
||||
import util from 'util'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
const inspect = util.inspect
|
||||
const format = util.format
|
||||
|
||||
|
||||
function Catcher() {
|
||||
this.records = []
|
||||
}
|
||||
Catcher.prototype.write = function (record) {
|
||||
this.records.push(record)
|
||||
}
|
||||
|
||||
let catcher = new Catcher()
|
||||
let log = new bunyan.createLogger({
|
||||
name: 'buffer.test',
|
||||
streams: [
|
||||
{
|
||||
type: 'raw',
|
||||
stream: catcher,
|
||||
level: 'trace'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
t.test('log.info(BUFFER)', function () {
|
||||
let b = Buffer.from('foo')
|
||||
|
||||
let testLevels = ['trace',
|
||||
'debug',
|
||||
'info',
|
||||
'warn',
|
||||
'error',
|
||||
'fatal']
|
||||
|
||||
testLevels.forEach(function (lvl) {
|
||||
log[lvl].call(log, b)
|
||||
let rec = catcher.records[catcher.records.length - 1]
|
||||
assert.strictEqual(rec.msg, inspect(b),
|
||||
format('log.%s msg is inspect(BUFFER)', lvl))
|
||||
assert.ok(rec['0'] === undefined,
|
||||
'no "0" array index key in record: ' + inspect(rec['0']))
|
||||
assert.ok(rec['parent'] === undefined,
|
||||
'no "parent" array index key in record: ' + inspect(rec['parent']))
|
||||
|
||||
log[lvl].call(log, b, 'bar')
|
||||
rec = catcher.records[catcher.records.length - 1]
|
||||
assert.strictEqual(rec.msg, inspect(b) + ' bar', format(
|
||||
'log.%s(BUFFER, "bar") msg is inspect(BUFFER) + " bar"', lvl))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
//test('log.info({buf: BUFFER})', function (t) {
|
||||
// let b = new Buffer('foo')
|
||||
//
|
||||
// // Really there isn't much Bunyan can do here. See
|
||||
// // <https://github.com/joyent/node/issues/3905>. An unwelcome hack would
|
||||
// // be to monkey-patch in Buffer.toJSON. Bletch.
|
||||
// log.info({buf: b}, 'my message')
|
||||
// let rec = catcher.records[catcher.records.length - 1]
|
||||
//
|
||||
// t.end()
|
||||
//})
|
|
@ -4,16 +4,8 @@
|
|||
* Test some `<Logger>.child(...)` behaviour.
|
||||
*/
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
|
||||
function CapturingStream(recs) {
|
||||
|
@ -24,10 +16,9 @@ CapturingStream.prototype.write = function (rec) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
test('child can add stream', function (t) {
|
||||
var dadStream = new CapturingStream();
|
||||
var dad = bunyan.createLogger({
|
||||
t.test('child can add stream', function () {
|
||||
let dadStream = new CapturingStream();
|
||||
let dad = bunyan.createLogger({
|
||||
name: 'surname',
|
||||
streams: [ {
|
||||
type: 'raw',
|
||||
|
@ -36,8 +27,8 @@ test('child can add stream', function (t) {
|
|||
} ]
|
||||
});
|
||||
|
||||
var sonStream = new CapturingStream();
|
||||
var son = dad.child({
|
||||
let sonStream = new CapturingStream();
|
||||
let son = dad.child({
|
||||
component: 'son',
|
||||
streams: [ {
|
||||
type: 'raw',
|
||||
|
@ -50,21 +41,20 @@ test('child can add stream', function (t) {
|
|||
dad.debug('debug from dad');
|
||||
son.debug('debug from son');
|
||||
|
||||
var rec;
|
||||
t.equal(dadStream.recs.length, 1);
|
||||
let rec;
|
||||
assert.equal(dadStream.recs.length, 1);
|
||||
rec = dadStream.recs[0];
|
||||
t.equal(rec.msg, 'info from dad');
|
||||
t.equal(sonStream.recs.length, 1);
|
||||
assert.equal(rec.msg, 'info from dad');
|
||||
assert.equal(sonStream.recs.length, 1);
|
||||
rec = sonStream.recs[0];
|
||||
t.equal(rec.msg, 'debug from son');
|
||||
assert.equal(rec.msg, 'debug from son');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('child can set level of inherited streams', function (t) {
|
||||
var dadStream = new CapturingStream();
|
||||
var dad = bunyan.createLogger({
|
||||
t.test('child can set level of inherited streams', function () {
|
||||
let dadStream = new CapturingStream();
|
||||
let dad = bunyan.createLogger({
|
||||
name: 'surname',
|
||||
streams: [ {
|
||||
type: 'raw',
|
||||
|
@ -75,7 +65,7 @@ test('child can set level of inherited streams', function (t) {
|
|||
|
||||
// Intention here is that the inherited `dadStream` logs at 'debug' level
|
||||
// for the son.
|
||||
var son = dad.child({
|
||||
let son = dad.child({
|
||||
component: 'son',
|
||||
level: 'debug'
|
||||
});
|
||||
|
@ -84,20 +74,19 @@ test('child can set level of inherited streams', function (t) {
|
|||
dad.debug('debug from dad');
|
||||
son.debug('debug from son');
|
||||
|
||||
var rec;
|
||||
t.equal(dadStream.recs.length, 2);
|
||||
let rec;
|
||||
assert.equal(dadStream.recs.length, 2);
|
||||
rec = dadStream.recs[0];
|
||||
t.equal(rec.msg, 'info from dad');
|
||||
assert.equal(rec.msg, 'info from dad');
|
||||
rec = dadStream.recs[1];
|
||||
t.equal(rec.msg, 'debug from son');
|
||||
assert.equal(rec.msg, 'debug from son');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('child can set level of inherited streams and add streams', function (t) {
|
||||
var dadStream = new CapturingStream();
|
||||
var dad = bunyan.createLogger({
|
||||
t.test('child can set level of inherited streams and add streams', function () {
|
||||
let dadStream = new CapturingStream();
|
||||
let dad = bunyan.createLogger({
|
||||
name: 'surname',
|
||||
streams: [ {
|
||||
type: 'raw',
|
||||
|
@ -108,8 +97,8 @@ test('child can set level of inherited streams and add streams', function (t) {
|
|||
|
||||
// Intention here is that the inherited `dadStream` logs at 'debug' level
|
||||
// for the son.
|
||||
var sonStream = new CapturingStream();
|
||||
var son = dad.child({
|
||||
let sonStream = new CapturingStream();
|
||||
let son = dad.child({
|
||||
component: 'son',
|
||||
level: 'trace',
|
||||
streams: [ {
|
||||
|
@ -124,21 +113,20 @@ test('child can set level of inherited streams and add streams', function (t) {
|
|||
son.trace('trace from son');
|
||||
son.debug('debug from son');
|
||||
|
||||
t.equal(dadStream.recs.length, 3);
|
||||
t.equal(dadStream.recs[0].msg, 'info from dad');
|
||||
t.equal(dadStream.recs[1].msg, 'trace from son');
|
||||
t.equal(dadStream.recs[2].msg, 'debug from son');
|
||||
assert.equal(dadStream.recs.length, 3);
|
||||
assert.equal(dadStream.recs[0].msg, 'info from dad');
|
||||
assert.equal(dadStream.recs[1].msg, 'trace from son');
|
||||
assert.equal(dadStream.recs[2].msg, 'debug from son');
|
||||
|
||||
t.equal(sonStream.recs.length, 1);
|
||||
t.equal(sonStream.recs[0].msg, 'debug from son');
|
||||
assert.equal(sonStream.recs.length, 1);
|
||||
assert.equal(sonStream.recs[0].msg, 'debug from son');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
// issue #291
|
||||
test('child should not lose parent "hostname"', function (t) {
|
||||
var stream = new CapturingStream();
|
||||
var dad = bunyan.createLogger({
|
||||
t.test('child should not lose parent "hostname"', function () {
|
||||
let stream = new CapturingStream();
|
||||
let dad = bunyan.createLogger({
|
||||
name: 'hostname-test',
|
||||
hostname: 'bar0',
|
||||
streams: [ {
|
||||
|
@ -147,15 +135,14 @@ test('child should not lose parent "hostname"', function (t) {
|
|||
level: 'info'
|
||||
} ]
|
||||
});
|
||||
var son = dad.child({component: 'son'});
|
||||
let son = dad.child({component: 'son'});
|
||||
|
||||
dad.info('HI');
|
||||
son.info('hi');
|
||||
|
||||
t.equal(stream.recs.length, 2);
|
||||
t.equal(stream.recs[0].hostname, 'bar0');
|
||||
t.equal(stream.recs[1].hostname, 'bar0');
|
||||
t.equal(stream.recs[1].component, 'son');
|
||||
assert.equal(stream.recs.length, 2);
|
||||
assert.equal(stream.recs[0].hostname, 'bar0');
|
||||
assert.equal(stream.recs[1].hostname, 'bar0');
|
||||
assert.equal(stream.recs[1].component, 'son');
|
||||
|
||||
t.end();
|
||||
});
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Trent Mick.
|
||||
*
|
||||
* Test the bunyan CLI's handling of the "client_req" field.
|
||||
* "client_req" is a common-ish Bunyan log field from restify-clients. See:
|
||||
* // JSSTYLED
|
||||
* https://github.com/restify/clients/blob/85374f87db9f4469de2605b6b15632b317cc12be/lib/helpers/bunyan.js#L213
|
||||
*/
|
||||
|
||||
var exec = require('child_process').exec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var _ = require('util').format;
|
||||
var vasync = require('vasync');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- globals
|
||||
|
||||
var BUNYAN = path.resolve(__dirname, '../bin/bunyan');
|
||||
|
||||
|
||||
// ---- tests
|
||||
|
||||
test('client_req extra newlines, client_res={} (pull #252)', function (t) {
|
||||
var expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2016-02-10T07:28:40.510Z] TRACE: aclientreq/23280 on danger0.local: request sent',
|
||||
' GET /--ping HTTP/1.1',
|
||||
'[2016-02-10T07:28:41.419Z] TRACE: aclientreq/23280 on danger0.local: Response received',
|
||||
' HTTP/1.1 200 OK',
|
||||
' request-id: e8a5a700-cfc7-11e5-a3dc-3b85d20f26ef',
|
||||
' content-type: application/json'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
exec(_('%s %s/corpus/clientreqres.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('client_req.address is not used for Host header in 2.x (issue #504)',
|
||||
function (t) {
|
||||
exec(_('%s %s/corpus/client-req-with-address.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout, [
|
||||
// JSSTYLED
|
||||
'[2017-05-12T23:59:15.877Z] TRACE: minfo/66266 on sharptooth.local: request sent (client_req.address=127.0.0.1)',
|
||||
' HEAD /dap/stor HTTP/1.1',
|
||||
' accept: application/json, */*',
|
||||
' host: foo.example.com',
|
||||
' date: Fri, 12 May 2017 23:59:15 GMT',
|
||||
''
|
||||
].join('\n'));
|
||||
t.end();
|
||||
});
|
||||
});
|
45
test/cli-client-req.test.mjs
Normal file
45
test/cli-client-req.test.mjs
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Trent Mick.
|
||||
*
|
||||
* Test the bunyan CLI's handling of the "client_req" field.
|
||||
* "client_req" is a common-ish Bunyan log field from restify-clients. See:
|
||||
* // JSSTYLED
|
||||
* https://github.com/restify/clients/blob/85374f87db9f4469de2605b6b15632b317cc12be/lib/helpers/bunyan.js#L213
|
||||
*/
|
||||
|
||||
import { exec, dirname } from './helper.mjs'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
|
||||
// ---- tests
|
||||
|
||||
t.test('client_req extra newlines, client_res={} (pull #252)', async function () {
|
||||
const expected = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2016-02-10T07:28:40.510Z] TRACE: aclientreq/23280 on danger0.local: request sent',
|
||||
' GET /--ping HTTP/1.1',
|
||||
'[2016-02-10T07:28:41.419Z] TRACE: aclientreq/23280 on danger0.local: Response received',
|
||||
' HTTP/1.1 200 OK',
|
||||
' request-id: e8a5a700-cfc7-11e5-a3dc-3b85d20f26ef',
|
||||
' content-type: application/json'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
|
||||
let res = await exec(dirname('/corpus/clientreqres.log'))
|
||||
assert.strictEqual(res.stdout, expected)
|
||||
});
|
||||
|
||||
|
||||
t.test('client_req.address is not used for Host header in 2.x (issue #504)', async function () {
|
||||
const expected = [
|
||||
// JSSTYLED
|
||||
'[2017-05-12T23:59:15.877Z] TRACE: minfo/66266 on sharptooth.local: request sent (client_req.address=127.0.0.1)',
|
||||
' HEAD /dap/stor HTTP/1.1',
|
||||
' accept: application/json, */*',
|
||||
' host: foo.example.com',
|
||||
' date: Fri, 12 May 2017 23:59:15 GMT',
|
||||
''
|
||||
].join('\n')
|
||||
|
||||
let res = await exec(dirname('/corpus/client-req-with-address.log'))
|
||||
assert.strictEqual(res.stdout, expected)
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Trent Mick.
|
||||
*
|
||||
* Test the bunyan CLI's handling of the "res" field.
|
||||
*/
|
||||
|
||||
var exec = require('child_process').exec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var _ = require('util').format;
|
||||
var vasync = require('vasync');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- globals
|
||||
|
||||
var BUNYAN = path.resolve(__dirname, '../bin/bunyan');
|
||||
|
||||
|
||||
// ---- tests
|
||||
|
||||
test('res with "header" string (issue #444)', function (t) {
|
||||
var expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2017-08-02T22:37:34.798Z] INFO: res-header/76488 on danger0.local: response sent',
|
||||
' HTTP/1.1 200 OK',
|
||||
' Foo: bar',
|
||||
' Date: Wed, 02 Aug 2017 22:37:34 GMT',
|
||||
' Connection: keep-alive',
|
||||
' Content-Length: 21'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
exec(_('%s %s/corpus/res-header.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('res without "header"', function (t) {
|
||||
var expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2017-08-02T22:37:34.798Z] INFO: res-header/76488 on danger0.local: response sent',
|
||||
' HTTP/1.1 200 OK'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
exec(_('%s %s/corpus/res-without-header.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
38
test/cli-res.test.mjs
Normal file
38
test/cli-res.test.mjs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Trent Mick.
|
||||
*
|
||||
* Test the bunyan CLI's handling of the "res" field.
|
||||
*/
|
||||
|
||||
import { exec, dirname } from './helper.mjs'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
|
||||
// ---- tests
|
||||
|
||||
t.test('res with "header" string (issue #444)', async function () {
|
||||
const expected = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2017-08-02T22:37:34.798Z] INFO: res-header/76488 on danger0.local: response sent',
|
||||
' HTTP/1.1 200 OK',
|
||||
' Foo: bar',
|
||||
' Date: Wed, 02 Aug 2017 22:37:34 GMT',
|
||||
' Connection: keep-alive',
|
||||
' Content-Length: 21'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
|
||||
let res = await exec(dirname('/corpus/res-header.log'))
|
||||
assert.strictEqual(res.stdout, expected)
|
||||
});
|
||||
|
||||
t.test('res without "header"', async function () {
|
||||
const expected = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2017-08-02T22:37:34.798Z] INFO: res-header/76488 on danger0.local: response sent',
|
||||
' HTTP/1.1 200 OK'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
|
||||
let res = await exec(dirname('/corpus/res-without-header.log'))
|
||||
assert.strictEqual(res.stdout, expected)
|
||||
});
|
489
test/cli.test.js
489
test/cli.test.js
|
@ -1,489 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `bunyan` CLI.
|
||||
*/
|
||||
|
||||
var p = console.warn;
|
||||
var exec = require('child_process').exec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var _ = require('util').format;
|
||||
var vasync = require('vasync');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- globals
|
||||
|
||||
var BUNYAN = path.resolve(__dirname, '../bin/bunyan');
|
||||
|
||||
|
||||
// ---- support stuff
|
||||
|
||||
/**
|
||||
* Copies over all keys in `from` to `to`, or
|
||||
* to a new object if `to` is not given.
|
||||
*/
|
||||
function objCopy(from, to) {
|
||||
if (to === undefined) {
|
||||
to = {};
|
||||
}
|
||||
for (var k in from) {
|
||||
to[k] = from[k];
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
// ---- tests
|
||||
|
||||
test('--version', function (t) {
|
||||
var version = require('../package.json').version;
|
||||
exec(BUNYAN + ' --version', function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout, 'bunyan ' + version + '\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('--help', function (t) {
|
||||
exec(BUNYAN + ' --help', function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.ok(stdout.indexOf('General options:') !== -1);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('-h', function (t) {
|
||||
exec(BUNYAN + ' -h', function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.ok(stdout.indexOf('General options:') !== -1);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('--bogus', function (t) {
|
||||
exec(BUNYAN + ' --bogus', function (err, stdout, stderr) {
|
||||
t.ok(err, 'should error out')
|
||||
t.equal(err.code, 1, '... with exit code 1')
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('simple.log', function (t) {
|
||||
exec(_('%s %s/corpus/simple.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
'[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: '
|
||||
+ 'My message\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
test('cat simple.log', function (t) {
|
||||
exec(_('cat %s/corpus/simple.log | %s', __dirname, BUNYAN),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message\n');
|
||||
t.end();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('time: simple.log utc long', function (t) {
|
||||
exec(_('%s -o long --time utc %s/corpus/simple.log', BUNYAN, __dirname),
|
||||
{env: process.env}, function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
'[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: '
|
||||
+ 'My message\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
test('time: simple.log utc short', function (t) {
|
||||
exec(_('%s -o short %s/corpus/simple.log', BUNYAN, __dirname),
|
||||
{env: process.env}, function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
'22:56:52.856Z INFO myservice: '
|
||||
+ 'My message\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('simple.log with color', function (t) {
|
||||
exec(_('%s --color %s/corpus/simple.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:52.856Z] \u001b[36m INFO\u001b[39m: myservice/123 on example.com: \u001b[36mMy message\u001b[39m\n\u001b[0m');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('extrafield.log', function (t) {
|
||||
exec(_('%s %s/corpus/extrafield.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
'[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: '
|
||||
+ 'My message (extra=field)\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
test('extrafield.log with color', function (t) {
|
||||
exec(_('%s --color %s/corpus/extrafield.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout,
|
||||
'[2012-02-08T22:56:52.856Z] \u001b[36m INFO\u001b[39m: '
|
||||
+ 'myservice/123 '
|
||||
+ 'on example.com: \u001b[36mMy message\u001b[39m'
|
||||
+ ' (extra=field)\n\u001b[0m');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('bogus.log', function (t) {
|
||||
exec(_('%s %s/corpus/bogus.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout, 'not a JSON line\n{"hi": "there"}\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('bogus.log -j', function (t) {
|
||||
exec(_('%s -j %s/corpus/bogus.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err)
|
||||
t.equal(stdout, 'not a JSON line\n{"hi": "there"}\n');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('all.log', function (t) {
|
||||
exec(_('%s %s/corpus/all.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
// Just make sure don't blow up on this.
|
||||
t.ifError(err)
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('simple.log doesnotexist1.log doesnotexist2.log', function (t) {
|
||||
exec(_('%s %s/corpus/simple.log doesnotexist1.log doesnotexist2.log',
|
||||
BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ok(err)
|
||||
t.equal(err.code, 2)
|
||||
t.equal(stdout,
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message\n');
|
||||
// Note: node v0.6.10:
|
||||
// ENOENT, no such file or directory 'asdf.log'
|
||||
// but node v0.6.14:
|
||||
// ENOENT, open 'asdf.log'
|
||||
// io.js 2.2 (at least):
|
||||
// ENOENT: no such file or directory, open 'doesnotexist1.log'
|
||||
var matches = [
|
||||
/^bunyan: ENOENT.*?, open 'doesnotexist1.log'/m,
|
||||
/^bunyan: ENOENT.*?, open 'doesnotexist2.log'/m,
|
||||
];
|
||||
matches.forEach(function (match) {
|
||||
t.ok(match.test(stderr), 'stderr matches ' + match.toString());
|
||||
});
|
||||
t.end();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('multiple logs', function (t) {
|
||||
var cmd = _('%s %s/corpus/log1.log %s/corpus/log2.log',
|
||||
BUNYAN, __dirname, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T16:58:55.586Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:01:49.339Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:47.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:57.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:08:01.105Z] INFO: agent2/76156 on headnode: message\n',
|
||||
/* END JSSTYLED */
|
||||
].join(''));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('multiple logs, bunyan format', function (t) {
|
||||
var cmd = _('%s -o bunyan %s/corpus/log1.log %s/corpus/log2.log',
|
||||
BUNYAN, __dirname, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, [
|
||||
/* BEGIN JSSTYLED */
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T16:57:55.586Z","v":0}',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T16:58:55.586Z","v":0}',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:01:49.339Z","v":0}',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:47.404Z","v":0}',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.339Z","v":0}',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.404Z","v":0}',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.404Z","v":0}',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:57.404Z","v":0}',
|
||||
'{"name":"agent2","pid":76156,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:08:01.105Z","v":0}',
|
||||
''
|
||||
/* END JSSTYLED */
|
||||
].join('\n'));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('log1.log.gz', function (t) {
|
||||
exec(_('%s %s/corpus/log1.log.gz', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
/* END JSSTYLED */
|
||||
].join(''));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('mixed text and gzip logs', function (t) {
|
||||
var cmd = _('%s %s/corpus/log1.log.gz %s/corpus/log2.log',
|
||||
BUNYAN, __dirname, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T16:58:55.586Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:01:49.339Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:47.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:57.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:08:01.105Z] INFO: agent2/76156 on headnode: message\n',
|
||||
/* END JSSTYLED */
|
||||
].join(''));
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('--level 40', function (t) {
|
||||
expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'# levels\n',
|
||||
'[2012-02-08T22:56:53.856Z] WARN: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:54.856Z] ERROR: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:55.856Z] LVL55: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:56.856Z] FATAL: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
/* END JSSTYLED */
|
||||
].join('');
|
||||
exec(_('%s -l 40 %s/corpus/all.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
exec(_('%s --level 40 %s/corpus/all.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('--condition "this.level === 10 && this.pid === 123"', function (t) {
|
||||
var expect = [
|
||||
'# levels\n',
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:50.856Z] TRACE: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join('');
|
||||
var cmd = _('%s -c "this.level === 10 && this.pid === 123"'
|
||||
+ ' %s/corpus/all.log', BUNYAN, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
var cmd = _(
|
||||
'%s --condition "this.level === 10 && this.pid === 123"'
|
||||
+ ' %s/corpus/all.log', BUNYAN, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('--condition "this.level === TRACE', function (t) {
|
||||
var expect = [
|
||||
'# levels\n',
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:50.856Z] TRACE: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join('');
|
||||
var cmd = _('%s -c "this.level === TRACE" %s/corpus/all.log',
|
||||
BUNYAN, __dirname);
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.done();
|
||||
});
|
||||
});
|
||||
|
||||
// multiple
|
||||
test('multiple --conditions', function (t) {
|
||||
var expect = [
|
||||
'# levels\n',
|
||||
/* JSSTYLED */
|
||||
'[2012-02-08T22:56:53.856Z] WARN: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join('');
|
||||
exec(_('%s %s/corpus/all.log -c "this.level === 40" -c "this.pid === 123"',
|
||||
BUNYAN, __dirname), function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/30
|
||||
//
|
||||
// One of the records in corpus/withreq.log has a 'req'
|
||||
// field with no 'headers'. Ditto for the 'res' field.
|
||||
test('robust req handling', function (t) {
|
||||
var expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2012-08-08T10:25:47.636Z] DEBUG: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: headAgentProbes respond (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, route=HeadAgentProbes, contentMD5=11FxOYiYfpMxmANj4kGJzg==)',
|
||||
'[2012-08-08T10:25:47.637Z] INFO: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: HeadAgentProbes handled: 200 (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, audit=true, remoteAddress=10.2.207.2, remotePort=50394, latency=3, secure=false, _audit=true, req.version=*)',
|
||||
' HEAD /agentprobes?agent=ccf92af9-0b24-46b6-ab60-65095fdd3037 HTTP/1.1',
|
||||
' accept: application/json',
|
||||
' content-type: application/json',
|
||||
' host: 10.2.207.16',
|
||||
' connection: keep-alive',
|
||||
' --',
|
||||
' HTTP/1.1 200 OK',
|
||||
' content-md5: 11FxOYiYfpMxmANj4kGJzg==',
|
||||
' access-control-allow-origin: *',
|
||||
' access-control-allow-headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version',
|
||||
' access-control-allow-methods: HEAD',
|
||||
' access-control-expose-headers: X-Api-Version, X-Request-Id, X-Response-Time',
|
||||
' connection: Keep-Alive',
|
||||
' date: Wed, 08 Aug 2012 10:25:47 GMT',
|
||||
' server: Amon Master/1.0.0',
|
||||
' x-request-id: cce79d15-ffc2-487c-a4e4-e940bdaac31e',
|
||||
' x-response-time: 3',
|
||||
' --',
|
||||
' route: {',
|
||||
' "name": "HeadAgentProbes",',
|
||||
' "version": false',
|
||||
' }',
|
||||
'[2012-08-08T10:25:47.637Z] INFO: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: HeadAgentProbes handled: 200 (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, audit=true, remoteAddress=10.2.207.2, remotePort=50394, latency=3, secure=false, _audit=true, req.version=*)',
|
||||
' HEAD /agentprobes?agent=ccf92af9-0b24-46b6-ab60-65095fdd3037 HTTP/1.1',
|
||||
' --',
|
||||
' HTTP/1.1 200 OK',
|
||||
' --',
|
||||
' route: {',
|
||||
' "name": "HeadAgentProbes",',
|
||||
' "version": false',
|
||||
' }'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
exec(_('%s %s/corpus/withreq.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
// Some past crashes from issues.
|
||||
test('should not crash on corpus/old-crashers/*.log', function (t) {
|
||||
var oldCrashers = fs.readdirSync(
|
||||
path.resolve(__dirname, 'corpus/old-crashers'))
|
||||
.filter(function (f) { return f.slice(-4) === '.log'; });
|
||||
vasync.forEachPipeline({
|
||||
inputs: oldCrashers,
|
||||
func: function (logName, next) {
|
||||
exec(_('%s %s/corpus/old-crashers/%s', BUNYAN, __dirname, logName),
|
||||
function (err, stdout, stderr) {
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
}, function (err, results) {
|
||||
t.ifError(err);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('should only show nonempty response bodies', function (t) {
|
||||
var expect = [
|
||||
/* BEGIN JSSTYLED */
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: UnauthorizedError',
|
||||
' HTTP/1.1 401 Unauthorized',
|
||||
' content-type: text/plain',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT',
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: hello',
|
||||
' HTTP/1.1 200 OK',
|
||||
' content-type: text/plain',
|
||||
' content-length: 0',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT',
|
||||
' ',
|
||||
' hello',
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: UnauthorizedError',
|
||||
' HTTP/1.1 401 Unauthorized',
|
||||
' content-type: text/plain',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT'
|
||||
/* END JSSTYLED */
|
||||
].join('\n') + '\n';
|
||||
exec(_('%s %s/corpus/content-length-0-res.log', BUNYAN, __dirname),
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, expect);
|
||||
t.end();
|
||||
});
|
||||
});
|
302
test/cli.test.mjs
Normal file
302
test/cli.test.mjs
Normal file
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `bunyan` CLI.
|
||||
*/
|
||||
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { exec, dirname } from './helper.mjs'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
|
||||
// ---- assertable variables
|
||||
|
||||
const catter = process.platform === 'win32' ? 'type' : 'cat'
|
||||
const assertSimpleLog = '[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message\n'
|
||||
|
||||
// ---- tests
|
||||
|
||||
t.test('--version', async function () {
|
||||
let pckg = JSON.parse(fs.readFileSync(dirname('/../package.json')))
|
||||
const version = pckg.version
|
||||
|
||||
let res = await exec('--version')
|
||||
assert.strictEqual(res.stdout, 'bunyan ' + version + '\n')
|
||||
});
|
||||
|
||||
t.test('--help', async function () {
|
||||
let res = await exec('--help')
|
||||
assert.match(res.stdout, /General options:/)
|
||||
});
|
||||
|
||||
t.test('-h', async function () {
|
||||
let res = await exec('-h')
|
||||
assert.match(res.stdout, /General options:/)
|
||||
});
|
||||
|
||||
t.test('--bogus', async function () {
|
||||
let err = await assert.isRejected(exec('--bogus'))
|
||||
assert.strictEqual(err.code, 1)
|
||||
});
|
||||
|
||||
t.test('simple.log', async function () {
|
||||
let res = await exec(dirname('/corpus/simple.log'))
|
||||
assert.strictEqual(res.stdout, assertSimpleLog)
|
||||
});
|
||||
|
||||
t.test(`${catter} simple.log`, async function () {
|
||||
let res = await exec('', `${catter} ${dirname('/corpus/simple.log')} | node `)
|
||||
assert.strictEqual(res.stdout, assertSimpleLog)
|
||||
});
|
||||
|
||||
t.test('time: simple.log utc long', async function () {
|
||||
let res = await exec('-o long --time utc ' + dirname('/corpus/simple.log'))
|
||||
assert.strictEqual(res.stdout, assertSimpleLog)
|
||||
});
|
||||
|
||||
t.test('time: simple.log utc short', async function () {
|
||||
let res = await exec('-o short ' + dirname('/corpus/simple.log'))
|
||||
assert.strictEqual(res.stdout, '22:56:52.856Z INFO myservice: My message\n')
|
||||
});
|
||||
|
||||
t.test('simple.log with color', async function () {
|
||||
let res = await exec(dirname('/corpus/simple.log'))
|
||||
assert.notMatch(res.stdout, /\[2012-02-08T22:56:52.856Z\] [^ ]+ INFO[^:]+:/)
|
||||
res = await exec('--color ' + dirname('/corpus/simple.log'))
|
||||
assert.match(res.stdout, /\[2012-02-08T22:56:52.856Z\] [^ ]+ INFO[^:]+:/)
|
||||
});
|
||||
|
||||
t.test('extrafield.log', async function () {
|
||||
let res = await exec(dirname('/corpus/extrafield.log'))
|
||||
assert.strictEqual(res.stdout, '[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message (extra=field)\n')
|
||||
});
|
||||
|
||||
t.test('extrafield.log with color', async function () {
|
||||
let res = await exec(dirname('/corpus/extrafield.log'))
|
||||
assert.notMatch(res.stdout, /My message[^ ]+ \(extra=field\)\n.+/)
|
||||
res = await exec('--color ' + dirname('/corpus/extrafield.log'))
|
||||
assert.match(res.stdout, /My message[^ ]+ \(extra=field\)\n.+/)
|
||||
});
|
||||
|
||||
t.test('bogus.log', async function () {
|
||||
let res = await exec(dirname('/corpus/bogus.log'))
|
||||
assert.strictEqual(res.stdout, 'not a JSON line\n{"hi": "there"}\n')
|
||||
});
|
||||
|
||||
t.test('bogus.log -j', async function () {
|
||||
let res = await exec('-j ' + dirname('/corpus/bogus.log'))
|
||||
assert.strictEqual(res.stdout, 'not a JSON line\n{"hi": "there"}\n')
|
||||
});
|
||||
|
||||
t.test('all.log', async function () {
|
||||
// Just make sure don't blow up on this.
|
||||
await exec(dirname('/corpus/all.log'))
|
||||
});
|
||||
|
||||
t.test('simple.log doesnotexist1.log doesnotexist2.log', async function () {
|
||||
let res = await assert.isRejected(exec(dirname('/corpus/simple.log') + ' doesnotexist1.log doesnotexist2.log'))
|
||||
assert.strictEqual(res.stdout, '[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message\n')
|
||||
|
||||
// Note: node v0.6.10:
|
||||
// ENOENT, no such file or directory 'asdf.log'
|
||||
// but node v0.6.14:
|
||||
// ENOENT, open 'asdf.log'
|
||||
// io.js 2.2 (at least):
|
||||
// ENOENT: no such file or directory, open 'doesnotexist1.log'
|
||||
let matches = [
|
||||
/^bunyan: ENOENT.*?, open '.+doesnotexist1.log'/m,
|
||||
/^bunyan: ENOENT.*?, open '.+doesnotexist2.log'/m,
|
||||
];
|
||||
matches.forEach(function (match) {
|
||||
assert.match(res.stderr, match);
|
||||
});
|
||||
});
|
||||
|
||||
t.test('multiple logs', async function () {
|
||||
let res = await exec(dirname('/corpus/log1.log') + ' ' + dirname('/corpus/log2.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T16:58:55.586Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:01:49.339Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:47.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:57.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:08:01.105Z] INFO: agent2/76156 on headnode: message\n',
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('multiple logs, bunyan format', async function () {
|
||||
let res = await exec('-o bunyan ' + dirname('/corpus/log1.log') + ' ' + dirname('/corpus/log2.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T16:57:55.586Z","v":0}\n',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T16:58:55.586Z","v":0}\n',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:01:49.339Z","v":0}\n',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:47.404Z","v":0}\n',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.339Z","v":0}\n',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.404Z","v":0}\n',
|
||||
'{"name":"agent1","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:49.404Z","v":0}\n',
|
||||
'{"name":"agent2","pid":73267,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:02:57.404Z","v":0}\n',
|
||||
'{"name":"agent2","pid":76156,"hostname":"headnode","level":30,"msg":"message","time":"2012-05-08T17:08:01.105Z","v":0}\n',
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('log1.log.gz', async function () {
|
||||
let res = await exec(dirname('/corpus/log1.log.gz'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('mixed text and gzip logs', async function () {
|
||||
let res = await exec(dirname('/corpus/log1.log.gz') + ' ' + dirname('/corpus/log2.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'[2012-05-08T16:57:55.586Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T16:58:55.586Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:01:49.339Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:47.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.339Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:49.404Z] INFO: agent1/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:02:57.404Z] INFO: agent2/73267 on headnode: message\n',
|
||||
'[2012-05-08T17:08:01.105Z] INFO: agent2/76156 on headnode: message\n',
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('--level 40', async function () {
|
||||
let res = await exec('-l 40 ' + dirname('/corpus/all.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'# levels\n',
|
||||
'[2012-02-08T22:56:53.856Z] WARN: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:54.856Z] ERROR: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:55.856Z] LVL55: myservice/123 on example.com: My message\n',
|
||||
'[2012-02-08T22:56:56.856Z] FATAL: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('--condition "this.level === 10 && this.pid === 123"', async function () {
|
||||
let res = await exec('-c "this.level === 10 && this.pid === 123" ' + dirname('/corpus/all.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'# levels\n',
|
||||
'[2012-02-08T22:56:50.856Z] TRACE: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('--condition "this.level === TRACE', async function () {
|
||||
let res = await exec('-c "this.level === TRACE" ' + dirname('/corpus/all.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'# levels\n',
|
||||
'[2012-02-08T22:56:50.856Z] TRACE: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join(''))
|
||||
});
|
||||
|
||||
t.test('multiple --conditions', async function () {
|
||||
let res = await exec(dirname('/corpus/all.log') + ' -c "this.level === 40" -c "this.pid === 123"')
|
||||
assert.strictEqual(res.stdout, [
|
||||
'# levels\n',
|
||||
'[2012-02-08T22:56:53.856Z] WARN: myservice/123 on example.com: My message\n',
|
||||
'\n',
|
||||
'# extra fields\n',
|
||||
'\n',
|
||||
'# bogus\n',
|
||||
'not a JSON line\n',
|
||||
'{"hi": "there"}\n'
|
||||
].join(''))
|
||||
});
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/30
|
||||
//
|
||||
// One of the records in corpus/withreq.log has a 'req'
|
||||
// field with no 'headers'. Ditto for the 'res' field.
|
||||
t.test('robust req handling', async function () {
|
||||
let res = await exec(dirname('/corpus/withreq.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'[2012-08-08T10:25:47.636Z] DEBUG: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: headAgentProbes respond (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, route=HeadAgentProbes, contentMD5=11FxOYiYfpMxmANj4kGJzg==)',
|
||||
'[2012-08-08T10:25:47.637Z] INFO: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: HeadAgentProbes handled: 200 (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, audit=true, remoteAddress=10.2.207.2, remotePort=50394, latency=3, secure=false, _audit=true, req.version=*)',
|
||||
' HEAD /agentprobes?agent=ccf92af9-0b24-46b6-ab60-65095fdd3037 HTTP/1.1',
|
||||
' accept: application/json',
|
||||
' content-type: application/json',
|
||||
' host: 10.2.207.16',
|
||||
' connection: keep-alive',
|
||||
' --',
|
||||
' HTTP/1.1 200 OK',
|
||||
' content-md5: 11FxOYiYfpMxmANj4kGJzg==',
|
||||
' access-control-allow-origin: *',
|
||||
' access-control-allow-headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version',
|
||||
' access-control-allow-methods: HEAD',
|
||||
' access-control-expose-headers: X-Api-Version, X-Request-Id, X-Response-Time',
|
||||
' connection: Keep-Alive',
|
||||
' date: Wed, 08 Aug 2012 10:25:47 GMT',
|
||||
' server: Amon Master/1.0.0',
|
||||
' x-request-id: cce79d15-ffc2-487c-a4e4-e940bdaac31e',
|
||||
' x-response-time: 3',
|
||||
' --',
|
||||
' route: {',
|
||||
' "name": "HeadAgentProbes",',
|
||||
' "version": false',
|
||||
' }',
|
||||
'[2012-08-08T10:25:47.637Z] INFO: amon-master/12859 on 9724a190-27b6-4fd8-830b-a574f839c67d: HeadAgentProbes handled: 200 (req_id=cce79d15-ffc2-487c-a4e4-e940bdaac31e, audit=true, remoteAddress=10.2.207.2, remotePort=50394, latency=3, secure=false, _audit=true, req.version=*)',
|
||||
' HEAD /agentprobes?agent=ccf92af9-0b24-46b6-ab60-65095fdd3037 HTTP/1.1',
|
||||
' --',
|
||||
' HTTP/1.1 200 OK',
|
||||
' --',
|
||||
' route: {',
|
||||
' "name": "HeadAgentProbes",',
|
||||
' "version": false',
|
||||
' }'
|
||||
].join('\n') + '\n')
|
||||
});
|
||||
|
||||
// Some past crashes from issues.
|
||||
t.test('should not crash on corpus/old-crashers/*.log', async function () {
|
||||
let oldCrashers = fs.readdirSync(
|
||||
path.resolve(dirname('/corpus/old-crashers')))
|
||||
.filter(function (f) { return f.slice(-4) === '.log'; });
|
||||
|
||||
await Promise.all(oldCrashers.map(function(logFile) {
|
||||
return exec(dirname('/corpus/old-crashers/' + logFile))
|
||||
}))
|
||||
});
|
||||
|
||||
t.test('should only show nonempty response bodies', async function () {
|
||||
let res = await exec(dirname('/corpus/content-length-0-res.log'))
|
||||
assert.strictEqual(res.stdout, [
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: UnauthorizedError',
|
||||
' HTTP/1.1 401 Unauthorized',
|
||||
' content-type: text/plain',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT',
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: hello',
|
||||
' HTTP/1.1 200 OK',
|
||||
' content-type: text/plain',
|
||||
' content-length: 0',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT',
|
||||
' ',
|
||||
' hello',
|
||||
'[2016-02-10T07:28:41.419Z] INFO: myservice/123 on example.com: UnauthorizedError',
|
||||
' HTTP/1.1 401 Unauthorized',
|
||||
' content-type: text/plain',
|
||||
' date: Sat, 07 Mar 2015 06:58:43 GMT'
|
||||
].join('\n') + '\n');
|
||||
});
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test type checking on creation of the Logger.
|
||||
*/
|
||||
|
||||
var bunyan = require('../lib/bunyan'),
|
||||
Logger = bunyan;
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
|
||||
test('ensure Logger creation options', function (t) {
|
||||
t.throws(function () { new Logger(); },
|
||||
/options \(object\) is required/,
|
||||
'no options should throw');
|
||||
|
||||
t.throws(function () { new Logger({}); },
|
||||
/options\.name \(string\) is required/,
|
||||
'no options.name should throw');
|
||||
|
||||
t.doesNotThrow(function () { new Logger({name: 'foo'}); },
|
||||
'just options.name should be sufficient');
|
||||
|
||||
var options = {name: 'foo', stream: process.stdout, streams: []};
|
||||
t.throws(function () { new Logger(options); },
|
||||
/* JSSTYLED */
|
||||
/cannot mix "streams" and "stream" options/,
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {name: 'foo', streams: {}};
|
||||
t.throws(function () { new Logger(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {name: 'foo', serializers: 'a string'};
|
||||
t.throws(function () { new Logger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {name: 'foo', serializers: [1, 2, 3]};
|
||||
t.throws(function () { new Logger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('ensure Logger constructor is safe without new', function (t) {
|
||||
t.doesNotThrow(function () { Logger({name: 'foo'}); },
|
||||
'constructor should call self with new if necessary');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('ensure Logger creation options (createLogger)', function (t) {
|
||||
t.throws(function () { bunyan.createLogger(); },
|
||||
/options \(object\) is required/,
|
||||
'no options should throw');
|
||||
|
||||
t.throws(function () { bunyan.createLogger({}); },
|
||||
/options\.name \(string\) is required/,
|
||||
'no options.name should throw');
|
||||
|
||||
t.doesNotThrow(function () { bunyan.createLogger({name: 'foo'}); },
|
||||
'just options.name should be sufficient');
|
||||
|
||||
var options = {name: 'foo', stream: process.stdout, streams: []};
|
||||
t.throws(function () { bunyan.createLogger(options); },
|
||||
/* JSSTYLED */
|
||||
/cannot mix "streams" and "stream" options/,
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {name: 'foo', streams: {}};
|
||||
t.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {name: 'foo', serializers: 'a string'};
|
||||
t.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {name: 'foo', serializers: [1, 2, 3]};
|
||||
t.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('ensure Logger child() options', function (t) {
|
||||
var log = new Logger({name: 'foo'});
|
||||
|
||||
t.doesNotThrow(function () { log.child(); },
|
||||
'no options should be fine');
|
||||
|
||||
t.doesNotThrow(function () { log.child({}); },
|
||||
'empty options should be fine too');
|
||||
|
||||
t.throws(function () { log.child({name: 'foo'}); },
|
||||
/invalid options.name: child cannot set logger name/,
|
||||
'child cannot change name');
|
||||
|
||||
var options = {stream: process.stdout, streams: []};
|
||||
t.throws(function () { log.child(options); },
|
||||
/* JSSTYLED */
|
||||
/cannot mix "streams" and "stream" options/,
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {streams: {}};
|
||||
t.throws(function () { log.child(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {serializers: 'a string'};
|
||||
t.throws(function () { log.child(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {serializers: [1, 2, 3]};
|
||||
t.throws(function () { log.child(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('ensure Logger() rejects non-Logger parents', function (t) {
|
||||
var dad = new Logger({name: 'dad', streams: []});
|
||||
|
||||
t.throws(function () { new Logger({}, {}); },
|
||||
/invalid Logger creation: do not pass a second arg/,
|
||||
'Logger arguments must be valid');
|
||||
|
||||
t.doesNotThrow(function () { new Logger(dad, {}); },
|
||||
'Logger allows Logger instance as parent');
|
||||
|
||||
t.end();
|
||||
});
|
124
test/ctor.test.mjs
Normal file
124
test/ctor.test.mjs
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test type checking on creation of the Logger.
|
||||
*/
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
t.test('ensure Logger creation options', function () {
|
||||
assert.throws(function () { new bunyan(); },
|
||||
/options \(object\) is required/,
|
||||
'no options should throw');
|
||||
|
||||
assert.throws(function () { new bunyan({}); },
|
||||
/options\.name \(string\) is required/,
|
||||
'no options.name should throw');
|
||||
|
||||
new bunyan({name: 'foo'});
|
||||
|
||||
let options = {name: 'foo', stream: process.stdout, streams: []};
|
||||
assert.throws(function () { new bunyan(options); },
|
||||
/cannot mix "streams" and "stream" options/, // JSSTYLED
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {name: 'foo', streams: {}};
|
||||
assert.throws(function () { new bunyan(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {name: 'foo', serializers: 'a string'};
|
||||
assert.throws(function () { new bunyan(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {name: 'foo', serializers: [1, 2, 3]};
|
||||
assert.throws(function () { new bunyan(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
});
|
||||
|
||||
|
||||
t.test('ensure Logger constructor is safe without new', function () {
|
||||
bunyan({name: 'foo'})
|
||||
});
|
||||
|
||||
|
||||
t.test('ensure Logger creation options (createLogger)', function () {
|
||||
assert.throws(function () { bunyan.createLogger(); },
|
||||
/options \(object\) is required/,
|
||||
'no options should throw');
|
||||
|
||||
assert.throws(function () { bunyan.createLogger({}); },
|
||||
/options\.name \(string\) is required/,
|
||||
'no options.name should throw');
|
||||
|
||||
bunyan.createLogger({name: 'foo'});
|
||||
|
||||
let options = {name: 'foo', stream: process.stdout, streams: []};
|
||||
assert.throws(function () { bunyan.createLogger(options); },
|
||||
/cannot mix "streams" and "stream" options/, // JSSTYLED
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {name: 'foo', streams: {}};
|
||||
assert.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {name: 'foo', serializers: 'a string'};
|
||||
assert.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {name: 'foo', serializers: [1, 2, 3]};
|
||||
assert.throws(function () { bunyan.createLogger(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
});
|
||||
|
||||
|
||||
t.test('ensure Logger child() options', function () {
|
||||
let log = new bunyan({name: 'foo'});
|
||||
|
||||
log.child();
|
||||
|
||||
log.child({});
|
||||
|
||||
assert.throws(function () { log.child({name: 'foo'}); },
|
||||
/invalid options.name: child cannot set logger name/,
|
||||
'child cannot change name');
|
||||
|
||||
let options = {stream: process.stdout, streams: []};
|
||||
assert.throws(function () { log.child(options); },
|
||||
/cannot mix "streams" and "stream" options/, // JSSTYLED
|
||||
'cannot use "stream" and "streams"');
|
||||
|
||||
// https://github.com/trentm/node-bunyan/issues/3
|
||||
options = {streams: {}};
|
||||
assert.throws(function () { log.child(options); },
|
||||
/invalid options.streams: must be an array/,
|
||||
'"streams" must be an array');
|
||||
|
||||
options = {serializers: 'a string'};
|
||||
assert.throws(function () { log.child(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be a string');
|
||||
|
||||
options = {serializers: [1, 2, 3]};
|
||||
assert.throws(function () { log.child(options); },
|
||||
/invalid options.serializers: must be an object/,
|
||||
'"serializers" cannot be an array');
|
||||
});
|
||||
|
||||
|
||||
t.test('ensure Logger() rejects non-Logger parents', function () {
|
||||
let dad = new bunyan({name: 'dad', streams: []});
|
||||
|
||||
assert.throws(function () { new bunyan({}, {}); },
|
||||
/invalid Logger creation: do not pass a second arg/,
|
||||
'Logger arguments must be valid');
|
||||
|
||||
new bunyan(dad, {});
|
||||
});
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Make sure cycles are safe.
|
||||
*/
|
||||
|
||||
var Logger = require('../lib/bunyan.js');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
var Stream = require('stream').Stream;
|
||||
var outstr = new Stream;
|
||||
outstr.writable = true;
|
||||
var output = [];
|
||||
outstr.write = function (c) {
|
||||
output.push(JSON.parse(c + ''));
|
||||
};
|
||||
outstr.end = function (c) {
|
||||
if (c) this.write(c);
|
||||
this.emit('end');
|
||||
};
|
||||
|
||||
// these are lacking a few fields that will probably never match
|
||||
var expect =
|
||||
[
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'msg': 'bango { bang: \'boom\', KABOOM: [Circular] }',
|
||||
'v': 0
|
||||
},
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'msg': 'kaboom { bang: \'boom\', KABOOM: [Circular] }',
|
||||
'v': 0
|
||||
},
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'bang': 'boom',
|
||||
'KABOOM': {
|
||||
'bang': 'boom',
|
||||
'KABOOM': '[Circular]'
|
||||
},
|
||||
'msg': '',
|
||||
'v': 0
|
||||
}
|
||||
];
|
||||
|
||||
var log = new Logger({
|
||||
name: 'blammo',
|
||||
streams: [
|
||||
{
|
||||
type: 'stream',
|
||||
level: 'info',
|
||||
stream: outstr
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
test('cycles', function (t) {
|
||||
outstr.on('end', function () {
|
||||
output.forEach(function (o, i) {
|
||||
// Drop variable parts for comparison.
|
||||
delete o.hostname;
|
||||
delete o.pid;
|
||||
delete o.time;
|
||||
// Hack object/dict comparison: JSONify.
|
||||
t.equal(JSON.stringify(o), JSON.stringify(expect[i]),
|
||||
'log item ' + i + ' matches');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
var obj = { bang: 'boom' };
|
||||
obj.KABOOM = obj;
|
||||
log.info('bango', obj);
|
||||
log.info('kaboom', obj.KABOOM);
|
||||
log.info(obj);
|
||||
outstr.end();
|
||||
t.ok('did not throw');
|
||||
});
|
83
test/cycles.test.mjs
Normal file
83
test/cycles.test.mjs
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Make sure cycles are safe.
|
||||
*/
|
||||
|
||||
import { Stream } from 'stream'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import Logger from '../lib/bunyan.mjs'
|
||||
|
||||
var outstr = new Stream;
|
||||
outstr.writable = true;
|
||||
var output = [];
|
||||
outstr.write = function (c) {
|
||||
output.push(JSON.parse(c + ''));
|
||||
};
|
||||
outstr.end = function (c) {
|
||||
if (c) this.write(c);
|
||||
this.emit('end');
|
||||
};
|
||||
|
||||
// these are lacking a few fields that will probably never match
|
||||
var expect = [
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'msg': 'bango <ref *1> { bang: \'boom\', KABOOM: [Circular *1] }',
|
||||
'v': 0
|
||||
},
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'msg': 'kaboom <ref *1> { bang: \'boom\', KABOOM: [Circular *1] }',
|
||||
'v': 0
|
||||
},
|
||||
{
|
||||
'name': 'blammo',
|
||||
'level': 30,
|
||||
'bang': 'boom',
|
||||
'KABOOM': {
|
||||
'bang': 'boom',
|
||||
'KABOOM': '[Circular]'
|
||||
},
|
||||
'msg': '',
|
||||
'v': 0
|
||||
}
|
||||
];
|
||||
|
||||
var log = new Logger({
|
||||
name: 'blammo',
|
||||
streams: [
|
||||
{
|
||||
type: 'stream',
|
||||
level: 'info',
|
||||
stream: outstr
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
t.test('cycles', function (cb) {
|
||||
outstr.on('end', function () {
|
||||
output.forEach(function (o, i) {
|
||||
// Drop variable parts for comparison.
|
||||
delete o.hostname;
|
||||
delete o.pid;
|
||||
delete o.time;
|
||||
// Hack object/dict comparison: JSONify.
|
||||
try {
|
||||
assert.strictEqual(JSON.stringify(o), JSON.stringify(expect[i]))
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
cb()
|
||||
});
|
||||
|
||||
var obj = { bang: 'boom' };
|
||||
obj.KABOOM = obj;
|
||||
log.info('bango', obj);
|
||||
log.info('kaboom', obj.KABOOM);
|
||||
log.info(obj);
|
||||
outstr.end();
|
||||
});
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 Trent Mick
|
||||
*
|
||||
* Test emission and handling of 'error' event in a logger with a 'path'
|
||||
* stream.
|
||||
*/
|
||||
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('util');
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
var BOGUS_PATH = '/this/path/is/bogus.log';
|
||||
|
||||
test('error event on file stream (reemitErrorEvents=undefined)', function (t) {
|
||||
var log = bunyan.createLogger(
|
||||
{name: 'error-event-1', streams: [ {path: BOGUS_PATH} ]});
|
||||
log.on('error', function (err, stream) {
|
||||
t.ok(err, 'got err in error event: ' + err);
|
||||
t.equal(err.code, 'ENOENT', 'error code is ENOENT');
|
||||
t.ok(stream, 'got a stream argument');
|
||||
t.equal(stream.path, BOGUS_PATH);
|
||||
t.equal(stream.type, 'file');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
test('error event on file stream (reemitErrorEvents=true)', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-2',
|
||||
streams: [ {
|
||||
path: BOGUS_PATH,
|
||||
reemitErrorEvents: true
|
||||
} ]
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
t.ok(err, 'got err in error event: ' + err);
|
||||
t.equal(err.code, 'ENOENT', 'error code is ENOENT');
|
||||
t.ok(stream, 'got a stream argument');
|
||||
t.equal(stream.path, BOGUS_PATH);
|
||||
t.equal(stream.type, 'file');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
test('error event on file stream (reemitErrorEvents=false)',
|
||||
function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-3',
|
||||
streams: [ {
|
||||
path: BOGUS_PATH,
|
||||
reemitErrorEvents: false
|
||||
} ]
|
||||
});
|
||||
// Hack into the underlying created file stream to catch the error event.
|
||||
log.streams[0].stream.on('error', function (err) {
|
||||
t.ok(err, 'got error event on the file stream');
|
||||
t.end();
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
t.fail('should not have gotten error event on logger');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
|
||||
function MyErroringStream() {}
|
||||
util.inherits(MyErroringStream, EventEmitter);
|
||||
MyErroringStream.prototype.write = function (rec) {
|
||||
this.emit('error', new Error('boom'));
|
||||
}
|
||||
|
||||
test('error event on raw stream (reemitErrorEvents=undefined)', function (t) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
estream.on('error', function (err) {
|
||||
t.ok(err, 'got error event on the raw stream');
|
||||
t.end();
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
t.fail('should not have gotten error event on logger');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
test('error event on raw stream (reemitErrorEvents=false)', function (t) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw',
|
||||
reemitErrorEvents: false
|
||||
}
|
||||
]
|
||||
});
|
||||
estream.on('error', function (err) {
|
||||
t.ok(err, 'got error event on the raw stream');
|
||||
t.end();
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
t.fail('should not have gotten error event on logger');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
test('error event on raw stream (reemitErrorEvents=true)', function (t) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw',
|
||||
reemitErrorEvents: true
|
||||
}
|
||||
]
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
t.ok(err, 'got err in error event: ' + err);
|
||||
t.equal(err.message, 'boom');
|
||||
t.ok(stream, 'got a stream argument');
|
||||
t.ok(stream.stream instanceof MyErroringStream);
|
||||
t.equal(stream.type, 'raw');
|
||||
t.end();
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
164
test/error-event.test.mjs
Normal file
164
test/error-event.test.mjs
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright 2016 Trent Mick
|
||||
*
|
||||
* Test emission and handling of 'error' event in a logger with a 'path'
|
||||
* stream.
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'events'
|
||||
import util from 'util'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
|
||||
var BOGUS_PATH = '/this/path/is/bogus.log';
|
||||
|
||||
t.test('error event on file stream (reemitErrorEvents=undefined)', function (cb) {
|
||||
var log = bunyan.createLogger(
|
||||
{name: 'error-event-1', streams: [ {path: BOGUS_PATH} ]});
|
||||
log.on('error', function (err, stream) {
|
||||
try {
|
||||
assert.ok(err, 'got err in error event: ' + err);
|
||||
assert.strictEqual(err.code, 'ENOENT', 'error code is ENOENT');
|
||||
assert.ok(stream, 'got a stream argument');
|
||||
assert.strictEqual(stream.path, BOGUS_PATH);
|
||||
assert.strictEqual(stream.type, 'file');
|
||||
cb()
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
t.test('error event on file stream (reemitErrorEvents=true)', function (cb) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-2',
|
||||
streams: [ {
|
||||
path: BOGUS_PATH,
|
||||
reemitErrorEvents: true
|
||||
} ]
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
try {
|
||||
assert.ok(err, 'got err in error event: ' + err);
|
||||
assert.strictEqual(err.code, 'ENOENT', 'error code is ENOENT');
|
||||
assert.ok(stream, 'got a stream argument');
|
||||
assert.strictEqual(stream.path, BOGUS_PATH);
|
||||
assert.strictEqual(stream.type, 'file');
|
||||
cb()
|
||||
} catch(err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
t.test('error event on file stream (reemitErrorEvents=false)',
|
||||
function (cb) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-3',
|
||||
streams: [ {
|
||||
path: BOGUS_PATH,
|
||||
reemitErrorEvents: false
|
||||
} ]
|
||||
});
|
||||
// Hack into the underlying created file stream to catch the error event.
|
||||
log.streams[0].stream.on('error', function (err) {
|
||||
try {
|
||||
assert.ok(err, 'got error event on the file stream');
|
||||
cb()
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
cb('should not have gotten error event on logger')
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
|
||||
function MyErroringStream() {}
|
||||
util.inherits(MyErroringStream, EventEmitter);
|
||||
MyErroringStream.prototype.write = function (rec) {
|
||||
this.emit('error', new Error('boom'));
|
||||
}
|
||||
|
||||
t.test('error event on raw stream (reemitErrorEvents=undefined)', function (cb) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
estream.on('error', function (err) {
|
||||
try {
|
||||
assert.ok(err, 'got error event on the raw stream');
|
||||
cb()
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
cb('should not have gotten error event on logger');
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
t.test('error event on raw stream (reemitErrorEvents=false)', function (cb) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw',
|
||||
reemitErrorEvents: false
|
||||
}
|
||||
]
|
||||
});
|
||||
estream.on('error', function (err) {
|
||||
try {
|
||||
assert.ok(err, 'got error event on the raw stream');
|
||||
cb()
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
cb('should not have gotten error event on logger');
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
||||
|
||||
t.test('error event on raw stream (reemitErrorEvents=true)', function (cb) {
|
||||
var estream = new MyErroringStream();
|
||||
var log = bunyan.createLogger({
|
||||
name: 'error-event-raw',
|
||||
streams: [
|
||||
{
|
||||
stream: estream,
|
||||
type: 'raw',
|
||||
reemitErrorEvents: true
|
||||
}
|
||||
]
|
||||
});
|
||||
log.on('error', function (err, stream) {
|
||||
try {
|
||||
assert.ok(err, 'got err in error event: ' + err);
|
||||
assert.strictEqual(err.message, 'boom');
|
||||
assert.ok(stream, 'got a stream argument');
|
||||
assert.ok(stream.stream instanceof MyErroringStream);
|
||||
assert.strictEqual(stream.type, 'raw');
|
||||
cb()
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
});
|
||||
log.info('info log message');
|
||||
});
|
29
test/helper.mjs
Normal file
29
test/helper.mjs
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { exec as ex } from 'child_process'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
let __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
var BUNYAN = path.resolve(__dirname, '../bin/bunyan.mjs');
|
||||
|
||||
export function exec(parameter, prefix = 'node', bunnyboy = BUNYAN) {
|
||||
let command = `${prefix} ${bunnyboy} ${parameter}`
|
||||
return new Promise(function(res, rej) {
|
||||
ex(command,
|
||||
function (err, stdout, stderr) {
|
||||
if (err) {
|
||||
err.stdout = stdout
|
||||
err.stderr = stderr
|
||||
return rej(err)
|
||||
}
|
||||
res({
|
||||
stdout,
|
||||
stderr,
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export function dirname(file) {
|
||||
return path.resolve(__dirname + file)
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `log.level(...)`.
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
format = util.format,
|
||||
inspect = util.inspect;
|
||||
var p = console.log;
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- test boolean `log.<level>()` calls
|
||||
|
||||
var log1 = bunyan.createLogger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
path: __dirname + '/level.test.log1.log',
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
test('log.level() -> level num', function (t) {
|
||||
t.equal(log1.level(), bunyan.INFO);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.level(<const>)', function (t) {
|
||||
log1.level(bunyan.DEBUG);
|
||||
t.equal(log1.level(), bunyan.DEBUG);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.level(<num>)', function (t) {
|
||||
log1.level(10);
|
||||
t.equal(log1.level(), bunyan.TRACE);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.level(<name>)', function (t) {
|
||||
log1.level('error');
|
||||
t.equal(log1.level(), bunyan.ERROR);
|
||||
t.end();
|
||||
});
|
||||
|
||||
// A trick to turn logging off.
|
||||
// See <https://github.com/trentm/node-bunyan/pull/148#issuecomment-53232979>.
|
||||
test('log.level(FATAL + 1)', function (t) {
|
||||
log1.level(bunyan.FATAL + 1);
|
||||
t.equal(log1.level(), bunyan.FATAL + 1);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.level(<weird numbers>)', function (t) {
|
||||
log1.level(0);
|
||||
t.equal(log1.level(), 0);
|
||||
log1.level(Number.MAX_VALUE);
|
||||
t.equal(log1.level(), Number.MAX_VALUE);
|
||||
log1.level(Infinity);
|
||||
t.equal(log1.level(), Infinity);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.level(<invalid values>)', function (t) {
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: 'booga'});
|
||||
// JSSTYLED
|
||||
}, /unknown level name: "booga"/);
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: []});
|
||||
}, /cannot resolve level: invalid arg \(object\): \[\]/);
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: true});
|
||||
}, /cannot resolve level: invalid arg \(boolean\): true/);
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: -1});
|
||||
}, /level is not a positive integer: -1/);
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: 3.14});
|
||||
}, /level is not a positive integer: 3.14/);
|
||||
t.throws(function () {
|
||||
var log = bunyan.createLogger({name: 'invalid', level: -Infinity});
|
||||
}, /level is not a positive integer: -Infinity/);
|
||||
t.end();
|
||||
});
|
79
test/level.test.mjs
Normal file
79
test/level.test.mjs
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `log.level(...)`.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
import { dirname } from './helper.mjs'
|
||||
|
||||
|
||||
// ---- test boolean `log.<level>()` calls
|
||||
|
||||
var log1 = bunyan.createLogger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
level: 'info',
|
||||
stream: process.stdout,
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
t.test('log.level() -> level num', function () {
|
||||
assert.strictEqual(log1.level(), bunyan.INFO);
|
||||
});
|
||||
|
||||
t.test('log.level(<const>)', function () {
|
||||
log1.level(bunyan.DEBUG);
|
||||
assert.strictEqual(log1.level(), bunyan.DEBUG);
|
||||
});
|
||||
|
||||
t.test('log.level(<num>)', function () {
|
||||
log1.level(10);
|
||||
assert.strictEqual(log1.level(), bunyan.TRACE);
|
||||
});
|
||||
|
||||
t.test('log.level(<name>)', function () {
|
||||
log1.level('error');
|
||||
assert.strictEqual(log1.level(), bunyan.ERROR);
|
||||
});
|
||||
|
||||
// A trick to turn logging off.
|
||||
// See <https://github.com/trentm/node-bunyan/pull/148#issuecomment-53232979>.
|
||||
t.test('log.level(FATAL + 1)', function () {
|
||||
log1.level(bunyan.FATAL + 1);
|
||||
assert.strictEqual(log1.level(), bunyan.FATAL + 1);
|
||||
});
|
||||
|
||||
t.test('log.level(<weird numbers>)', function () {
|
||||
log1.level(0);
|
||||
assert.strictEqual(log1.level(), 0);
|
||||
log1.level(Number.MAX_VALUE);
|
||||
assert.strictEqual(log1.level(), Number.MAX_VALUE);
|
||||
log1.level(Infinity);
|
||||
assert.strictEqual(log1.level(), Infinity);
|
||||
});
|
||||
|
||||
t.test('log.level(<invalid values>)', function () {
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: 'booga'});
|
||||
}, /unknown level name: "booga"/);
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: []});
|
||||
}, /cannot resolve level: invalid arg \(object\): \[\]/);
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: true});
|
||||
}, /cannot resolve level: invalid arg \(boolean\): true/);
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: -1});
|
||||
}, /level is not a positive integer: -1/);
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: 3.14});
|
||||
}, /level is not a positive integer: 3.14/);
|
||||
assert.throws(function () {
|
||||
bunyan.createLogger({name: 'invalid', level: -Infinity});
|
||||
}, /level is not a positive integer: -Infinity/);
|
||||
});
|
271
test/log.test.js
271
test/log.test.js
|
@ -1,271 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `log.trace(...)`, `log.debug(...)`, ..., `log.fatal(...)` API.
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
format = util.format,
|
||||
inspect = util.inspect;
|
||||
var p = console.log;
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- test boolean `log.<level>()` calls
|
||||
|
||||
var log1 = bunyan.createLogger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
path: __dirname + '/log.test.log1.log',
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var log2 = bunyan.createLogger({
|
||||
name: 'log2',
|
||||
streams: [
|
||||
{
|
||||
path: __dirname + '/log.test.log2a.log',
|
||||
level: 'error'
|
||||
},
|
||||
{
|
||||
path: __dirname + '/log.test.log2b.log',
|
||||
level: 'debug'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
test('log.LEVEL() -> boolean', function (t) {
|
||||
t.equal(log1.trace(), false, 'log1.trace() is false')
|
||||
t.equal(log1.debug(), false)
|
||||
t.equal(log1.info(), true)
|
||||
t.equal(log1.warn(), true)
|
||||
t.equal(log1.error(), true)
|
||||
t.equal(log1.fatal(), true)
|
||||
|
||||
// Level is the *lowest* level of all streams.
|
||||
t.equal(log2.trace(), false)
|
||||
t.equal(log2.debug(), true)
|
||||
t.equal(log2.info(), true)
|
||||
t.equal(log2.warn(), true)
|
||||
t.equal(log2.error(), true)
|
||||
t.equal(log2.fatal(), true)
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
// ---- test `log.<level>(...)` calls which various input types
|
||||
|
||||
function Catcher() {
|
||||
this.records = [];
|
||||
}
|
||||
Catcher.prototype.write = function (record) {
|
||||
this.records.push(record);
|
||||
}
|
||||
var catcher = new Catcher();
|
||||
var log3 = new bunyan.createLogger({
|
||||
name: 'log3',
|
||||
streams: [
|
||||
{
|
||||
type: 'raw',
|
||||
stream: catcher,
|
||||
level: 'trace'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var names = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
|
||||
var fields = {one: 'un'};
|
||||
|
||||
test('log.info(undefined, <msg>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, undefined, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'undefined \'some message\'',
|
||||
format('log.%s msg is "some message"', lvl));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, undefined)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, undefined);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'undefined',
|
||||
format('log.%s msg: expect "undefined", got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(null, <msg>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, null, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'some message',
|
||||
format('log.%s msg is "some message"', lvl));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, null)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, null);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'null',
|
||||
format('log.%s msg: expect "null", got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<str>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'some message',
|
||||
format('log.%s msg is "some message"', lvl));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, <str>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'some message',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<bool>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, true);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'true',
|
||||
format('log.%s msg is "true"', lvl));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, <bool>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, true);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'true',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<num>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, 3.14);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, '3.14',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, <num>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, 3.14);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, '3.14',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<function>)', function (t) {
|
||||
var func = function func1() {};
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, func);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, '[Function: func1]',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, <function>)', function (t) {
|
||||
var func = function func2() {};
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, func);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, '[Function: func2]',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<array>)', function (t) {
|
||||
var arr = ['a', 1, {two: 'deux'}];
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, arr);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, format(arr),
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(<fields>, <array>)', function (t) {
|
||||
var arr = ['a', 1, {two: 'deux'}];
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, fields, arr);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, format(arr),
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
t.equal(rec.one, 'un');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* By accident (starting with trentm/node-bunyan#85 in bunyan@0.23.0),
|
||||
* log.info(null, ...)
|
||||
* was interpreted as `null` being the object of fields. It is gracefully
|
||||
* handled, which is good. However, had I to do it again, I would have made
|
||||
* that interpret `null` as the *message*, and no fields having been passed.
|
||||
* I think it is baked now. It would take a major bunyan rev to change it,
|
||||
* but I don't think it is worth it: passing `null` as the first arg isn't
|
||||
* really an intended way to call these Bunyan methods for either case.
|
||||
*/
|
||||
|
||||
test('log.info(null)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, null);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, '', format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('log.info(null, <msg>)', function (t) {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl].call(log3, null, 'my message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
t.equal(rec.msg, 'my message',
|
||||
format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
t.end();
|
||||
});
|
227
test/log.test.mjs
Normal file
227
test/log.test.mjs
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the `log.trace(...)`, `log.debug(...)`, ..., `log.fatal(...)` API.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import { format } from 'util'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
// ---- test boolean `log.<level>()` calls
|
||||
|
||||
var log1 = bunyan.createLogger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var log2 = bunyan.createLogger({
|
||||
name: 'log2',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
level: 'error'
|
||||
},
|
||||
{
|
||||
stream: process.stdout,
|
||||
level: 'debug'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
t.test('log.LEVEL() -> boolean', function () {
|
||||
assert.strictEqual(log1.trace(), false, 'log1.trace() is false')
|
||||
assert.strictEqual(log1.debug(), false)
|
||||
assert.strictEqual(log1.info(), true)
|
||||
assert.strictEqual(log1.warn(), true)
|
||||
assert.strictEqual(log1.error(), true)
|
||||
assert.strictEqual(log1.fatal(), true)
|
||||
|
||||
// Level is the *lowest* level of all streams.
|
||||
assert.strictEqual(log2.trace(), false)
|
||||
assert.strictEqual(log2.debug(), true)
|
||||
assert.strictEqual(log2.info(), true)
|
||||
assert.strictEqual(log2.warn(), true)
|
||||
assert.strictEqual(log2.error(), true)
|
||||
assert.strictEqual(log2.fatal(), true)
|
||||
});
|
||||
|
||||
|
||||
// ---- test `log.<level>(...)` calls which various input types
|
||||
|
||||
function Catcher() {
|
||||
this.records = [];
|
||||
}
|
||||
Catcher.prototype.write = function (record) {
|
||||
this.records.push(record);
|
||||
}
|
||||
var catcher = new Catcher();
|
||||
var log3 = new bunyan.createLogger({
|
||||
name: 'log3',
|
||||
streams: [
|
||||
{
|
||||
type: 'raw',
|
||||
stream: catcher,
|
||||
level: 'trace'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var names = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
|
||||
var fields = {one: 'un'};
|
||||
|
||||
t.test('log.info(undefined, <msg>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](undefined, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'undefined some message');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, undefined)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, undefined);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'undefined');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(null, <msg>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](null, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'some message');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, null)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, null);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'null');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<str>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl]('some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'some message');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, <str>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, 'some message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'some message');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<bool>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](true);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'true');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, <bool>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, true);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'true');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<num>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](3.14);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, '3.14');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, <num>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, 3.14);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, '3.14');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<function>)', function () {
|
||||
var func = function func1() {};
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](func);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, '[Function: func1]');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, <function>)', function () {
|
||||
var func = function func2() {};
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, func);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, '[Function: func2]');
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<array>)', function () {
|
||||
var arr = ['a', 1, {two: 'deux'}];
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](arr);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, format(arr));
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(<fields>, <array>)', function () {
|
||||
var arr = ['a', 1, {two: 'deux'}];
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](fields, arr);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, format(arr));
|
||||
assert.strictEqual(rec.one, 'un');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* By accident (starting with trentm/node-bunyan#85 in bunyan@0.23.0),
|
||||
* log.info(null, ...)
|
||||
* was interpreted as `null` being the object of fields. It is gracefully
|
||||
* handled, which is good. However, had I to do it again, I would have made
|
||||
* that interpret `null` as the *message*, and no fields having been passed.
|
||||
* I think it is baked now. It would take a major bunyan rev to change it,
|
||||
* but I don't think it is worth it: passing `null` as the first arg isn't
|
||||
* really an intended way to call these Bunyan methods for either case.
|
||||
*/
|
||||
|
||||
t.test('log.info(null)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](null);
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, '', format('log.%s msg: got %j', lvl, rec.msg));
|
||||
});
|
||||
});
|
||||
|
||||
t.test('log.info(null, <msg>)', function () {
|
||||
names.forEach(function (lvl) {
|
||||
log3[lvl](null, 'my message');
|
||||
var rec = catcher.records[catcher.records.length - 1];
|
||||
assert.strictEqual(rec.msg, 'my message');
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test other parts of the exported API.
|
||||
*/
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
test('bunyan.<LEVEL>s', function (t) {
|
||||
t.ok(bunyan.TRACE, 'TRACE');
|
||||
t.ok(bunyan.DEBUG, 'DEBUG');
|
||||
t.ok(bunyan.INFO, 'INFO');
|
||||
t.ok(bunyan.WARN, 'WARN');
|
||||
t.ok(bunyan.ERROR, 'ERROR');
|
||||
t.ok(bunyan.FATAL, 'FATAL');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('bunyan.resolveLevel()', function (t) {
|
||||
t.equal(bunyan.resolveLevel('trace'), bunyan.TRACE, 'TRACE');
|
||||
t.equal(bunyan.resolveLevel('TRACE'), bunyan.TRACE, 'TRACE');
|
||||
t.equal(bunyan.resolveLevel('debug'), bunyan.DEBUG, 'DEBUG');
|
||||
t.equal(bunyan.resolveLevel('DEBUG'), bunyan.DEBUG, 'DEBUG');
|
||||
t.equal(bunyan.resolveLevel('info'), bunyan.INFO, 'INFO');
|
||||
t.equal(bunyan.resolveLevel('INFO'), bunyan.INFO, 'INFO');
|
||||
t.equal(bunyan.resolveLevel('warn'), bunyan.WARN, 'WARN');
|
||||
t.equal(bunyan.resolveLevel('WARN'), bunyan.WARN, 'WARN');
|
||||
t.equal(bunyan.resolveLevel('error'), bunyan.ERROR, 'ERROR');
|
||||
t.equal(bunyan.resolveLevel('ERROR'), bunyan.ERROR, 'ERROR');
|
||||
t.equal(bunyan.resolveLevel('fatal'), bunyan.FATAL, 'FATAL');
|
||||
t.equal(bunyan.resolveLevel('FATAL'), bunyan.FATAL, 'FATAL');
|
||||
t.end();
|
||||
});
|
33
test/other-api.test.mjs
Normal file
33
test/other-api.test.mjs
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test other parts of the exported API.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
|
||||
t.test('bunyan.<LEVEL>s', function () {
|
||||
assert.ok(bunyan.TRACE, 'TRACE');
|
||||
assert.ok(bunyan.DEBUG, 'DEBUG');
|
||||
assert.ok(bunyan.INFO, 'INFO');
|
||||
assert.ok(bunyan.WARN, 'WARN');
|
||||
assert.ok(bunyan.ERROR, 'ERROR');
|
||||
assert.ok(bunyan.FATAL, 'FATAL');
|
||||
});
|
||||
|
||||
t.test('bunyan.resolveLevel()', function () {
|
||||
assert.strictEqual(bunyan.resolveLevel('trace'), bunyan.TRACE, 'TRACE');
|
||||
assert.strictEqual(bunyan.resolveLevel('TRACE'), bunyan.TRACE, 'TRACE');
|
||||
assert.strictEqual(bunyan.resolveLevel('debug'), bunyan.DEBUG, 'DEBUG');
|
||||
assert.strictEqual(bunyan.resolveLevel('DEBUG'), bunyan.DEBUG, 'DEBUG');
|
||||
assert.strictEqual(bunyan.resolveLevel('info'), bunyan.INFO, 'INFO');
|
||||
assert.strictEqual(bunyan.resolveLevel('INFO'), bunyan.INFO, 'INFO');
|
||||
assert.strictEqual(bunyan.resolveLevel('warn'), bunyan.WARN, 'WARN');
|
||||
assert.strictEqual(bunyan.resolveLevel('WARN'), bunyan.WARN, 'WARN');
|
||||
assert.strictEqual(bunyan.resolveLevel('error'), bunyan.ERROR, 'ERROR');
|
||||
assert.strictEqual(bunyan.resolveLevel('ERROR'), bunyan.ERROR, 'ERROR');
|
||||
assert.strictEqual(bunyan.resolveLevel('fatal'), bunyan.FATAL, 'FATAL');
|
||||
assert.strictEqual(bunyan.resolveLevel('FATAL'), bunyan.FATAL, 'FATAL');
|
||||
});
|
|
@ -1,11 +0,0 @@
|
|||
var bunyan = require('../lib/bunyan');
|
||||
var log = bunyan.createLogger({
|
||||
name: 'default',
|
||||
streams: [ {
|
||||
type: 'rotating-file',
|
||||
path: __dirname + '/log.test.rot.log',
|
||||
period: '1d',
|
||||
count: 7
|
||||
} ]
|
||||
});
|
||||
console.log('done');
|
|
@ -1,32 +0,0 @@
|
|||
'use strict';
|
||||
/*
|
||||
* Test that bunyan process will terminate.
|
||||
*
|
||||
* Note: Currently (bunyan 0.23.1) this fails on node 0.8, because there is
|
||||
* no `unref` in node 0.8 and bunyan doesn't yet have `Logger.prototype.close()`
|
||||
* support.
|
||||
*/
|
||||
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
var nodeVer = process.versions.node.split('.').map(Number);
|
||||
|
||||
if (nodeVer[0] <= 0 && nodeVer[1] <= 8) {
|
||||
console.warn('skip test (node <= 0.8)');
|
||||
} else {
|
||||
test('log with rotating file stream will terminate', function (t) {
|
||||
exec('node ' +__dirname + '/process-exit.js', {timeout: 1000},
|
||||
function (err, stdout, stderr) {
|
||||
t.ifError(err);
|
||||
t.equal(stdout, 'done\n');
|
||||
t.equal(stderr, '');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test `type: 'raw'` Logger streams.
|
||||
*/
|
||||
|
||||
var format = require('util').format;
|
||||
var Logger = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
|
||||
test('raw stream', function (t) {
|
||||
var recs = [];
|
||||
|
||||
var log = new Logger({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(recs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
log.info('first');
|
||||
log.info({two: 'deux'}, 'second');
|
||||
|
||||
t.equal(recs.length, 2);
|
||||
t.equal(typeof (recs[0]), 'object', 'first rec is an object');
|
||||
t.equal(recs[1].two, 'deux', '"two" field made it through');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('raw streams and regular streams can mix', function (t) {
|
||||
var rawRecs = [];
|
||||
var nonRawRecs = [];
|
||||
|
||||
var log = new Logger({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(rawRecs),
|
||||
type: 'raw'
|
||||
},
|
||||
{
|
||||
stream: new CapturingStream(nonRawRecs)
|
||||
}
|
||||
]
|
||||
});
|
||||
log.info('first');
|
||||
log.info({two: 'deux'}, 'second');
|
||||
|
||||
t.equal(rawRecs.length, 2);
|
||||
t.equal(typeof (rawRecs[0]), 'object', 'first rawRec is an object');
|
||||
t.equal(rawRecs[1].two, 'deux', '"two" field made it through');
|
||||
|
||||
t.equal(nonRawRecs.length, 2);
|
||||
t.equal(typeof (nonRawRecs[0]), 'string', 'first nonRawRec is a string');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('child adding a non-raw stream works', function (t) {
|
||||
var parentRawRecs = [];
|
||||
var rawRecs = [];
|
||||
var nonRawRecs = [];
|
||||
|
||||
var logParent = new Logger({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(parentRawRecs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
var logChild = logParent.child({
|
||||
child: true,
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(rawRecs),
|
||||
type: 'raw'
|
||||
},
|
||||
{
|
||||
stream: new CapturingStream(nonRawRecs)
|
||||
}
|
||||
]
|
||||
});
|
||||
logParent.info('first');
|
||||
logChild.info({two: 'deux'}, 'second');
|
||||
|
||||
t.equal(rawRecs.length, 1,
|
||||
format('rawRecs length should be 1 (is %d)', rawRecs.length));
|
||||
t.equal(typeof (rawRecs[0]), 'object', 'rawRec entry is an object');
|
||||
t.equal(rawRecs[0].two, 'deux', '"two" field made it through');
|
||||
|
||||
t.equal(nonRawRecs.length, 1);
|
||||
t.equal(typeof (nonRawRecs[0]), 'string', 'first nonRawRec is a string');
|
||||
|
||||
t.end();
|
||||
});
|
107
test/raw-stream.test.mjs
Normal file
107
test/raw-stream.test.mjs
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test `type: 'raw'` Logger streams.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import { format } from 'util'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
|
||||
t.test('raw stream', function () {
|
||||
var recs = [];
|
||||
|
||||
var log = new bunyan({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(recs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
log.info('first');
|
||||
log.info({two: 'deux'}, 'second');
|
||||
|
||||
assert.strictEqual(recs.length, 2);
|
||||
assert.strictEqual(typeof (recs[0]), 'object', 'first rec is an object');
|
||||
assert.strictEqual(recs[1].two, 'deux', '"two" field made it through');
|
||||
});
|
||||
|
||||
|
||||
t.test('raw streams and regular streams can mix', function () {
|
||||
var rawRecs = [];
|
||||
var nonRawRecs = [];
|
||||
|
||||
var log = new bunyan({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(rawRecs),
|
||||
type: 'raw'
|
||||
},
|
||||
{
|
||||
stream: new CapturingStream(nonRawRecs)
|
||||
}
|
||||
]
|
||||
});
|
||||
log.info('first');
|
||||
log.info({two: 'deux'}, 'second');
|
||||
|
||||
assert.strictEqual(rawRecs.length, 2);
|
||||
assert.strictEqual(typeof (rawRecs[0]), 'object', 'first rawRec is an object');
|
||||
assert.strictEqual(rawRecs[1].two, 'deux', '"two" field made it through');
|
||||
|
||||
assert.strictEqual(nonRawRecs.length, 2);
|
||||
assert.strictEqual(typeof (nonRawRecs[0]), 'string', 'first nonRawRec is a string');
|
||||
|
||||
});
|
||||
|
||||
|
||||
t.test('child adding a non-raw stream works', function () {
|
||||
var parentRawRecs = [];
|
||||
var rawRecs = [];
|
||||
var nonRawRecs = [];
|
||||
|
||||
var logParent = new bunyan({
|
||||
name: 'raw-stream-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(parentRawRecs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
var logChild = logParent.child({
|
||||
child: true,
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(rawRecs),
|
||||
type: 'raw'
|
||||
},
|
||||
{
|
||||
stream: new CapturingStream(nonRawRecs)
|
||||
}
|
||||
]
|
||||
});
|
||||
logParent.info('first');
|
||||
logChild.info({two: 'deux'}, 'second');
|
||||
|
||||
assert.strictEqual(rawRecs.length, 1,
|
||||
format('rawRecs length should be 1 (is %d)', rawRecs.length));
|
||||
assert.strictEqual(typeof (rawRecs[0]), 'object', 'rawRec entry is an object');
|
||||
assert.strictEqual(rawRecs[0].two, 'deux', '"two" field made it through');
|
||||
|
||||
assert.strictEqual(nonRawRecs.length, 1);
|
||||
assert.strictEqual(typeof (nonRawRecs[0]), 'string', 'first nonRawRec is a string');
|
||||
|
||||
});
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Test the RingBuffer output stream.
|
||||
*/
|
||||
|
||||
var Logger = require('../lib/bunyan');
|
||||
var ringbuffer = new Logger.RingBuffer({ 'limit': 5 });
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
var log1 = new Logger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
stream: ringbuffer,
|
||||
type: 'raw',
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
test('ringbuffer', function (t) {
|
||||
log1.info('hello');
|
||||
log1.trace('there');
|
||||
log1.error('android');
|
||||
t.equal(ringbuffer.records.length, 2);
|
||||
t.equal(ringbuffer.records[0]['msg'], 'hello');
|
||||
t.equal(ringbuffer.records[1]['msg'], 'android');
|
||||
log1.error('one');
|
||||
log1.error('two');
|
||||
log1.error('three');
|
||||
t.equal(ringbuffer.records.length, 5);
|
||||
log1.error('four');
|
||||
t.equal(ringbuffer.records.length, 5);
|
||||
t.equal(ringbuffer.records[0]['msg'], 'android');
|
||||
t.equal(ringbuffer.records[1]['msg'], 'one');
|
||||
t.equal(ringbuffer.records[2]['msg'], 'two');
|
||||
t.equal(ringbuffer.records[3]['msg'], 'three');
|
||||
t.equal(ringbuffer.records[4]['msg'], 'four');
|
||||
t.end();
|
||||
});
|
38
test/ringbuffer.test.mjs
Normal file
38
test/ringbuffer.test.mjs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Test the RingBuffer output stream.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
var ringbuffer = new bunyan.RingBuffer({ 'limit': 5 });
|
||||
|
||||
var log1 = new bunyan({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
stream: ringbuffer,
|
||||
type: 'raw',
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
t.test('ringbuffer', function () {
|
||||
log1.info('hello');
|
||||
log1.trace('there');
|
||||
log1.error('android');
|
||||
assert.strictEqual(ringbuffer.records.length, 2);
|
||||
assert.strictEqual(ringbuffer.records[0]['msg'], 'hello');
|
||||
assert.strictEqual(ringbuffer.records[1]['msg'], 'android');
|
||||
log1.error('one');
|
||||
log1.error('two');
|
||||
log1.error('three');
|
||||
assert.strictEqual(ringbuffer.records.length, 5);
|
||||
log1.error('four');
|
||||
assert.strictEqual(ringbuffer.records.length, 5);
|
||||
assert.strictEqual(ringbuffer.records[0]['msg'], 'android');
|
||||
assert.strictEqual(ringbuffer.records[1]['msg'], 'one');
|
||||
assert.strictEqual(ringbuffer.records[2]['msg'], 'two');
|
||||
assert.strictEqual(ringbuffer.records[3]['msg'], 'three');
|
||||
assert.strictEqual(ringbuffer.records[4]['msg'], 'four');
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
var bunyan = require('../lib/bunyan');
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'safe-json-stringify-1'
|
|
@ -1,5 +1,5 @@
|
|||
import bunyan from '../lib/bunyan.mjs'
|
||||
process.env.BUNYAN_TEST_NO_SAFE_JSON_STRINGIFY = '1';
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'safe-json-stringify-2'
|
|
@ -1,4 +1,4 @@
|
|||
var bunyan = require('../lib/bunyan');
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'safe-json-stringify-3'
|
|
@ -1,5 +1,5 @@
|
|||
import bunyan from '../lib/bunyan.mjs'
|
||||
process.env.BUNYAN_TEST_NO_SAFE_JSON_STRINGIFY = '1';
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'safe-json-stringify-4'
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* If available, use `safe-json-stringfy` as a fallback stringifier.
|
||||
* This covers the case where an enumerable property throws an error
|
||||
* in its getter.
|
||||
*
|
||||
* See <https://github.com/trentm/node-bunyan/pull/182>
|
||||
*/
|
||||
|
||||
var p = console.warn;
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
test('__defineGetter__ boom', function (t) {
|
||||
var cmd = process.execPath + ' ' + __dirname + '/safe-json-stringify-1.js';
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err, err);
|
||||
var rec = JSON.parse(stdout.trim());
|
||||
t.equal(rec.obj.boom, '[Throws: __defineGetter__ ouch!]');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('__defineGetter__ boom, without safe-json-stringify', function (t) {
|
||||
var cmd = process.execPath + ' ' + __dirname + '/safe-json-stringify-2.js';
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err, err);
|
||||
t.ok(stdout.indexOf('Exception in JSON.stringify') !== -1);
|
||||
t.ok(stderr.indexOf(
|
||||
'You can install the "safe-json-stringify" module') !== -1);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('defineProperty boom', function (t) {
|
||||
var cmd = process.execPath + ' ' + __dirname + '/safe-json-stringify-3.js';
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err, err);
|
||||
var recs = stdout.trim().split(/\n/g);
|
||||
t.equal(recs.length, 2);
|
||||
var rec = JSON.parse(recs[0]);
|
||||
t.equal(rec.obj.boom, '[Throws: defineProperty ouch!]');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('defineProperty boom, without safe-json-stringify', function (t) {
|
||||
var cmd = process.execPath + ' ' + __dirname + '/safe-json-stringify-4.js';
|
||||
exec(cmd, function (err, stdout, stderr) {
|
||||
t.ifError(err, err);
|
||||
t.ok(stdout.indexOf('Exception in JSON.stringify') !== -1);
|
||||
t.equal(stdout.match(/Exception in JSON.stringify/g).length, 2);
|
||||
t.ok(stderr.indexOf(
|
||||
'You can install the "safe-json-stringify" module') !== -1);
|
||||
t.equal(stderr.match(
|
||||
/* JSSTYLED */
|
||||
/You can install the "safe-json-stringify" module/g).length, 1);
|
||||
t.end();
|
||||
});
|
||||
});
|
46
test/safe-json-stringify.test.mjs
Normal file
46
test/safe-json-stringify.test.mjs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* If available, use `safe-json-stringfy` as a fallback stringifier.
|
||||
* This covers the case where an enumerable property throws an error
|
||||
* in its getter.
|
||||
*
|
||||
* See <https://github.com/trentm/node-bunyan/pull/182>
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import { exec, dirname } from './helper.mjs'
|
||||
|
||||
|
||||
t.test('__defineGetter__ boom', async function () {
|
||||
let res = await exec('', 'node', dirname('/safe-json-stringify-1.mjs'))
|
||||
|
||||
var rec = JSON.parse(res.stdout.trim());
|
||||
assert.strictEqual(rec.obj.boom, '[Throws: __defineGetter__ ouch!]');
|
||||
});
|
||||
|
||||
t.test('__defineGetter__ boom, without safe-json-stringify', async function () {
|
||||
let res = await exec('', 'node', dirname('/safe-json-stringify-2.mjs'))
|
||||
assert.ok(res.stdout.indexOf('Exception in JSON.stringify') !== -1);
|
||||
assert.ok(res.stderr.indexOf(
|
||||
'You can install the "safe-json-stringify" module') !== -1);
|
||||
});
|
||||
|
||||
t.test('defineProperty boom', async function () {
|
||||
let res = await exec('', 'node', dirname('/safe-json-stringify-3.mjs'))
|
||||
var recs = res.stdout.trim().split(/\n/g);
|
||||
assert.strictEqual(recs.length, 2);
|
||||
var rec = JSON.parse(recs[0]);
|
||||
assert.strictEqual(rec.obj.boom, '[Throws: defineProperty ouch!]');
|
||||
});
|
||||
|
||||
t.test('defineProperty boom, without safe-json-stringify', async function () {
|
||||
let res = await exec('', 'node', dirname('/safe-json-stringify-4.mjs'))
|
||||
|
||||
assert.ok(res.stdout.indexOf('Exception in JSON.stringify') !== -1);
|
||||
assert.strictEqual(res.stdout.match(/Exception in JSON.stringify/g).length, 2);
|
||||
assert.ok(res.stderr.indexOf(
|
||||
'You can install the "safe-json-stringify" module') !== -1);
|
||||
assert.strictEqual(res.stderr.match(
|
||||
/You can install the "safe-json-stringify" module/g).length, 1);
|
||||
});
|
175
test/safe-json.test.mjs
Normal file
175
test/safe-json.test.mjs
Normal file
|
@ -0,0 +1,175 @@
|
|||
import { Eltro as t, assert} from 'eltro'
|
||||
import safeJson from '../lib/safe-json.mjs'
|
||||
|
||||
t.test('basic stringify', function() {
|
||||
assert.strictEqual('"foo"', safeJson('foo'));
|
||||
assert.strictEqual('{"foo":"bar"}', safeJson({foo: 'bar'}));
|
||||
});
|
||||
|
||||
t.test('object identity', function() {
|
||||
var a = { foo: 'bar' };
|
||||
var b = { one: a, two: a };
|
||||
assert.strictEqual('{"one":{"foo":"bar"},"two":{"foo":"bar"}}',safeJson(b));
|
||||
});
|
||||
|
||||
t.test('circular references', function() {
|
||||
var a = {};
|
||||
a.a = a;
|
||||
a.b = 'c';
|
||||
|
||||
assert.doesNotThrow(
|
||||
function() { safeJson(a); },
|
||||
'should not exceed stack size'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
'{"a":"[Circular]","b":"c"}',
|
||||
safeJson(a)
|
||||
);
|
||||
});
|
||||
|
||||
t.test('null', function() {
|
||||
assert.strictEqual(
|
||||
'{"x":null}',
|
||||
safeJson({x: null})
|
||||
)
|
||||
});
|
||||
|
||||
t.test('arrays', function() {
|
||||
var arr = [ 2 ];
|
||||
assert.strictEqual(
|
||||
'[2]',
|
||||
safeJson(arr)
|
||||
);
|
||||
|
||||
arr.push(arr);
|
||||
|
||||
assert.strictEqual(
|
||||
'[2,"[Circular]"]',
|
||||
safeJson(arr)
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
'{"x":[2,"[Circular]"]}',
|
||||
safeJson({x: arr})
|
||||
);
|
||||
});
|
||||
|
||||
t.test('throwing toJSON', function() {
|
||||
var obj = {
|
||||
toJSON: function() {
|
||||
throw new Error('Failing');
|
||||
}
|
||||
};
|
||||
|
||||
assert.strictEqual(
|
||||
'"[Throws: Failing]"',
|
||||
safeJson(obj)
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
'{"x":"[Throws: Failing]"}',
|
||||
safeJson({ x: obj })
|
||||
);
|
||||
});
|
||||
|
||||
t.test('properties on Object.create(null)', function() {
|
||||
var obj = Object.create(null, {
|
||||
foo: {
|
||||
get: function() { return 'bar'; },
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
assert.strictEqual(
|
||||
'{"foo":"bar"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
|
||||
var obj = Object.create(null, {
|
||||
foo: {
|
||||
get: function() { return 'bar'; },
|
||||
enumerable: true
|
||||
},
|
||||
broken: {
|
||||
get: function() { throw new Error('Broken'); },
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
assert.strictEqual(
|
||||
'{"foo":"bar","broken":"[Throws: Broken]"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
});
|
||||
|
||||
t.test('defined getter properties using __defineGetter__', function() {
|
||||
// non throwing
|
||||
var obj = {};
|
||||
obj.__defineGetter__('foo', function() { return 'bar'; });
|
||||
assert.strictEqual(
|
||||
'{"foo":"bar"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
|
||||
// throwing
|
||||
obj = {};
|
||||
obj.__defineGetter__('foo', function() { return undefined['oh my']; });
|
||||
|
||||
assert.doesNotThrow(
|
||||
function(){ safeJson(obj)}
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
'{"foo":"[Throws: Cannot read property \'oh my\' of undefined]"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
});
|
||||
|
||||
t.test('enumerable defined getter properties using Object.defineProperty', function() {
|
||||
// non throwing
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, 'foo', {get: function() { return 'bar'; }, enumerable: true});
|
||||
assert.strictEqual(
|
||||
'{"foo":"bar"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
|
||||
// throwing
|
||||
obj = {};
|
||||
Object.defineProperty(obj, 'foo', {get: function() { return undefined['oh my']; }, enumerable: true});
|
||||
|
||||
assert.doesNotThrow(
|
||||
function(){ safeJson(obj)}
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
'{"foo":"[Throws: Cannot read property \'oh my\' of undefined]"}',
|
||||
safeJson(obj)
|
||||
);
|
||||
});
|
||||
|
||||
t.test('formatting', function() {
|
||||
var obj = {a:{b:1, c:[{d: 1}]}}; // some nested object
|
||||
var formatters = [3, "\t", " "];
|
||||
formatters.forEach((formatter) => {
|
||||
assert.strictEqual(
|
||||
JSON.stringify(obj, null, formatter),
|
||||
safeJson(obj, null, formatter)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
t.test('replacing', function() {
|
||||
var obj = {a:{b:1, c:[{d: 1}]}}; // some nested object
|
||||
var replacers = [
|
||||
["a", "c"],
|
||||
(k, v) => typeof v == 'number' ? "***" : v,
|
||||
() => undefined,
|
||||
[]
|
||||
];
|
||||
replacers.forEach((replacer) => {
|
||||
assert.strictEqual(
|
||||
JSON.stringify(obj, replacer),
|
||||
safeJson(obj, replacer)
|
||||
);
|
||||
});
|
||||
});
|
|
@ -1,334 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the standard serializers in Bunyan.
|
||||
*/
|
||||
|
||||
var http = require('http');
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
var verror = require('verror');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
|
||||
test('req serializer', function (t) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
req: bunyan.stdSerializers.req
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusReqs = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusReqs.length; i++) {
|
||||
log.info({req: bogusReqs[i]}, 'hi');
|
||||
t.equal(records[i].req, bogusReqs[i]);
|
||||
}
|
||||
|
||||
// Get http request and response objects to play with and test.
|
||||
var theReq, theRes;
|
||||
var server = http.createServer(function (req, res) {
|
||||
theReq = req;
|
||||
theRes = res;
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.end('Hello World\n');
|
||||
})
|
||||
server.listen(8765, function () {
|
||||
http.get({host: '127.0.0.1', port: 8765, path: '/'}, function (res) {
|
||||
res.resume();
|
||||
log.info({req: theReq}, 'the request');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.req.method, 'GET');
|
||||
t.equal(lastRecord.req.url, theReq.url);
|
||||
t.equal(lastRecord.req.remoteAddress,
|
||||
theReq.connection.remoteAddress);
|
||||
t.equal(lastRecord.req.remotePort, theReq.connection.remotePort);
|
||||
server.close();
|
||||
t.end();
|
||||
}).on('error', function (err) {
|
||||
t.ok(false, 'error requesting to our test server: ' + err);
|
||||
server.close();
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('res serializer', function (t) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
res: bunyan.stdSerializers.res
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusRess = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusRess.length; i++) {
|
||||
log.info({res: bogusRess[i]}, 'hi');
|
||||
t.equal(records[i].res, bogusRess[i]);
|
||||
}
|
||||
|
||||
// Get http request and response objects to play with and test.
|
||||
var theReq, theRes;
|
||||
var server = http.createServer(function (req, res) {
|
||||
theReq = req;
|
||||
theRes = res;
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.end('Hello World\n');
|
||||
})
|
||||
server.listen(8765, function () {
|
||||
http.get({host: '127.0.0.1', port: 8765, path: '/'}, function (res) {
|
||||
res.resume();
|
||||
log.info({res: theRes}, 'the response');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.res.statusCode, theRes.statusCode);
|
||||
t.equal(lastRecord.res.header, theRes._header);
|
||||
server.close();
|
||||
t.end();
|
||||
}).on('error', function (err) {
|
||||
t.ok(false, 'error requesting to our test server: ' + err);
|
||||
server.close();
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('err serializer', function (t) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
err: bunyan.stdSerializers.err
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusErrs = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusErrs.length; i++) {
|
||||
log.info({err: bogusErrs[i]}, 'hi');
|
||||
t.equal(records[i].err, bogusErrs[i]);
|
||||
}
|
||||
|
||||
var theErr = new TypeError('blah');
|
||||
|
||||
log.info(theErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, theErr.message);
|
||||
t.equal(lastRecord.err.name, theErr.name);
|
||||
t.equal(lastRecord.err.stack, theErr.stack);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('err serializer: custom serializer', function (t) {
|
||||
var records = [];
|
||||
|
||||
function customSerializer(err) {
|
||||
return {
|
||||
message: err.message,
|
||||
name: err.name,
|
||||
stack: err.stack,
|
||||
beep: err.beep
|
||||
};
|
||||
}
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
err: customSerializer
|
||||
}
|
||||
});
|
||||
|
||||
var e1 = new Error('message1');
|
||||
e1.beep = 'bop';
|
||||
var e2 = new Error('message2');
|
||||
var errs = [e1, e2];
|
||||
|
||||
for (var i = 0; i < errs.length; i++) {
|
||||
log.info(errs[i]);
|
||||
t.equal(records[i].err.message, errs[i].message);
|
||||
t.equal(records[i].err.beep, errs[i].beep);
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('err serializer: long stack', function (t) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [ {
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
} ],
|
||||
serializers: {
|
||||
err: bunyan.stdSerializers.err
|
||||
}
|
||||
});
|
||||
|
||||
var topErr, midErr, bottomErr;
|
||||
|
||||
// Just a VError.
|
||||
topErr = new verror.VError('top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message, 'Just a VError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'Just a VError');
|
||||
t.equal(lastRecord.err.stack, topErr.stack, 'Just a VError');
|
||||
|
||||
// Just a WError.
|
||||
topErr = new verror.WError('top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message, 'Just a WError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'Just a WError');
|
||||
t.equal(lastRecord.err.stack, topErr.stack, 'Just a WError');
|
||||
|
||||
// WError <- TypeError
|
||||
bottomErr = new TypeError('bottom err');
|
||||
topErr = new verror.WError(bottomErr, 'top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message, 'WError <- TypeError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'WError <- TypeError');
|
||||
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
||||
t.equal(lastRecord.err.stack, expectedStack, 'WError <- TypeError');
|
||||
|
||||
// WError <- WError
|
||||
bottomErr = new verror.WError('bottom err');
|
||||
topErr = new verror.WError(bottomErr, 'top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message, 'WError <- WError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError');
|
||||
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
||||
t.equal(lastRecord.err.stack, expectedStack, 'WError <- WError');
|
||||
|
||||
// WError <- WError <- TypeError
|
||||
bottomErr = new TypeError('bottom err');
|
||||
midErr = new verror.WError(bottomErr, 'mid err');
|
||||
topErr = new verror.WError(midErr, 'top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message,
|
||||
'WError <- WError <- TypeError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError <- TypeError');
|
||||
var expectedStack = (topErr.stack
|
||||
+ '\nCaused by: ' + midErr.stack
|
||||
+ '\nCaused by: ' + bottomErr.stack);
|
||||
t.equal(lastRecord.err.stack, expectedStack,
|
||||
'WError <- WError <- TypeError');
|
||||
|
||||
// WError <- WError <- WError
|
||||
bottomErr = new verror.WError('bottom err');
|
||||
midErr = new verror.WError(bottomErr, 'mid err');
|
||||
topErr = new verror.WError(midErr, 'top err');
|
||||
log.info(topErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
t.equal(lastRecord.err.message, topErr.message,
|
||||
'WError <- WError <- WError');
|
||||
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError <- WError');
|
||||
var expectedStack = (topErr.stack
|
||||
+ '\nCaused by: ' + midErr.stack
|
||||
+ '\nCaused by: ' + bottomErr.stack);
|
||||
t.equal(lastRecord.err.stack, expectedStack, 'WError <- WError <- WError');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
// Bunyan 0.18.3 introduced a bug where *all* serializers are applied
|
||||
// even if the log record doesn't have the associated key. That means
|
||||
// serializers that don't handle an `undefined` value will blow up.
|
||||
test('do not apply serializers if no record key', function (t) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [ {
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
} ],
|
||||
serializers: {
|
||||
err: bunyan.stdSerializers.err,
|
||||
boom: function (value) {
|
||||
throw new Error('boom');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
log.info({foo: 'bar'}, 'record one');
|
||||
log.info({err: new Error('record two err')}, 'record two');
|
||||
|
||||
t.equal(records[0].boom, undefined);
|
||||
t.equal(records[0].foo, 'bar');
|
||||
t.equal(records[1].boom, undefined);
|
||||
t.equal(records[1].err.message, 'record two err');
|
||||
|
||||
t.end();
|
||||
});
|
242
test/serializers.test.mjs
Normal file
242
test/serializers.test.mjs
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test the standard serializers in Bunyan.
|
||||
*/
|
||||
|
||||
import http from 'http'
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
t.test('req serializer', function (cb) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
req: bunyan.stdSerializers.req
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusReqs = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusReqs.length; i++) {
|
||||
log.info({req: bogusReqs[i]}, 'hi');
|
||||
assert.strictEqual(records[i].req, bogusReqs[i]);
|
||||
}
|
||||
|
||||
// Get http request and response objects to play with and test.
|
||||
var theReq, theRes;
|
||||
var server = http.createServer(function (req, res) {
|
||||
theReq = req;
|
||||
theRes = res;
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.end('Hello World\n');
|
||||
})
|
||||
server.listen(8765, function () {
|
||||
http.get({host: '127.0.0.1', port: 8765, path: '/'}, function (res) {
|
||||
res.resume();
|
||||
log.info({req: theReq}, 'the request');
|
||||
var lastRecord = records[records.length-1];
|
||||
|
||||
try {
|
||||
assert.strictEqual(lastRecord.req.method, 'GET');
|
||||
assert.strictEqual(lastRecord.req.url, theReq.url);
|
||||
assert.strictEqual(lastRecord.req.remoteAddress,
|
||||
theReq.connection.remoteAddress);
|
||||
assert.strictEqual(lastRecord.req.remotePort, theReq.connection.remotePort);
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
server.close();
|
||||
cb()
|
||||
}).on('error', function (err) {
|
||||
server.close();
|
||||
cb(err)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
t.test('res serializer', function (cb) {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
res: bunyan.stdSerializers.res
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusRess = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusRess.length; i++) {
|
||||
log.info({res: bogusRess[i]}, 'hi');
|
||||
assert.strictEqual(records[i].res, bogusRess[i]);
|
||||
}
|
||||
|
||||
// Get http request and response objects to play with and test.
|
||||
var theReq, theRes;
|
||||
var server = http.createServer(function (req, res) {
|
||||
theReq = req;
|
||||
theRes = res;
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.end('Hello World\n');
|
||||
})
|
||||
server.listen(8765, function () {
|
||||
http.get({host: '127.0.0.1', port: 8765, path: '/'}, function (res) {
|
||||
res.resume();
|
||||
log.info({res: theRes}, 'the response');
|
||||
var lastRecord = records[records.length-1];
|
||||
try {
|
||||
assert.strictEqual(lastRecord.res.statusCode, theRes.statusCode);
|
||||
assert.strictEqual(lastRecord.res.header, theRes._header);
|
||||
} catch (err) {
|
||||
cb(err)
|
||||
}
|
||||
server.close();
|
||||
cb()
|
||||
}).on('error', function (err) {
|
||||
server.close();
|
||||
cb(err)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
t.test('err serializer', function () {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
err: bunyan.stdSerializers.err
|
||||
}
|
||||
});
|
||||
|
||||
// None of these should blow up.
|
||||
var bogusErrs = [
|
||||
undefined,
|
||||
null,
|
||||
{},
|
||||
1,
|
||||
'string',
|
||||
[1, 2, 3],
|
||||
{'foo':'bar'}
|
||||
];
|
||||
for (var i = 0; i < bogusErrs.length; i++) {
|
||||
log.info({err: bogusErrs[i]}, 'hi');
|
||||
assert.strictEqual(records[i].err, bogusErrs[i]);
|
||||
}
|
||||
|
||||
var theErr = new TypeError('blah');
|
||||
|
||||
log.info(theErr, 'the error');
|
||||
var lastRecord = records[records.length-1];
|
||||
assert.strictEqual(lastRecord.err.message, theErr.message);
|
||||
assert.strictEqual(lastRecord.err.name, theErr.name);
|
||||
assert.strictEqual(lastRecord.err.stack, theErr.stack);
|
||||
});
|
||||
|
||||
t.test('err serializer: custom serializer', function () {
|
||||
var records = [];
|
||||
|
||||
function customSerializer(err) {
|
||||
return {
|
||||
message: err.message,
|
||||
name: err.name,
|
||||
stack: err.stack,
|
||||
beep: err.beep
|
||||
};
|
||||
}
|
||||
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
}
|
||||
],
|
||||
serializers: {
|
||||
err: customSerializer
|
||||
}
|
||||
});
|
||||
|
||||
var e1 = new Error('message1');
|
||||
e1.beep = 'bop';
|
||||
var e2 = new Error('message2');
|
||||
var errs = [e1, e2];
|
||||
|
||||
for (var i = 0; i < errs.length; i++) {
|
||||
log.info(errs[i]);
|
||||
assert.strictEqual(records[i].err.message, errs[i].message);
|
||||
assert.strictEqual(records[i].err.beep, errs[i].beep);
|
||||
}
|
||||
});
|
||||
|
||||
// Bunyan 0.18.3 introduced a bug where *all* serializers are applied
|
||||
// even if the log record doesn't have the associated key. That means
|
||||
// serializers that don't handle an `undefined` value will blow up.
|
||||
t.test('do not apply serializers if no record key', function () {
|
||||
var records = [];
|
||||
var log = bunyan.createLogger({
|
||||
name: 'serializer-test',
|
||||
streams: [ {
|
||||
stream: new CapturingStream(records),
|
||||
type: 'raw'
|
||||
} ],
|
||||
serializers: {
|
||||
err: bunyan.stdSerializers.err,
|
||||
boom: function (value) {
|
||||
throw new Error('boom');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
log.info({foo: 'bar'}, 'record one');
|
||||
log.info({err: new Error('record two err')}, 'record two');
|
||||
|
||||
assert.strictEqual(records[0].boom, undefined);
|
||||
assert.strictEqual(records[0].foo, 'bar');
|
||||
assert.strictEqual(records[1].boom, undefined);
|
||||
assert.strictEqual(records[1].err.message, 'record two err');
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick.
|
||||
*
|
||||
* Test `src: true` usage.
|
||||
*/
|
||||
|
||||
// Intentionally on line 8 for tests below:
|
||||
function logSomething(log) { log.info('something'); }
|
||||
|
||||
|
||||
var format = require('util').format;
|
||||
var Logger = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var after = tap4nodeunit.after;
|
||||
var before = tap4nodeunit.before;
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
|
||||
test('src', function (t) {
|
||||
var recs = [];
|
||||
|
||||
var log = new Logger({
|
||||
name: 'src-test',
|
||||
src: true,
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(recs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
log.info('top-level');
|
||||
logSomething(log);
|
||||
|
||||
t.equal(recs.length, 2);
|
||||
recs.forEach(function (rec) {
|
||||
t.ok(rec.src);
|
||||
t.equal(typeof (rec.src), 'object');
|
||||
t.equal(rec.src.file, __filename);
|
||||
t.ok(rec.src.line);
|
||||
t.equal(typeof (rec.src.line), 'number');
|
||||
});
|
||||
var rec = recs[1];
|
||||
t.ok(rec.src.func);
|
||||
t.equal(rec.src.func, 'logSomething');
|
||||
t.equal(rec.src.line, 8);
|
||||
|
||||
t.end();
|
||||
});
|
52
test/src.test.mjs
Normal file
52
test/src.test.mjs
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick.
|
||||
*
|
||||
* Test `src: true` usage.
|
||||
*/
|
||||
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
// Intentionally on line 11 for tests below:
|
||||
function logSomething(log) { log.info('something'); }
|
||||
|
||||
function CapturingStream(recs) {
|
||||
this.recs = recs;
|
||||
}
|
||||
CapturingStream.prototype.write = function (rec) {
|
||||
this.recs.push(rec);
|
||||
}
|
||||
|
||||
// commented out due to broken implementation of
|
||||
// getting caller line in strict mode (getCaller3Info())
|
||||
|
||||
/* t.only().test('src', function () {
|
||||
var recs = [];
|
||||
|
||||
var log = new bunyan({
|
||||
name: 'src-test',
|
||||
src: true,
|
||||
streams: [
|
||||
{
|
||||
stream: new CapturingStream(recs),
|
||||
type: 'raw'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
log.info('top-level');
|
||||
logSomething(log);
|
||||
|
||||
assert.strictEqual(recs.length, 2);
|
||||
recs.forEach(function (rec) {
|
||||
assert.ok(rec.src);
|
||||
assert.strictEqual(typeof (rec.src), 'object');
|
||||
assert.strictEqual(rec.src.file, __filename);
|
||||
assert.ok(rec.src.line);
|
||||
assert.strictEqual(typeof (rec.src.line), 'number');
|
||||
});
|
||||
var rec = recs[1];
|
||||
assert.ok(rec.src.func);
|
||||
assert.strictEqual(rec.src.func, 'logSomething');
|
||||
assert.strictEqual(rec.src.line, 11);
|
||||
});*/
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test that streams (the various way they can be added to
|
||||
* a Logger instance) get the appropriate level.
|
||||
*/
|
||||
|
||||
var util = require('util'),
|
||||
format = util.format,
|
||||
inspect = util.inspect;
|
||||
var p = console.log;
|
||||
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
// node-tap API
|
||||
if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
var test = tap4nodeunit.test;
|
||||
|
||||
|
||||
// ---- Tests
|
||||
|
||||
var log1 = bunyan.createLogger({
|
||||
name: 'log1',
|
||||
streams: [
|
||||
{
|
||||
path: __dirname + '/level.test.log1.log',
|
||||
level: 'info'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
test('default stream log level', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo'
|
||||
});
|
||||
t.equal(log.level(), bunyan.INFO);
|
||||
t.equal(log.streams[0].level, bunyan.INFO);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('default stream, level=DEBUG specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: bunyan.DEBUG
|
||||
});
|
||||
t.equal(log.level(), bunyan.DEBUG);
|
||||
t.equal(log.streams[0].level, bunyan.DEBUG);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('default stream, level="trace" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'trace'
|
||||
});
|
||||
t.equal(log.level(), bunyan.TRACE);
|
||||
t.equal(log.streams[0].level, bunyan.TRACE);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('stream & level="trace" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: process.stderr,
|
||||
level: 'trace'
|
||||
});
|
||||
t.equal(log.level(), bunyan.TRACE);
|
||||
t.equal(log.streams[0].level, bunyan.TRACE);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('one stream, default level', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.INFO);
|
||||
t.equal(log.streams[0].level, bunyan.INFO);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('one stream, top-"level" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'error',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.ERROR);
|
||||
t.equal(log.streams[0].level, bunyan.ERROR);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('one stream, stream-"level" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'error'
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.ERROR);
|
||||
t.equal(log.streams[0].level, bunyan.ERROR);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('one stream, both-"level" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'debug',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'error'
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.ERROR);
|
||||
t.equal(log.streams[0].level, bunyan.ERROR);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('two streams, both-"level" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'debug',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
level: 'trace'
|
||||
},
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.TRACE, 'log.level()');
|
||||
t.equal(log.streams[0].level, bunyan.TRACE);
|
||||
t.equal(log.streams[1].level, bunyan.FATAL);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('two streams, one with "level" specified', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
},
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(log.level(), bunyan.INFO);
|
||||
t.equal(log.streams[0].level, bunyan.INFO);
|
||||
t.equal(log.streams[1].level, bunyan.FATAL);
|
||||
t.end();
|
||||
});
|
||||
|
||||
// Issue #335
|
||||
test('log level 0 to turn on all logging', function (t) {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 0
|
||||
});
|
||||
t.equal(log.level(), 0);
|
||||
t.equal(log.streams[0].level, 0);
|
||||
t.end();
|
||||
});
|
152
test/stream-levels.test.mjs
Normal file
152
test/stream-levels.test.mjs
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Trent Mick. All rights reserved.
|
||||
*
|
||||
* Test that streams (the various way they can be added to
|
||||
* a Logger instance) get the appropriate level.
|
||||
*/
|
||||
import { Eltro as t, assert} from 'eltro'
|
||||
import bunyan from '../lib/bunyan.mjs'
|
||||
|
||||
|
||||
// ---- Tests
|
||||
|
||||
|
||||
t.test('default stream log level', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo'
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.INFO);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.INFO);
|
||||
});
|
||||
|
||||
t.test('default stream, level=DEBUG specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: bunyan.DEBUG
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.DEBUG);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.DEBUG);
|
||||
});
|
||||
|
||||
t.test('default stream, level="trace" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'trace'
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.TRACE);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.TRACE);
|
||||
});
|
||||
|
||||
t.test('stream & level="trace" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
stream: process.stderr,
|
||||
level: 'trace'
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.TRACE);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.TRACE);
|
||||
});
|
||||
|
||||
t.test('one stream, default level', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.INFO);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.INFO);
|
||||
});
|
||||
|
||||
t.test('one stream, top-"level" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'error',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.ERROR);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.ERROR);
|
||||
});
|
||||
|
||||
t.test('one stream, stream-"level" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'error'
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.ERROR);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.ERROR);
|
||||
});
|
||||
|
||||
t.test('one stream, both-"level" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'debug',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'error'
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.ERROR);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.ERROR);
|
||||
});
|
||||
|
||||
t.test('two streams, both-"level" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 'debug',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
level: 'trace'
|
||||
},
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.TRACE, 'log.level()');
|
||||
assert.strictEqual(log.streams[0].level, bunyan.TRACE);
|
||||
assert.strictEqual(log.streams[1].level, bunyan.FATAL);
|
||||
});
|
||||
|
||||
t.test('two streams, one with "level" specified', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
streams: [
|
||||
{
|
||||
stream: process.stdout,
|
||||
},
|
||||
{
|
||||
stream: process.stderr,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
});
|
||||
assert.strictEqual(log.level(), bunyan.INFO);
|
||||
assert.strictEqual(log.streams[0].level, bunyan.INFO);
|
||||
assert.strictEqual(log.streams[1].level, bunyan.FATAL);
|
||||
});
|
||||
|
||||
// Issue #335
|
||||
t.test('log level 0 to turn on all logging', function () {
|
||||
var log = bunyan.createLogger({
|
||||
name: 'foo',
|
||||
level: 0
|
||||
});
|
||||
assert.strictEqual(log.level(), 0);
|
||||
assert.strictEqual(log.streams[0].level, 0);
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Mark Cavage. All rights reserved.
|
||||
*
|
||||
* Help nodeunit API feel like node-tap's.
|
||||
*
|
||||
* Usage:
|
||||
* if (require.cache[__dirname + '/tap4nodeunit.js'])
|
||||
* delete require.cache[__dirname + '/tap4nodeunit.js'];
|
||||
* var tap4nodeunit = require('./tap4nodeunit.js');
|
||||
* var after = tap4nodeunit.after;
|
||||
* var before = tap4nodeunit.before;
|
||||
* var test = tap4nodeunit.test;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//---- Exports
|
||||
|
||||
module.exports = {
|
||||
after: function after(teardown) {
|
||||
module.parent.exports.tearDown = function _teardown(callback) {
|
||||
try {
|
||||
teardown.call(this, callback);
|
||||
} catch (e) {
|
||||
console.error('after:\n' + e.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
before: function before(setup) {
|
||||
module.parent.exports.setUp = function _setup(callback) {
|
||||
try {
|
||||
setup.call(this, callback);
|
||||
} catch (e) {
|
||||
console.error('before:\n' + e.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
test: function test(name, tester) {
|
||||
module.parent.exports[name] = function _(t) {
|
||||
var _done = false;
|
||||
t.end = function end() {
|
||||
if (!_done) {
|
||||
_done = true;
|
||||
t.done();
|
||||
}
|
||||
};
|
||||
t.notOk = function notOk(ok, message) {
|
||||
return (t.ok(!ok, message));
|
||||
};
|
||||
t.error = t.ifError;
|
||||
|
||||
tester.call(this, t);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
};
|
43
tools/ben.js
Normal file
43
tools/ben.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Bring ben to local and remove one more dependancy.
|
||||
// The package ben has either way not been updated in over 10 years.
|
||||
// https://github.com/substack/node-ben
|
||||
|
||||
var ben = module.exports = function (times, cb) {
|
||||
if (typeof times === 'function') {
|
||||
cb = times;
|
||||
times = 10000;
|
||||
}
|
||||
|
||||
var t0 = Date.now();
|
||||
for (var i = 0; i < times; i++) {
|
||||
cb();
|
||||
}
|
||||
var elapsed = Date.now() - t0;
|
||||
|
||||
return elapsed / times;
|
||||
};
|
||||
ben.sync = ben;
|
||||
|
||||
ben.async = function (times, cb, resultCb) {
|
||||
if (typeof times === 'function') {
|
||||
resultCb = cb;
|
||||
cb = times;
|
||||
times = 100;
|
||||
}
|
||||
|
||||
var pending = times;
|
||||
var t = Date.now();
|
||||
var elapsed = 0;
|
||||
|
||||
cb(function fn () {
|
||||
elapsed += Date.now() - t;
|
||||
|
||||
if (--pending === 0) {
|
||||
resultCb(elapsed / times);
|
||||
}
|
||||
else {
|
||||
t = Date.now();
|
||||
cb(fn);
|
||||
}
|
||||
});
|
||||
};
|
|
@ -13,7 +13,7 @@
|
|||
* Result: Another order of magnitude.
|
||||
*/
|
||||
|
||||
var ben = require('ben'); // npm install ben
|
||||
var ben = require('./ben'); // npm install ben
|
||||
var Logger = require('../lib/bunyan');
|
||||
|
||||
var log = new Logger({
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
console.log('Time JSON.stringify and alternatives in Logger._emit:');
|
||||
|
||||
var ben = require('ben'); // npm install ben
|
||||
var ben = require('./ben'); // npm install ben
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
function Collector() {}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
console.log('Time log.trace() when log level is "info":');
|
||||
|
||||
var ben = require('ben'); // npm install ben
|
||||
var ben = require('./ben'); // npm install ben
|
||||
var bunyan = require('../lib/bunyan');
|
||||
|
||||
function Collector() {}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
console.log('Time adding "src" field with call source info:');
|
||||
|
||||
var ben = require('ben'); // npm install ben
|
||||
var ben = require('./ben'); // npm install ben
|
||||
var Logger = require('../lib/bunyan');
|
||||
|
||||
var records = [];
|
||||
|
|
Loading…
Reference in a new issue