You can create a custom Bunyan stream to filter out log records based on environment variables. This allows you to mute specific log entries without modifying the core library.
How it works:
- Define a custom stream class (e.g.,
MuteByEnvVars) that implements a write method. - The stream scans
process.env for keys starting with BUNYAN_MUTE_. - When a log record is written, the stream checks if any field in the record matches the corresponding environment variable value.
- If a match is found, the record is suppressed (muted). Otherwise, it is written to the underlying stream.
Usage Pattern:
- Set environment variables in the format
BUNYAN_MUTE_<field_path>=<value> before running your script. - Use dot notation for nested fields (e.g.,
BUNYAN_MUTE_user.id=123). - Attach the custom stream to your logger with
type: 'raw'.
Example:
var bunyan = require('bunyan');
function MuteByEnvVars(opts) {
opts = opts || {};
this.stream = opts.stream || process.stdout;
var PREFIX = 'BUNYAN_MUTE_';
this.mutes = {};
for (var k in process.env) {
if (k.indexOf(PREFIX) === 0) {
this.mutes[k.slice(PREFIX.length)] = process.env[k];
}
}
}
MuteByEnvVars.prototype._objectFromDotNotation = function (o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1');
s = s.replace(/^\./, '');
var a = s.split('.');
while (a.length) {
var n = a.shift();
if (n in o) {
o = o[n];
} else {
return;
}
}
return o;
}
MuteByEnvVars.prototype.write = function (rec) {
if (typeof (rec) !== 'object') {
console.error('error: MuteByEnvVars raw stream got a non-object record: %j', rec);
return;
}
var muteRec = false;
var keys = Object.keys(this.mutes);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
var match = this._objectFromDotNotation(rec, k);
if (match === this.mutes[k]) {
muteRec = true;
break;
}
}
if (!muteRec) {
this.stream.write(JSON.stringify(rec) + '\n');
}
}
var log = bunyan.createLogger({
name: 'mute-by-envvars-stream',
streams: [
{
level: 'info',
stream: new MuteByEnvVars(),
type: 'raw'
}
]
});
log.info('hi raw stream');
log.info({foo: 'bar'}, 'added "foo" key');
Running with Mute Rules:
To mute logs containing {foo: 'bar'}:
BUNYAN_MUTE_foo=bar node mute-by-envvars-stream.js
Notes:
- This is a custom implementation and may not be optimized for performance or edge cases.
- Nested fields must be accessed using dot notation in the environment variable key (e.g.,
BUNYAN_MUTE_user.name=John). - The stream treats all environment variable values as strings.
var bunyan = require('bunyan');
function MuteByEnvVars(opts) {
opts = opts || {};
this.stream = opts.stream || process.stdout;
var PREFIX = 'BUNYAN_MUTE_';
this.mutes = {};
for (var k in process.env) {
if (k.indexOf(PREFIX) === 0) {
this.mutes[k.slice(PREFIX.length)] = process.env[k];
}
}
}
MuteByEnvVars.prototype._objectFromDotNotation = function (o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1');
s = s.replace(/^\./, '');
var a = s.split('.');
while (a.length) {
var n = a.shift();
if (n in o) {
o = o[n];
} else {
return;
}
}
return o;
}
MuteByEnvVars.prototype.write = function (rec) {
if (typeof (rec) !== 'object') {
console.error('error: MuteByEnvVars raw stream got a non-object record: %j', rec);
return;
}
var muteRec = false;
var keys = Object.keys(this.mutes);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
var match = this._objectFromDotNotation(rec, k);
if (match === this.mutes[k]) {
muteRec = true;
break;
}
}
if (!muteRec) {
this.stream.write(JSON.stringify(rec) + '\n');
}
}
var log = bunyan.createLogger({
name: 'mute-by-envvars-stream',
streams: [
{
level: 'info',
stream: new MuteByEnvVars(),
type: 'raw'
}
]
});
log.info('hi raw stream');
log.info({foo: 'bar'}, 'added "foo" key');
Sources: examples/mute-by-envvars-stream.js