@athenna/logger
Version:
The Athenna logging solution. Log in stdout, files and buckets.
187 lines (186 loc) • 5.49 kB
JavaScript
/**
* @athenna/logger
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Config } from '@athenna/config';
import { Driver } from '#src/drivers/Driver';
import { Color, Json, Macroable } from '@athenna/common';
import { DriverFactory } from '#src/factories/DriverFactory';
import { VANILLA_CHANNELS } from '#src/constants/VanillaChannels';
export class Logger extends Macroable {
constructor() {
super();
/**
* The drivers responsible for transporting the logs.
*/
this.drivers = [];
/**
* Runtime configurations to be used inside the Drivers and Formatters.
*/
this.runtimeConfigs = {};
/**
* Store the current logger strategy so config() and create()
* can clone the logger preserving its behavior.
*/
this.selection = {
method: 'vanilla',
values: []
};
this.channelOrVanilla(Config.get('logging.default'));
}
/**
* Create a new standalone logger instance. Very
* useful to create new loggers without changing the
* channels that are already defined in the main instance.
*/
static standalone(...configs) {
const logger = new Logger();
logger.vanilla(...configs);
return logger;
}
/**
* Set runtime configurations for drivers and
* formatters.
*/
config(runtimeConfigs) {
this.runtimeConfigs = Json.copy(runtimeConfigs || {});
return this.applySelection();
}
/**
* Create a new logger instance inheriting the current
* configuration and adding default message content.
*/
create(defaults = {}) {
const logger = new Logger();
const runtimeConfigs = Json.copy(this.runtimeConfigs);
if (!runtimeConfigs.formatterConfig) {
runtimeConfigs.formatterConfig = {};
}
runtimeConfigs.formatterConfig.defaults = Json.copy(defaults);
logger.selection = {
method: this.selection.method,
values: Json.copy(this.selection.values)
};
return logger.config(runtimeConfigs);
}
/**
* Change the log channel.
*/
channel(...channels) {
this.drivers = [];
this.selection = {
method: 'channel',
values: [...channels]
};
channels.forEach(channel => {
const driver = DriverFactory.fabricate(channel, this.runtimeConfigs);
this.drivers.push(driver);
});
return this;
}
/**
* Change the log drivers using vanilla configurations.
* This method does not depend in Athenna configuration
* files to be executed.
*/
vanilla(...configs) {
this.drivers = [];
this.selection = {
method: 'vanilla',
values: Json.copy(configs)
};
if (!configs.length) {
this.drivers.push(DriverFactory.fabricateVanilla(this.runtimeConfigs));
return this;
}
configs.forEach(config => {
const driver = DriverFactory.fabricateVanilla({
...config,
...this.runtimeConfigs
});
this.drivers.push(driver);
});
return this;
}
/**
* Verify if channel configuration exists. If not, Athenna will
* use the default vanilla configurations as drivers.
*/
channelOrVanilla(channel, configs = {}) {
if (Config.exists(`logging.channels.${channel}`)) {
return this.channel(channel);
}
return this.vanilla({
...VANILLA_CHANNELS[channel],
...configs
});
}
/**
* Create a new standalone logger instance. Very
* useful to create new loggers without changing the
* channels that are already defined in the main instance.
*/
standalone(...configs) {
return Logger.standalone(...configs);
}
/**
* Creates a log of type trace in channel.
*/
trace(...args) {
return this.log('trace', ...args);
}
/**
* Creates a log of type debug in channel.
*/
debug(...args) {
return this.log('debug', ...args);
}
/**
* Creates a log of type info in channel.
*/
info(...args) {
return this.log('info', ...args);
}
/**
* Creates a log of type success in channel.
*/
success(...args) {
return this.log('success', ...args);
}
/**
* Creates a log of type warn in channel.
*/
warn(...args) {
return this.log('warn', ...args);
}
/**
* Creates a log of type error in channel.
*/
error(...args) {
return this.log('error', ...args);
}
/**
* Creates a log of type fatal in channel.
*/
fatal(...args) {
return this.log('fatal', ...args);
}
/**
* Call drivers to transport the log.
*/
async log(level, ...args) {
const message = Color.apply(...args);
const promises = this.drivers.map((driver) => driver.transport(level, message));
return Promise.all(promises);
}
/**
* Rebuild drivers using the current logger selection.
*/
applySelection() {
return this[this.selection.method](...Json.copy(this.selection.values));
}
}