674 lines
26 KiB
JavaScript
674 lines
26 KiB
JavaScript
'use strict';
|
|
|
|
var SyslogStream = require('./index'),
|
|
format = require('util').format,
|
|
os = require('os');
|
|
|
|
require('should');
|
|
|
|
var TEST = {
|
|
NAME: 'Test',
|
|
MSG_ID: 'FOOMSG',
|
|
PEN: 12343,
|
|
FACILITY: 'LOCAL3',
|
|
HOSTNAME: '127.0.1.1'
|
|
};
|
|
|
|
var syslogRegex = new RegExp(format(
|
|
'^<\\d+>\\d [\\d\\-.T:Z]+ %s %s \\d+ %s \\S',
|
|
TEST.HOSTNAME,
|
|
TEST.NAME,
|
|
TEST.MSG_ID
|
|
));
|
|
var ISOStringRegex = /"[\d\-.T:Z]+"$/;
|
|
|
|
var BUNYAN = {
|
|
FATAL: 60,
|
|
ERROR: 50,
|
|
WARN: 40,
|
|
INFO: 30,
|
|
DEBUG: 20,
|
|
TRACE: 10
|
|
};
|
|
var SYSLOG = {
|
|
VERSION: 1,
|
|
NILVALUE: '-',
|
|
LEVEL: {
|
|
EMERG: 0,
|
|
ALERT: 1,
|
|
CRIT: 2,
|
|
ERR: 3,
|
|
WARNING: 4,
|
|
NOTICE: 5,
|
|
INFO: 6,
|
|
DEBUG: 7
|
|
},
|
|
FACILITY: {
|
|
KERN: 0,
|
|
USER: 1,
|
|
MAIL: 2,
|
|
DAEMON: 3,
|
|
AUTH: 4,
|
|
SYSLOG: 5,
|
|
LPR: 6,
|
|
NEWS: 7,
|
|
UUCP: 8,
|
|
CLOCK: 9,
|
|
AUTHPRIV: 10,
|
|
FTP: 11,
|
|
NTP: 12,
|
|
LOG_AUDIT: 13,
|
|
LOG_ALERT: 14,
|
|
CRON: 15,
|
|
LOCAL0: 16,
|
|
LOCAL1: 17,
|
|
LOCAL2: 18,
|
|
LOCAL3: 19,
|
|
LOCAL4: 20,
|
|
LOCAL5: 21,
|
|
LOCAL6: 22,
|
|
LOCAL7: 23
|
|
}
|
|
};
|
|
describe('SyslogStream', function () {
|
|
var syslog, stream;
|
|
|
|
// cheating - relying on emit's synchronous behavior
|
|
function getMsg(r, log) {
|
|
var msg;
|
|
if (!log) { log = syslog; }
|
|
|
|
log.once('data', function (chunk) {
|
|
msg = chunk.toString();
|
|
});
|
|
log.write(r);
|
|
return msg.replace(/\r?\n$/, '');
|
|
}
|
|
function getHeader(r, log) {
|
|
var msg = getMsg(r, log);
|
|
return msg.split(' ').slice(0, 7);
|
|
}
|
|
|
|
beforeEach(function () {
|
|
syslog = new SyslogStream({
|
|
name: TEST.NAME,
|
|
msgId: TEST.MSG_ID,
|
|
PEN: TEST.PEN,
|
|
facility: TEST.FACILITY,
|
|
hostname: TEST.HOSTNAME
|
|
});
|
|
});
|
|
|
|
afterEach(function (done) {
|
|
syslog.end(done);
|
|
});
|
|
|
|
describe('constructor', function () {
|
|
it('provides default values', function () {
|
|
var log = new SyslogStream();
|
|
['type', 'facility', 'host', 'appName', 'msgID', 'pid']
|
|
.forEach(function (type) {
|
|
log.glossy[type].should.be.ok;
|
|
});
|
|
log.decodeBuffers.should.equal(false);
|
|
log.decodeJSON.should.equal(false);
|
|
log.defaultSeverity.should.equal('notice');
|
|
});
|
|
describe('appName', function () {
|
|
var _title = process.title,
|
|
_argv = process.argv;
|
|
beforeEach(function () {
|
|
delete process.title;
|
|
delete process.argv;
|
|
});
|
|
afterEach(function () {
|
|
process.title = _title;
|
|
process.argv = _argv;
|
|
});
|
|
|
|
it('should respect the specified value', function () {
|
|
var log = new SyslogStream({ appName: TEST.NAME });
|
|
getHeader('bar', log)[3].should.equal(TEST.NAME);
|
|
|
|
var log = new SyslogStream({ name: TEST.NAME });
|
|
getHeader('bar', log)[3].should.equal(TEST.NAME);
|
|
});
|
|
it('should fall back on process.title', function () {
|
|
process.title = 'process.title';
|
|
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[3].should.equal('process.title');
|
|
});
|
|
it('should fall back on process.argv[0]', function () {
|
|
process.argv = ['process.argv'];
|
|
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[3].should.equal('process.argv');
|
|
});
|
|
it('should fall back on NILVALUE', function () {
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[3].should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
describe('hostname', function () {
|
|
var _os_hostname = os.hostname;
|
|
beforeEach(function () {
|
|
os.hostname = function () { };
|
|
});
|
|
afterEach(function () {
|
|
os.hostname = _os_hostname;
|
|
});
|
|
it('should respect the specified hostname', function () {
|
|
var log = new SyslogStream({ host: TEST.HOSTNAME });
|
|
getHeader('bar', log)[2].should.equal(TEST.HOSTNAME);
|
|
|
|
var log = new SyslogStream({ hostname: TEST.HOSTNAME });
|
|
getHeader('bar', log)[2].should.equal(TEST.HOSTNAME);
|
|
});
|
|
it('should fall back on os.hostname()', function () {
|
|
os.hostname = function () { return 'os.hostname'; }
|
|
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[2].should.equal('os.hostname');
|
|
});
|
|
it('should fall back on NILVALUE', function () {
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[2].should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
describe('pid', function () {
|
|
var _pid = process.pid;
|
|
beforeEach(function () {
|
|
delete process.pid;
|
|
});
|
|
afterEach(function () {
|
|
process.pid = _pid
|
|
});
|
|
it('should respect the specified pid', function () {
|
|
var log = new SyslogStream({ pid: 1 });
|
|
getHeader('bar', log)[4].should.equal('1');
|
|
});
|
|
it('should fall back on process.pid', function () {
|
|
process.pid = 2;
|
|
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[4].should.equal('2');
|
|
});
|
|
it('should fall back on NILVALUE', function () {
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[4].should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
describe('msgID', function () {
|
|
it('should respect the specified hostname', function () {
|
|
var log = new SyslogStream({ msgID: TEST.MSG_ID });
|
|
getHeader('bar', log)[5].should.equal(TEST.MSG_ID);
|
|
|
|
var log = new SyslogStream({ msgId: TEST.MSG_ID });
|
|
getHeader('bar', log)[5].should.equal(TEST.MSG_ID);
|
|
});
|
|
it('should fall back on NILVALUE', function () {
|
|
var log = new SyslogStream();
|
|
getHeader('bar', log)[5].should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
it('should respect the decodeBuffers option', function () {
|
|
var log = new SyslogStream({
|
|
decodeBuffers: true
|
|
});
|
|
getMsg(new Buffer('foo'), log).should.match(/foo$/);
|
|
|
|
var log = new SyslogStream({
|
|
decodeBuffers: false
|
|
});
|
|
|
|
try {
|
|
getMsg(new Buffer('foo'), log).should.match(/\[102,111,111\]$/);
|
|
} catch (e) {
|
|
getMsg(new Buffer('foo'), log).should.match(/\{"type":"Buffer","data":\[102,111,111\]\}$/);
|
|
}
|
|
|
|
});
|
|
it('should respect the decodeJSON option', function () {
|
|
var log = new SyslogStream({
|
|
decodeJSON: true
|
|
});
|
|
getMsg('{"msg":"foo"}', log).should.match(/foo$/);
|
|
|
|
var log = new SyslogStream({
|
|
decodeJSON: false
|
|
});
|
|
getMsg('{"msg":"foo"}', log).should.match(/\{"msg":"foo"\}$/);
|
|
});
|
|
it('should allow decodeBuffers and decodeJSON to work together', function () {
|
|
var log = new SyslogStream({
|
|
decodeBuffers: true,
|
|
decodeJSON: true
|
|
});
|
|
getMsg(new Buffer('{"msg":"foo"}'), log).should.match(/foo$/);
|
|
});
|
|
it('should respect the useStructuredData option', function () {
|
|
var log = new SyslogStream({ useStructuredData: true, PEN: 1 });
|
|
getMsg({ msg: 'foo', data: { bar: 'baz' } }, log).should.match(/\[data@1 bar="baz"\] foo$/);
|
|
|
|
var log = new SyslogStream({ useStructuredData: true });
|
|
getMsg({ msg: 'foo' }, log).should.match(/- foo$/);
|
|
|
|
var log = new SyslogStream({ useStructuredData: false, PEN: 1 });
|
|
getMsg({ msg: 'foo', data: { bar: 'baz' } }, log).should.match(/- foo \{"data":\{"bar":"baz"\}\}$/);
|
|
|
|
var log = new SyslogStream({ useStructuredData: false});
|
|
getMsg({ msg: 'foo' }, log).should.match(/- foo$/);
|
|
});
|
|
});
|
|
describe('message', function () {
|
|
it('should accept plain text strings', function () {
|
|
getMsg('foo').should.match(syslogRegex);
|
|
});
|
|
it('should return JSON encoded messages for arrays', function () {
|
|
getMsg([null, 'foo']).should.match(/\[null,"foo"\]$/);
|
|
});
|
|
it('should return an ISO Date string for Date objects', function () {
|
|
getMsg(new Date()).should.match(ISOStringRegex);
|
|
});
|
|
it('should interpret other primitives as strings', function () {
|
|
getMsg(true).should.match(/true$/);
|
|
getMsg(123).should.match(/123$/);
|
|
});
|
|
it('should use the \'msg\' field of a record as the message if it exists', function () {
|
|
getMsg({
|
|
msg: 'msgKey'
|
|
}).should.match(/msgKey$/);
|
|
});
|
|
});
|
|
describe('header', function () {
|
|
function priority(level, facility) {
|
|
level = syslog.convertBunyanLevel(level);
|
|
return new RegExp(format('^<%d>1$', facility * 8 + level));
|
|
}
|
|
function header(rec, token) {
|
|
if (arguments.length === 1) {
|
|
return getHeader({ msg: 'foo' })[rec];
|
|
}
|
|
rec.msg = rec.msg || 'foo';
|
|
return getHeader(rec)[token];
|
|
}
|
|
|
|
describe('priority', function () {
|
|
var DEF_FACILITY = SYSLOG.FACILITY[TEST.FACILITY];
|
|
it('should default the level to BUNYAN.INFO', function () {
|
|
header(0).should.match(priority(BUNYAN.INFO, DEF_FACILITY));
|
|
});
|
|
it('should default the facility to local0', function () {
|
|
var log = new SyslogStream();
|
|
getHeader('foo', log)[0].should.match(priority(BUNYAN.INFO, SYSLOG.FACILITY.LOCAL0));
|
|
});
|
|
it('should reflect explicitly specified levels', function () {
|
|
header({ level: 'fatal' }, 0).should.match(priority(BUNYAN.FATAL, DEF_FACILITY));
|
|
});
|
|
});
|
|
describe('time', function () {
|
|
it('should default the timestamp to the current time', function () {
|
|
var now = new Date();
|
|
var ts = new Date(header(1));
|
|
|
|
Math.abs(now-ts).should.be.within(0, 10);
|
|
});
|
|
it('should use the provided timestamp if given', function () {
|
|
var then = new Date();
|
|
then.setFullYear(then.getFullYear() - 1);
|
|
|
|
header({ time: then }, 1).should.equal(then.toISOString());
|
|
});
|
|
it('should use the NILVALUE if given false for the timestamp', function () {
|
|
header({ time: 'foo' }, 1).should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
it('should supply hostname', function () {
|
|
header(2).should.equal(TEST.HOSTNAME);
|
|
});
|
|
it('should supply appName', function () {
|
|
header(3).should.equal(TEST.NAME);
|
|
});
|
|
it('should supply procId', function () {
|
|
header(4).should.eql(String(process.pid));
|
|
});
|
|
it('should supply msgId', function () {
|
|
header(5).should.equal(TEST.MSG_ID);
|
|
});
|
|
it('should supply structuredData as NILVALUE when none is given', function () {
|
|
header(6).should.equal(SYSLOG.NILVALUE);
|
|
});
|
|
});
|
|
describe('structured data', function () {
|
|
function SD(r, log) {
|
|
r.msg = 'foo';
|
|
var msg = getMsg(r, log);
|
|
|
|
var matched = msg.split(' ').slice(6).join(' ').replace(/\\\\/, '').match(/(\[(\\\]|[^\]])+\])+/);
|
|
|
|
return matched ? matched[0] : '';
|
|
};
|
|
|
|
describe('standard SDIDs', function () {
|
|
describe('timeQuality', function () {
|
|
it('should validate with no arguments', function () {
|
|
SD({
|
|
timeQuality: { }
|
|
}).should.equal('[timeQuality]');
|
|
});
|
|
it('should accept tzKnown', function () {
|
|
SD({
|
|
timeQuality: { tzKnown: 1 }
|
|
}).should.equal('[timeQuality tzKnown="1"]');
|
|
});
|
|
it('should error if tzKnown is invalid', function () {
|
|
[null, 1.2, 3, -1, Infinity, { }].forEach(function (val) {
|
|
SD({ timeQuality: { tzKnown: val } }).should.equal('');
|
|
});
|
|
});
|
|
it('should accept isSynced', function () {
|
|
SD({
|
|
timeQuality: { isSynced: 0 }
|
|
}).should.equal('[timeQuality isSynced="0"]');
|
|
});
|
|
it('should error if isSynced is invalid', function () {
|
|
[null, 1.2, 3, -1, Infinity, { }].forEach(function (val) {
|
|
SD({ timeQuality: { isSynced: val} }).should.equal('');
|
|
});
|
|
});
|
|
it('should accept syncAccuracy', function () {
|
|
// Joi counts isSynced being undefined as being defined as 0,
|
|
// so must specify 'isSynced' here even though it's not required by the RFC
|
|
SD({
|
|
timeQuality: { isSynced: 1, syncAccuracy: 123 }
|
|
}).should.equal('[timeQuality isSynced="1" syncAccuracy="123"]');
|
|
});
|
|
it('should error if syncAccuracy is supplied when isSynced is 0', function () {
|
|
var rec = { timeQuality: { isSynced: 0, syncAccuracy: 123 } };
|
|
SD(rec).should.equal('');
|
|
rec.msg = 'foo';
|
|
getMsg(rec).should.match(/syncAccuracy is not allowed/);
|
|
});
|
|
});
|
|
describe('origin', function () {
|
|
it('should validate with no arguments', function () {
|
|
SD({ origin: { } }).should.equal('[origin]');
|
|
});
|
|
it('should accept a single ip', function () {
|
|
SD({ origin: { ip: '127.0.0.1' } }).should.equal('[origin ip="127.0.0.1"]');
|
|
});
|
|
it('should accept a single hostname', function () {
|
|
SD({ origin: { ip: 'foo' } }).should.equal('[origin ip="foo"]');
|
|
SD({ origin: { ip: 'foo.bar' } }).should.equal('[origin ip="foo.bar"]');
|
|
});
|
|
it('should error on an invalid parameter for \'ip\'', function () {
|
|
var rec = { origin: { ip: '.' } };
|
|
SD(rec).should.equal('');
|
|
rec.msg = 'foo';
|
|
getMsg(rec).should.match(/ip must be a valid hostname/);
|
|
});
|
|
it('should accept an array', function () {
|
|
SD({ origin: { ip: ['127.0.0.1', '127.0.0.2'] } }).should.equal('[origin ip="127.0.0.1" ip="127.0.0.2"]');
|
|
});
|
|
it('should accept an enterpriseId', function () {
|
|
SD({ origin: { enterpriseId: '1234' } }).should.equal('[origin enterpriseId="1234"]');
|
|
});
|
|
it('should accept a software name', function () {
|
|
SD({ origin: { software: 'poop' } }).should.equal('[origin software="poop"]');
|
|
});
|
|
it('should accept a software version', function () {
|
|
SD({ origin: { swVersion: '4242' } }).should.equal('[origin swVersion="4242"]');
|
|
});
|
|
});
|
|
describe('meta', function () {
|
|
it('should validate with no arguments', function () {
|
|
SD({ meta: { } }).should.equal('[meta]');
|
|
});
|
|
// probably could/should implement this into the code
|
|
it('should accept a sequence id', function () {
|
|
SD({ meta: { sequenceId: 1 } }).should.equal('[meta sequenceId="1"]');
|
|
});
|
|
it('should accept system uptime', function () {
|
|
SD({ meta: { sysUpTime: 1234 } }).should.equal('[meta sysUpTime="1234"]');
|
|
});
|
|
it('should accept a language', function () {
|
|
SD({ meta: { language: 'en-us' } }).should.equal('[meta language="en-us"]');
|
|
});
|
|
it('should error on an invalid BCP_47 language tag', function () {
|
|
['en_US', 1234, 'jabberwocky', null].forEach(function(val) {
|
|
SD({ meta: { language: val } }).should.equal('');
|
|
});
|
|
});
|
|
});
|
|
it('should accept everything', function () {
|
|
SD({
|
|
timeQuality: {
|
|
tzKnown: 1,
|
|
isSynced: 1,
|
|
syncAccuracy: 123
|
|
},
|
|
origin: {
|
|
ip: ['127.0.0.1', 'foo.bar'],
|
|
enterpriseId: '3434.34355',
|
|
software: 'keke',
|
|
swVersion: '1.2.3'
|
|
},
|
|
meta: {
|
|
sequenceId: 55,
|
|
sysUpTime: 21355,
|
|
language: 'fr'
|
|
}
|
|
}).should.equal(
|
|
'[timeQuality tzKnown="1" isSynced="1" syncAccuracy="123"]'+
|
|
'[origin ip="127.0.0.1" ip="foo.bar" enterpriseId="3434.34355" software="keke" swVersion="1.2.3"]'+
|
|
'[meta sequenceId="55" sysUpTime="21355" language="fr"]'
|
|
);
|
|
});
|
|
});
|
|
describe('custom SDIDs', function () {
|
|
var PEN = TEST.PEN;
|
|
it('should not produce custom structured data if PEN is invalid', function () {
|
|
var log = new SyslogStream({
|
|
PEN: 'foo'
|
|
});
|
|
SD({ foo: { bar: 123 } }, log).should.equal('');
|
|
});
|
|
it('should format any extra keys as structured data; SDID should contain the PEN', function () {
|
|
SD({ foo: { bar: 123 } }).should.equal('[foo@'+PEN+' bar="123"]');
|
|
});
|
|
it('should not create any structured data if there is no PEN', function () {
|
|
var _useSD = syslog.useStructuredData;
|
|
syslog.useStructuredData = false;
|
|
SD({ foo: { bar: 123 } }).should.equal('');
|
|
syslog.useStructuredData = _useSD;
|
|
});
|
|
it('should not format keys that are not maps', function () {
|
|
['bar', new Date(), true, /./].forEach(function (val) {
|
|
var rec = { foo: val };
|
|
SD(rec).should.equal('');
|
|
rec.foo.should.equal(val);
|
|
rec.should.not.have.property('SD_VALIDATION_ERROR');
|
|
});
|
|
});
|
|
it('should not format keys that are illegal SDID values', function () {
|
|
var rec = { '@': { invalid: 'true' } };
|
|
SD(rec).should.equal('');
|
|
rec['@'].invalid.should.equal('true');
|
|
rec.should.not.have.property('SD_VALIDATION_ERROR');
|
|
});
|
|
it('should accept arrays', function () {
|
|
SD({ foo: { bar: [ 1, 2, 3 ] } }).should.equal('[foo@'+PEN+' bar="1" bar="2" bar="3"]');
|
|
});
|
|
});
|
|
});
|
|
describe('write', function () {
|
|
it('should provide any data not converted to structured data as JSON', function () {
|
|
getMsg({
|
|
msg: 'hai',
|
|
'@': 'foo'
|
|
}).should.match(/{"@":"foo"}$/);
|
|
});
|
|
it('should not be destructive to the passed object', function () {
|
|
var rec = { level: 'warn', msg: 'foo' };
|
|
syslog.write(rec);
|
|
rec.should.eql({
|
|
level: 'warn',
|
|
msg: 'foo'
|
|
});
|
|
});
|
|
it('should convert a buffer to a string', function () {
|
|
var _decodeBuffers = syslog.decodeBuffers;
|
|
syslog.decodeBuffers = true;
|
|
getMsg(new Buffer('foo')).should.match(/foo$/);
|
|
syslog.decodeBuffers = _decodeBuffers;
|
|
});
|
|
it('should decode JSON if possible', function () {
|
|
var _decodeJSON = syslog.decodeJSON;
|
|
syslog.decodeJSON = true;
|
|
getMsg('{"msg":"foo"}').should.match(/foo$/);
|
|
syslog.decodeJSON = _decodeJSON;
|
|
});
|
|
});
|
|
describe('formatObject', function () {
|
|
it('should flag circular references', function () {
|
|
var obj = { };
|
|
obj.foo = obj;
|
|
getMsg(obj).should.match(/\{"foo":"\[Circular\]"\}$/);
|
|
});
|
|
});
|
|
describe('convertBunyanLevel', function () {
|
|
it('should return the correct syslog mapping for the given bunyan level', function () {
|
|
[ [ BUNYAN.FATAL, SYSLOG.LEVEL.EMERG ],
|
|
[ BUNYAN.ERROR, SYSLOG.LEVEL.ERR ],
|
|
[ BUNYAN.WARN, SYSLOG.LEVEL.WARNING ],
|
|
[ BUNYAN.INFO, SYSLOG.LEVEL.NOTICE ],
|
|
[ BUNYAN.DEBUG, SYSLOG.LEVEL.INFO ],
|
|
[ BUNYAN.TRACE, SYSLOG.LEVEL.DEBUG ] ]
|
|
.forEach(function (pair) {
|
|
syslog.convertBunyanLevel(pair[0]).should.equal(pair[1]);
|
|
});
|
|
});
|
|
it('should return a valid syslog mapping for other log values not mapped directly to bunyan log names', function () {
|
|
[ [ 99, SYSLOG.LEVEL.EMERG ],
|
|
[ 53, SYSLOG.LEVEL.ERR ],
|
|
[ 42, SYSLOG.LEVEL.WARNING ],
|
|
[ 31, SYSLOG.LEVEL.NOTICE ],
|
|
[ 28, SYSLOG.LEVEL.INFO ],
|
|
[ 11, SYSLOG.LEVEL.DEBUG ],
|
|
[ 7, SYSLOG.LEVEL.DEBUG ],
|
|
[ 'foo', SYSLOG.LEVEL.NOTICE ] ]
|
|
.forEach(function (pair) {
|
|
syslog.convertBunyanLevel(pair[0]).should.equal(pair[1]);
|
|
});
|
|
});
|
|
it('should accept (case-insensitive) strings', function () {
|
|
[ [ 'Fatal', SYSLOG.LEVEL.EMERG ],
|
|
[ 'Error', SYSLOG.LEVEL.ERR ],
|
|
[ 'Warn', SYSLOG.LEVEL.WARNING ],
|
|
[ 'infO', SYSLOG.LEVEL.NOTICE ],
|
|
[ 'debuG', SYSLOG.LEVEL.INFO ],
|
|
[ 'tracE', SYSLOG.LEVEL.DEBUG ] ]
|
|
.forEach(function (pair) {
|
|
syslog.convertBunyanLevel(pair[0]).should.equal(pair[1]);
|
|
});
|
|
});
|
|
it('should return the syslog notice level for invalid values', function () {
|
|
[null, new Date(), 'foo', [ ]]
|
|
.forEach(function (val) {
|
|
syslog.convertBunyanLevel(val).should.equal(SYSLOG.LEVEL.NOTICE);
|
|
});
|
|
});
|
|
});
|
|
describe('bunyan record', function () {
|
|
it('should output a message', function () {
|
|
getMsg({
|
|
msg: 'foo'
|
|
}).should.match(/foo$/);
|
|
});
|
|
it('should process structured data', function () {
|
|
getMsg({
|
|
msg: 'hai',
|
|
'@': 'foo'
|
|
}).should.match(/{"@":"foo"}$/);
|
|
|
|
getMsg({
|
|
msg: 'foo',
|
|
timeQuality: {
|
|
tzKnown: 1,
|
|
isSynced: 1,
|
|
syncAccuracy: 123
|
|
},
|
|
origin: {
|
|
ip: ['127.0.0.1', 'foo.bar'],
|
|
enterpriseId: '3434.34355',
|
|
software: 'keke',
|
|
swVersion: '1.2.3'
|
|
},
|
|
meta: {
|
|
sequenceId: 55,
|
|
sysUpTime: 21355,
|
|
language: 'fr'
|
|
}
|
|
}).should.containEql(
|
|
'[timeQuality tzKnown="1" isSynced="1" syncAccuracy="123"]'+
|
|
'[origin ip="127.0.0.1" ip="foo.bar" enterpriseId="3434.34355" software="keke" swVersion="1.2.3"]'+
|
|
'[meta sequenceId="55" sysUpTime="21355" language="fr"]'
|
|
);
|
|
});
|
|
it('should fall back on JSON with invalid data', function () {
|
|
getMsg({
|
|
v: 'bar',
|
|
msg: 'foo'
|
|
}).should.containEql('{"v":"bar","msg":"foo"}');
|
|
});
|
|
});
|
|
describe('glossy record', function () {
|
|
it('should output a message', function () {
|
|
getMsg({
|
|
message: 'foo'
|
|
}).should.match(/foo$/);
|
|
});
|
|
it('should process structured data', function () {
|
|
getMsg({
|
|
message: 'hai',
|
|
structuredData: {
|
|
'@': 'foo'
|
|
}
|
|
}).should.match(/{"@":"foo"}$/);
|
|
|
|
getMsg({
|
|
message: 'foo',
|
|
structuredData: {
|
|
timeQuality: {
|
|
tzKnown: 1,
|
|
isSynced: 1,
|
|
syncAccuracy: 123
|
|
},
|
|
origin: {
|
|
ip: ['127.0.0.1', 'foo.bar'],
|
|
enterpriseId: '3434.34355',
|
|
software: 'keke',
|
|
swVersion: '1.2.3'
|
|
},
|
|
meta: {
|
|
sequenceId: 55,
|
|
sysUpTime: 21355,
|
|
language: 'fr'
|
|
}
|
|
}
|
|
}).should.containEql(
|
|
'[timeQuality tzKnown="1" isSynced="1" syncAccuracy="123"]'+
|
|
'[origin ip="127.0.0.1" ip="foo.bar" enterpriseId="3434.34355" software="keke" swVersion="1.2.3"]'+
|
|
'[meta sequenceId="55" sysUpTime="21355" language="fr"]'
|
|
);
|
|
});
|
|
it('should fall back on JSON with invalid data', function () {
|
|
getMsg({
|
|
appName: null,
|
|
message: 'foo'
|
|
}).should.containEql('{"appName":null,"message":"foo"}');
|
|
});
|
|
});
|
|
});
|