Skip to content

Commit

Permalink
feat: add optional logging context (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
BillDorn authored Aug 31, 2020
1 parent 99e2c6d commit 85c4837
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 16 deletions.
39 changes: 23 additions & 16 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ function omit(obj, omitKey) {
}, {});
}

function logBundleWarning(index, message, value) {
function logBundleWarning(index, message, value, context) {
if(value === undefined) {
console.log('WARNING: config[%d] has %s.', index, message);
console.log('WARNING: config[%d] has %s.%s', index, message, context);
} else {
console.log('WARNING: config[%d] has %s. %s', index, message, value);
console.log('WARNING: config[%d] has %s. %s%s', index, message, value, context);
}
}

Expand All @@ -80,6 +80,10 @@ function Ycb(bundle, options) {
this.tree = new Map();
this.masterDelta = undefined;
this.dimensions = [];
this.logContext = '';
if(this.options.logContext !== undefined) {
this.logContext = ' source=' + this.options.logContext;
}
this._processRawBundle(cloneDeep(bundle));
}
Ycb.prototype = {
Expand Down Expand Up @@ -519,12 +523,12 @@ Ycb.prototype = {
for(var i=0; i<config.length; i++) {
var configObj = config[i];
if(!isA(configObj, Object)) {
logBundleWarning(i, 'non-object config', JSON.stringify(configObj));
logBundleWarning(i, 'non-object config', JSON.stringify(configObj), this.logContext);
continue;
}
if(!configObj.settings) {
if(!configObj.dimensions) {
logBundleWarning(i, 'no valid settings field', JSON.stringify(configObj));
logBundleWarning(i, 'no valid settings field', JSON.stringify(configObj), this.logContext);
}
continue;
}
Expand All @@ -537,34 +541,34 @@ Ycb.prototype = {
var settingSchedule = setting.schedule;
var interval = undefined;
if(Object.keys(config[i]).length === 1) { //Don't skip as empty configs are valid and appear on tree walk
logBundleWarning(i, 'empty config', JSON.stringify(settingDimensions));
logBundleWarning(i, 'empty config', JSON.stringify(settingDimensions), this.logContext);
}
if(!Array.isArray(settingDimensions)) {
logBundleWarning(i, 'non-array settings', JSON.stringify(settingDimensions));
logBundleWarning(i, 'non-array settings', JSON.stringify(settingDimensions), this.logContext);
continue;
}
if(settingDimensions.length === 0 ) {
logBundleWarning(i, 'empty settings array');
logBundleWarning(i, 'empty settings array', undefined, this.logContext);
continue;
}
if(settingSchedule !== undefined) {
interval = {start: 0, end: SENTINEL_TIME};
if(settingSchedule.start === undefined && settingSchedule.end === undefined){
logBundleWarning(i, 'empty schedule', JSON.stringify(setting));
logBundleWarning(i, 'empty schedule', JSON.stringify(setting), this.logContext);
continue;
}
if(settingSchedule.start !== undefined) {
var startDate = new Date(settingSchedule.start);
if(isNaN(startDate)) {
logBundleWarning(i, 'invalid start date', JSON.stringify(settingSchedule));
logBundleWarning(i, 'invalid start date', JSON.stringify(settingSchedule), this.logContext);
continue;
}
interval.start = startDate.getTime();
}
if(settingSchedule.end !== undefined) {
var endDate = new Date(settingSchedule.end);
if(isNaN(endDate)) {
logBundleWarning(i, 'invalid end date', JSON.stringify(settingSchedule));
logBundleWarning(i, 'invalid end date', JSON.stringify(settingSchedule), this.logContext);
continue;
}
interval.end = endDate.getTime();
Expand All @@ -573,7 +577,8 @@ Ycb.prototype = {
}
if(settingDimensions[0] === 'master') {
if(settingDimensions.length > 1) {
logBundleWarning(i, 'master setting with additional dimensions', JSON.stringify(settingDimensions));
logBundleWarning(i, 'master setting with additional dimensions',
JSON.stringify(settingDimensions), this.logContext);
continue;
}
if(this.masterDelta !== undefined) { //if master delta has been set than combine with existing one
Expand All @@ -592,13 +597,15 @@ Ycb.prototype = {
for(var j=0; j<settingDimensions.length; j++) {
var kv = settingDimensions[j].split(':');
if(kv.length !== 2) {
logBundleWarning(i, 'invalid setting ' + settingDimensions[j], JSON.stringify(settingDimensions));
logBundleWarning(i, 'invalid setting ' + settingDimensions[j],
JSON.stringify(settingDimensions), this.logContext);
continue configLoop;
}
var dim = kv[0];
var index = allDimensions[dim];
if(index === undefined) {
logBundleWarning(i, 'invalid dimension ' + dim, JSON.stringify(settingDimensions));
logBundleWarning(i, 'invalid dimension ' + dim,
JSON.stringify(settingDimensions), this.logContext);
continue configLoop;
}
usedDimensions[dim] = 1;
Expand Down Expand Up @@ -885,7 +892,7 @@ Ycb.prototype = {
newValue.push(0);
} else {
logBundleWarning(configIndex, 'invalid value ' + valueChunk + ' for dimension ' + dimensionName,
JSON.stringify(setting));
JSON.stringify(setting), this.logContext);
}
}
if(newValue.length === 0) {
Expand All @@ -897,7 +904,7 @@ Ycb.prototype = {
newContext[activeIndex] = this.valueToNumber[dimensionName][contextValue];
} else if(contextValue !== DEFAULT) {
logBundleWarning(configIndex, 'invalid value ' + contextValue + ' for dimension ' + dimensionName,
JSON.stringify(setting));
JSON.stringify(setting), this.logContext);
return;
}
}
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,46 @@ describe('ycb unit tests', function () {
assert.equal(count, 10, 'the valid empty config should be included');
});

it('should add the logging context', function () {
var bundle, ycb;
bundle = readFixtureFile('dimensions.json')
.concat(readFixtureFile('simple-1.json'))
.concat(readFixtureFile('bad-configs.json'))
.concat(readFixtureFile('simple-3.json'));
var logHistory = [];
var oldLog = console.log;
console.log = function(...args) {
logHistory.push(util.format(...args));
}
ycb = new libycb.Ycb(bundle, {logContext: '/bundle-path.json'});
console.log = oldLog;
assert.equal(logHistory[0], 'WARNING: config[2] has non-object config. [] source=/bundle-path.json','warning log should match');
assert.equal(logHistory[1], 'WARNING: config[3] has non-object config. null source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[2], 'WARNING: config[4] has non-object config. true source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[3], 'WARNING: config[5] has no valid settings field. {} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[4], 'WARNING: config[6] has no valid settings field. {"foo":"bar"} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[5], 'WARNING: config[7] has empty config. ["environment:production"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[6], 'WARNING: config[8] has no valid settings field. {"settings":null} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[7], 'WARNING: config[9] has empty settings array. source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[8], 'WARNING: config[10] has master setting with additional dimensions. ["master","lang:fr"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[9], 'WARNING: config[11] has invalid setting master. ["lang:fr","master"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[10], 'WARNING: config[13] has invalid dimension blah. ["blah:fr"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[11], 'WARNING: config[14] has empty config. ["master"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[12], 'WARNING: config[14] has empty schedule. {"dimensions":["master"],"schedule":{}} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[13], 'WARNING: config[15] has empty config. ["master"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[14], 'WARNING: config[15] has invalid start date. {"start":"bad"} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[15], 'WARNING: config[16] has empty config. ["master"] source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[16], 'WARNING: config[16] has invalid end date. {"end":"bad"} source=/bundle-path.json', 'warning log should match');
assert.equal(logHistory[17], 'WARNING: config[12] has invalid value barbar for dimension lang. {"dimensions":["lang:barbar"]} source=/bundle-path.json', 'warning log should match');

var count = 0;
ycb.walkSettings(function() {
count++;
return true;
});
assert.equal(count, 10, 'the valid empty config should be included');
});

it('should not break if there are no dimensions', function () {
var bundle, ycb;
bundle = readFixtureFile('simple-1.json')
Expand Down

0 comments on commit 85c4837

Please sign in to comment.