@ayanaware/logger
Version:
Useful and great looking logging made easy
291 lines • 12.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
const path = require("path");
const PackageDetector_1 = require("./PackageDetector");
const LogLevel_1 = require("./constants/LogLevel");
const Config_1 = require("./config/Config");
const Transport_1 = require("./transports/Transport");
const Formatter_1 = require("./formatter/Formatter");
const DefaultFormatter_1 = require("./formatter/default/DefaultFormatter");
/**
* Logger main class. Use Logger.get() to create a new Logger.
*/
class Logger {
constructor(name, pkgName, pkgPath, extra) {
if (typeof name === 'function') {
Object.defineProperty(this, 'name', {
get: name,
configurable: false,
enumerable: false,
});
}
else {
Object.defineProperty(this, 'name', {
value: name,
writable: false,
configurable: false,
enumerable: true,
});
}
if (typeof pkgName === 'function') {
Object.defineProperty(this, 'packageName', {
get: pkgName,
configurable: false,
enumerable: false,
});
}
else {
Object.defineProperty(this, 'packageName', {
value: pkgName,
writable: false,
configurable: false,
enumerable: true,
});
}
if (typeof pkgPath === 'function') {
Object.defineProperty(this, 'packagePath', {
get: pkgPath,
configurable: false,
enumerable: false,
});
}
else {
Object.defineProperty(this, 'packagePath', {
value: pkgPath,
writable: false,
configurable: false,
enumerable: true,
});
}
if (typeof extra !== 'object')
extra = {};
Object.defineProperty(this, 'extra', {
value: extra,
writable: false,
configurable: false,
enumerable: false,
});
}
/**
* Logs a message with [[LogLevel]] *ERROR*
*
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*
* @see Logger#log
*/
error(log, uniqueMarker, extra) {
this.log(LogLevel_1.LogLevel.ERROR, log, uniqueMarker, extra);
}
/**
* Logs a message with [[LogLevel]] *WARN*
*
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*
* @see Logger#log
*/
warn(log, uniqueMarker, extra) {
this.log(LogLevel_1.LogLevel.WARN, log, uniqueMarker, extra);
}
/**
* Logs a message with [[LogLevel]] *INFO*
*
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*
* @see Logger#log
*/
info(log, uniqueMarker, extra) {
this.log(LogLevel_1.LogLevel.INFO, log, uniqueMarker, extra);
}
/**
* Logs a message with [[LogLevel]] *DEBUG*
*
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*
* @see Logger#log
*/
debug(log, uniqueMarker, extra) {
this.log(LogLevel_1.LogLevel.DEBUG, log, uniqueMarker, extra);
}
/**
* Logs a message with [[LogLevel]] *TRACE*
*
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*
* @see Logger#log
*/
trace(log, uniqueMarker, extra) {
this.log(LogLevel_1.LogLevel.TRACE, log, uniqueMarker, extra);
}
/**
* Logs a message.
*
* @param level The log level
* @param log The string or error that should be logged. This can also be a function returning a string or an error. The function will only be called if the result is acutally logged
* @param uniqueMarker Optional. The unique marker for denoting different instances of a class
* @param extra Optional. An object containing additional data that can be used later on
*/
log(level, log, uniqueMarker, extra) {
let meta = null;
for (const transport of Config_1.Config.getInstance().transports) {
if (meta == null)
meta = transport.log(this, level, log, uniqueMarker, { ...Config_1.Config.getInstance().globalExtra, ...this.extra, ...extra });
else
transport.logMeta(meta);
}
}
/**
* Creates a new logger instance for the current context.
*
* @param name A string or a class for the loggers name.
* If left empty the current files name (excluding the file extension) will be used as the logger name.
* If set to an empty string the logger name will remain empty.
* @param extra Optional. An object containing additional data that will be appended on every log call
*
* @returns A new logger instance
*/
static get(name, extra) {
let loggerName;
if (name == null)
loggerName = null;
else if (typeof name === 'function')
loggerName = name.name;
else if (typeof name === 'string')
loggerName = name;
else
throw new Error('Logger.get(): Invalid name parameter. Pass nothing (null / undefined), a string or a named function');
let pkgName = '<unknown>';
// Relative path that gets printed in the end
let pkgPath = '<unknown>';
const callerFile = Logger.detector.getCallerFile();
if (callerFile != null) {
const callerDir = path.dirname(callerFile);
const projectRoot = Logger.detector.getRootOf(callerDir);
const pkg = Logger.detector.getInfo(projectRoot);
let pkgMain = '';
if (pkg.awLoggerRoot != null)
pkgMain = pkg.awLoggerRoot;
else if (pkg.main != null)
pkgMain = path.dirname(pkg.main);
// Project file root. Used as a base to find the package path
const pkgBase = path.join(projectRoot, pkgMain);
pkgName = pkg.name;
pkgPath = path.relative(pkgBase, callerDir);
if (loggerName == null) {
loggerName = path.basename(callerFile);
loggerName = loggerName.substr(0, loggerName.indexOf('.'));
}
}
// Check path starting with . or .. which means it is not a child of the pkgBase directory
if (pkgPath.startsWith('.'))
throw new Error('Logger.get(): This file is not in the logger base path for this project');
pkgPath = pkgPath.replace(path.sep, '.');
if (loggerName == null)
loggerName = '<unknown>';
if (pkgPath.length > 0 && loggerName !== '')
pkgPath = `${pkgPath}.`;
return new Logger(loggerName, pkgName, pkgPath, extra);
}
/**
* Creates a new custom logger instance without running any package detection.
* The first three arguments can also be functions returning the specified value so they can be changed.
* The functions will be called for every log-call.
*
* @param name The loggers name
* @param packageName The loggers package name
* @param packagePath The loggers package path (This should to end with a "." if it's not empty so it looks correct)
* @param extra Optional. An object containing additional data that will be appended on every log call
*
* @returns A new logger instance
*/
static custom(name, packageName, packagePath, extra) {
return new Logger(name, packageName, packagePath, extra);
}
/**
* Changes the global formatter.
* Note that this will affect every transport not explicitly defining their own formatter.
* If you want to only change the formatter on the default transport use `Logger.getDefaultTransport().setFormatter()`.
* The formatter must extend the class [[Formatter]].
* Alternatively `null` can be passed to reset the global formatter to the [[DefaultFormatter]].
*
* @param formatter The new global formatter
*/
static setFormatter(formatter) {
// Reset to default formatter if null or undefined is given
if (formatter == null)
formatter = new DefaultFormatter_1.DefaultFormatter();
// Check instance
if (!(formatter instanceof Formatter_1.Formatter))
throw new Error('Invalid formatter');
Config_1.Config.getInstance().formatter = formatter;
}
/**
* Adds a new transport.
* Note that the transport will get all logging data from every installed module that uses this logging library.
* The transport must extend the class [[Transport]].
*
* @param transport The transport to be added
*/
static addTransport(transport) {
if (transport == null)
return;
if (!(transport instanceof Transport_1.Transport))
throw new Error('Invalid transport');
Config_1.Config.getInstance().transports.push(transport);
}
/**
* Returns the default [[ConsoleTransport]] or null if the default transport has been disabled.
*
* @returns The default [[ConsoleTransport]]
*/
static getDefaultTransport() {
return Config_1.Config.getInstance().defaultTransport;
}
/**
* Disables the default [[ConsoleTransport]].
* Note that calling this will affect every installed module that uses this logging library.
*/
static disableDefaultTransport() {
Config_1.Config.getInstance().disableDefaultTransport();
}
/**
* Sets the global extra object applied to every log call.
*
* @param extra The global extra object
*/
static setGlobalExtra(extra) {
if (typeof extra !== 'object')
extra = {};
Config_1.Config.getInstance().globalExtra = extra;
}
/**
* Returns the current global extra object.
*
* @returns The current global extra object
*/
static getGlobalExtra() {
return Config_1.Config.getInstance().globalExtra;
}
/**
* Returns the version major of this package.
* This is used by @ayana/logger-api to determine compatibility.
*
* @returns The version major of this package.
*/
static getVersionMajor() {
return Number(Config_1.Config.getInstance().major);
}
}
exports.Logger = Logger;
Logger.detector = new PackageDetector_1.PackageDetector();
//# sourceMappingURL=Logger.js.map