Merge pull request #5038 from simianhacker/filter-logs-fix
Adding filtering to the logger
This commit is contained in:
commit
3cda9ade6c
|
@ -61,7 +61,7 @@ module.exports = Joi.object({
|
||||||
|
|
||||||
events: Joi.any().default({}),
|
events: Joi.any().default({}),
|
||||||
dest: Joi.string().default('stdout'),
|
dest: Joi.string().default('stdout'),
|
||||||
|
filter: Joi.any().default({}),
|
||||||
json: Joi.boolean()
|
json: Joi.boolean()
|
||||||
.when('dest', {
|
.when('dest', {
|
||||||
is: 'stdout',
|
is: 'stdout',
|
||||||
|
|
|
@ -6,6 +6,7 @@ let ansicolors = require('ansicolors');
|
||||||
let stringify = require('json-stringify-safe');
|
let stringify = require('json-stringify-safe');
|
||||||
let querystring = require('querystring');
|
let querystring = require('querystring');
|
||||||
let inspect = require('util').inspect;
|
let inspect = require('util').inspect;
|
||||||
|
let applyFiltersToKeys = require('./applyFiltersToKeys');
|
||||||
|
|
||||||
function serializeError(err) {
|
function serializeError(err) {
|
||||||
return {
|
return {
|
||||||
|
@ -24,16 +25,23 @@ let levelColor = function (code) {
|
||||||
return ansicolors.red(code);
|
return ansicolors.red(code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = class TransformObjStream extends Stream.Transform {
|
module.exports = class TransformObjStream extends Stream.Transform {
|
||||||
constructor() {
|
constructor(config) {
|
||||||
super({
|
super({
|
||||||
readableObjectMode: false,
|
readableObjectMode: false,
|
||||||
writableObjectMode: true
|
writableObjectMode: true
|
||||||
});
|
});
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter(data) {
|
||||||
|
if (!this.config.filter) return data;
|
||||||
|
return applyFiltersToKeys(data, this.config.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
_transform(event, enc, next) {
|
_transform(event, enc, next) {
|
||||||
var data = this.readEvent(event);
|
var data = this.filter(this.readEvent(event));
|
||||||
this.push(this.format(data) + '\n');
|
this.push(this.format(data) + '\n');
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ let LogFormatString = require('./LogFormatString');
|
||||||
module.exports = class KbnLogger {
|
module.exports = class KbnLogger {
|
||||||
constructor(events, config) {
|
constructor(events, config) {
|
||||||
this.squeeze = new Squeeze(events);
|
this.squeeze = new Squeeze(events);
|
||||||
this.format = config.json ? new LogFormatJson() : new LogFormatString();
|
this.format = config.json ? new LogFormatJson(config) : new LogFormatString(config);
|
||||||
|
|
||||||
if (config.dest === 'stdout') {
|
if (config.dest === 'stdout') {
|
||||||
this.dest = process.stdout;
|
this.dest = process.stdout;
|
||||||
|
|
39
src/server/logging/__tests__/applyFiltersToKeys.js
Normal file
39
src/server/logging/__tests__/applyFiltersToKeys.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
var applyFiltersToKeys = require('../applyFiltersToKeys');
|
||||||
|
var expect = require('expect.js');
|
||||||
|
|
||||||
|
describe('applyFiltersToKeys(obj, actionsByKey)', function () {
|
||||||
|
it('applies for each key+prop in actionsByKey', function () {
|
||||||
|
var data = applyFiltersToKeys({
|
||||||
|
a: {
|
||||||
|
b: {
|
||||||
|
c: 1
|
||||||
|
},
|
||||||
|
d: {
|
||||||
|
e: 'foobar'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
headers: {
|
||||||
|
authorization: 'Basic dskd939k2i'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
b: 'remove',
|
||||||
|
e: 'censor',
|
||||||
|
authorization: '/([^\\s]+)$/'
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(data).to.eql({
|
||||||
|
a: {
|
||||||
|
d: {
|
||||||
|
e: 'XXXXXX',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
headers: {
|
||||||
|
authorization: 'Basic XXXXXXXXXX'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
42
src/server/logging/applyFiltersToKeys.js
Normal file
42
src/server/logging/applyFiltersToKeys.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
function toPojo(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
function replacer(match, group) {
|
||||||
|
return (new Array(group.length + 1).join('X'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply(obj, key, action) {
|
||||||
|
for (let k in obj) {
|
||||||
|
if (obj.hasOwnProperty(k)) {
|
||||||
|
let val = obj[k];
|
||||||
|
if (k === key) {
|
||||||
|
if (action === 'remove') {
|
||||||
|
delete obj[k];
|
||||||
|
}
|
||||||
|
else if (action === 'censor' && typeof val === 'object') {
|
||||||
|
delete obj[key];
|
||||||
|
}
|
||||||
|
else if (action === 'censor') {
|
||||||
|
obj[k] = ('' + val).replace(/./g, 'X');
|
||||||
|
}
|
||||||
|
else if (/\/.+\//.test(action)) {
|
||||||
|
var matches = action.match(/\/(.+)\//);
|
||||||
|
if (matches) {
|
||||||
|
let regex = new RegExp(matches[1]);
|
||||||
|
obj[k] = ('' + val).replace(regex, replacer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (typeof val === 'object') {
|
||||||
|
val = apply(val, key, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (obj, actionsByKey) {
|
||||||
|
return Object.keys(actionsByKey).reduce((output, key) => {
|
||||||
|
return apply(output, key, actionsByKey[key]);
|
||||||
|
}, toPojo(obj));
|
||||||
|
};
|
|
@ -42,7 +42,14 @@ module.exports = function (kbnServer, server, config) {
|
||||||
reporter: require('./LogReporter'),
|
reporter: require('./LogReporter'),
|
||||||
config: {
|
config: {
|
||||||
json: config.get('logging.json'),
|
json: config.get('logging.json'),
|
||||||
dest: config.get('logging.dest')
|
dest: config.get('logging.dest'),
|
||||||
|
// I'm adding the default here because if you add another filter
|
||||||
|
// using the commandline it will remove authorization. I want users
|
||||||
|
// to have to explicitly set --logging.filter.authorization=none to
|
||||||
|
// have it show up int he logs.
|
||||||
|
filter: _.defaults(config.get('logging.filter'), {
|
||||||
|
authorization: 'remove'
|
||||||
|
})
|
||||||
},
|
},
|
||||||
events: _.transform(events, function (filtered, val, key) {
|
events: _.transform(events, function (filtered, val, key) {
|
||||||
// provide a string compatible way to remove events
|
// provide a string compatible way to remove events
|
||||||
|
|
Loading…
Reference in a new issue