Not possible to extend
Closed this issue · 2 comments
Your code style make it really impossible to extend an appender
e.g. i want to use my own "formatLevel" function within RollingFileAppender, because i add a "success" LogLevel and want to add more spaces to all other LogLevels.
With AbstractAppender.extend( this, options );
you create a new Class that will be extended with the existing function methods, but this let us not overwrite AbstractAppender functions.
If you could change your style to .prototype, then we can extend RollingFileAppender with our own method.
The same problem exists when you create your own Appender, hope the code sample explain it better.
e.g. my ColoredConsoleAppender, i set a comments in the code where the problem is:
const logLevels = [ 'all', 'trace', 'debug', 'info', 'success', 'warn', 'error', 'fatal' ]
const colors = {
trace : (text) => chalk.blueBright(text),
debug : (text) => chalk.cyanBright(text),
info : (text) => chalk.white(text),
success: (text) => chalk.greenBright(text),
warn : (text) => chalk.yellowBright(text),
error : (text) => chalk.red(text),
fatal : (text) => chalk.red.inverse(text)
}
const formatLevel = function(level) {
let str = level.toUpperCase()
// pad space right
for (let i = str.length; i < 7; i++) {
str += ' ';
}
return str;
}
const ColoredConsoleAppender = function(opts) {
const appender = this
const options = Object.assign({}, opts)
options.typeName = 'ColoredConsoleAppender'
const writer = options.writer || console.log
let level = options.level || logLevels[0]
let levels = options.levels || logLevels
let currentLevel = levels.indexOf( level )
//
// Here we create a new Class and extend only methods from this, but we cant overwrite AbstracAppender
//
let appendWithin = Logger.AbstractAppender.extend( this, options )
//
// to use my own function i need to add this code INSIDE this function
// but i cant do this in your RollingFileAppender without copy the whole code.
// From outside, i did not have access to the appendWithin var, whichwe created above
//
appendWithin .formatLevel = formatLevel
this.formatter = function(entry) {
const fields = appender.formatEntry( entry )
let colorize = colors[entry.level] || function(text) { return text }
return colorize( fields.join( appender.separator ) )
}
this.write = function(entry) {
if (levels.indexOf( entry.level ) >= currentLevel) {
writer( appender.formatter( entry ))
}
}
this.setLevel = function(level) {
const idx = levels.indexOf( level )
if (idx >= 0) {
currentLevel = idx
}
}
}
The problem is in AbstractAppender's formatEntry() method; it's calling it's own methods that are defined at construction time, not override-time. Lots of ways that this could be fixed, probably the easiest is to add a second parameter to formatEntry(entry, thisArg) where thisArg is the overriding object (similar to javascript iteration). I will do this for version 0.93.32...
@darrylwest Is this possible to do yet? Current version is 0.93.40