Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding log level methods when using Logger class #2351

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Create log level methods for Logger class
danilobatistaqueiroz committed Sep 18, 2023
commit 398de1967ae92af131817c241d3d59410ecbabc2
59 changes: 1 addition & 58 deletions lib/winston/create-logger.js
Original file line number Diff line number Diff line change
@@ -7,14 +7,8 @@

'use strict';

const { LEVEL } = require('triple-beam');
const config = require('./config');
const Logger = require('./logger');
const debug = require('@dabh/diagnostics')('winston:create-logger');

function isLevelEnabledFunctionName(level) {
return 'is' + level.charAt(0).toUpperCase() + level.slice(1) + 'Enabled';
}

/**
* Create a new instance of a winston Logger. Creates a new
@@ -47,58 +41,7 @@ module.exports = function (opts = {}) {

const logger = new DerivedLogger(opts);

//
// Create the log level methods for the derived logger.
//
Object.keys(opts.levels).forEach(function (level) {
debug('Define prototype method for "%s"', level);
if (level === 'log') {
// eslint-disable-next-line no-console
console.warn('Level "log" not defined: conflicts with the method "log". Use a different level name.');
return;
}

//
// Define prototype methods for each log level e.g.:
// logger.log('info', msg) implies these methods are defined:
// - logger.info(msg)
// - logger.isInfoEnabled()
//
// Remark: to support logger.child this **MUST** be a function
// so it'll always be called on the instance instead of a fixed
// place in the prototype chain.
//
DerivedLogger.prototype[level] = function (...args) {
// Prefer any instance scope, but default to "root" logger
const self = this || logger;

// Optimize the hot-path which is the single object.
if (args.length === 1) {
const [msg] = args;
const info = msg && msg.message && msg || { message: msg };
info.level = info[LEVEL] = level;
self._addDefaultMeta(info);
self.write(info);
return (this || logger);
}

// When provided nothing assume the empty string
if (args.length === 0) {
self.log(level, '');
return self;
}

// Otherwise build argument list which could potentially conform to
// either:
// . v3 API: log(obj)
// 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
return self.log(level, ...args);
};

DerivedLogger.prototype[isLevelEnabledFunctionName(level)] = function () {
return (this || logger).isLevelEnabled(level);
};
});
logger.createLogLevelMethods(logger, opts.levels);

return logger;
};
52 changes: 52 additions & 0 deletions lib/winston/logger.js
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ const LegacyTransportStream = require('winston-transport/legacy');
const Profiler = require('./profiler');
const { warn } = require('./common');
const config = require('./config');
const debug = require('@dabh/diagnostics')('winston:create-logger');

/**
* Captures the number of format (i.e. %s strings) in a given string.
@@ -149,6 +150,57 @@ class Logger extends Transform {
}
}

//
// Create the log level methods for the derived logger.
//
createLogLevelMethods(logger, levels) {
Object.keys(levels).forEach(function (level) {
debug('Define prototype method for "%s"', level);
if (level === 'log') {
// eslint-disable-next-line no-console
console.warn('Level "log" not defined: conflicts with the method "log". Use a different level name.');
return;
}
//
// Define prototype methods for each log level e.g.:
// logger.log('info', msg) implies these methods are defined:
// - logger.info(msg)
// - logger.isInfoEnabled()
//
// Remark: to support logger.child this **MUST** be a function
// so it'll always be called on the instance instead of a fixed
// place in the prototype chain.
//
Logger.prototype[level] = function (...args) {
// Prefer any instance scope, but default to "root" logger
const self = this || logger;
// Optimize the hot-path which is the single object.
if (args.length === 1) {
const [msg] = args;
const info = msg && msg.message && msg || { message: msg };
info.level = info[LEVEL] = level;
self._addDefaultMeta(info);
self.write(info);
return (this || logger);
}
// When provided nothing assume the empty string
if (args.length === 0) {
self.log(level, '');
return self;
}
// Otherwise build argument list which could potentially conform to
// either:
// . v3 API: log(obj)
// 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
return self.log(level, ...args);
};
const isLevelEnabledFunctionName = 'is' + level.charAt(0).toUpperCase() + level.slice(1) + 'Enabled';
Logger.prototype[isLevelEnabledFunctionName] = function () {
return (this || logger).isLevelEnabled(level);
};
});
}

isLevelEnabled(level) {
const givenLevelValue = getLevelValue(this.levels, level);
if (givenLevelValue === null) {