///
import { LoggerLevel, ILoggerImpl } from "../types";
import { default as _BaseLoggerImpl, ColoredText as ColoredText_ } from "./baseimpl";
var BaseLoggerImpl: typeof _BaseLoggerImpl;
var ColoredText: typeof ColoredText_;
export = class NullLogger {
static active: ILoggerImpl;
private scopeCache: any;
readonly scopes: string[];
constructor(...scopes: string[]) {
this.scopes = scopes;
}
static makeColored(text: string, color: string | number) {
return new (ColoredText || (ColoredText = require("./baseimpl").ColoredText))(text, color);
}
static makeLoggerImpl() {
if (process.env.LOGGER_IMPL) {
var plugin = require(process.env.LOGGER_IMPL);
if(plugin.default)
return new (plugin.default);
return new plugin();
}
var plugins: any[] = [
"0-silent-logger",
"1-cli-color-logger",
"2-text-logger"
];
var $break = new Object();
var _impl: ILoggerImpl;
try {
plugins.forEach(function(plugin) {
try {
plugin = require("./impl/" + plugin);
_impl = new plugin();
} catch (e) {
return;
}
throw $break;
});
} catch (e) {
if (e !== $break)
throw e;
}
return _impl;
}
/**
* Log data to the specified implementation.
*
* @param level The logging level to use
* @param loggerOrScopes The logger, scope(s)
* @param messages The message data to log
* @param impl The logger implementation
*/
static log(level: LoggerLevel, loggerOrScopes: NullLogger | string[] | string, messages: any[], impl: ILoggerImpl = NullLogger.active) {
return (impl || NullLogger.active || (NullLogger.active = NullLogger.makeLoggerImpl())).log(level, loggerOrScopes, messages);
}
/**
* Log with gears level
*
* @param messages The message data to log
*/
static gears(...messages: any[]) {
NullLogger.log(LoggerLevel.Gears, undefined, messages);
}
/**
* Log with performance level
*
* @param messages The message data to log
*/
static performance(...messages: any[]) {
NullLogger.log(LoggerLevel.Performance, undefined, messages);
}
/**
* Log with performance level
*
* @param messages The message data to log
*/
static perf(...messages: any[]) {
NullLogger.log(LoggerLevel.Performance, undefined, messages);
}
/**
* Log with debugging level
*
* @param messages The message data to log
*/
static debugging(...messages: any[]) {
NullLogger.log(LoggerLevel.Debugging, undefined, messages);
}
/**
* Log with debugging level
*
* @param messages The message data to log
*/
static debug(...messages: any[]) {
NullLogger.log(LoggerLevel.Debugging, undefined, messages);
}
/**
* Log with information level
*
* @param messages The message data to log
*/
static info(...messages: any[]) {
NullLogger.log(LoggerLevel.Information, undefined, messages);
}
/**
* Log with information level
*
* @param messages The message data to log
*/
static information(...messages: any[]) {
NullLogger.log(LoggerLevel.Information, undefined, messages);
}
/**
* Log with warning level
*
* @param messages The message data to log
*/
static warn(...messages: any[]) {
NullLogger.log(LoggerLevel.Warning, undefined, messages);
}
/**
* Log with warning level
*
* @param messages The message data to log
*/
static warning(...messages: any[]) {
NullLogger.log(LoggerLevel.Warning, undefined, messages);
}
/**
* Log with error level
*
* @param messages The message data to log
*/
static error(...messages: any[]) {
NullLogger.log(LoggerLevel.Fatal, undefined, messages);
}
/**
* Log with fatal level, then exit with code 1
*
* @param messages The message data to log
*/
static fatal(...messages: any[]) {
NullLogger.log(LoggerLevel.Fatal, undefined, messages);
process.exit(1);
}
/**
* Change the minimum logging level
*
* @param level The new minimum logging level to use
*/
static setMinLevel(level: LoggerLevel | string) {
if(!BaseLoggerImpl)
BaseLoggerImpl = require("./baseimpl").default;
if(typeof level === "string")
BaseLoggerImpl.setMinLevel(level);
else
BaseLoggerImpl.MIN_LEVEL = level;
}
/**
* Return the minimum logging level
*/
static minLevel(): LoggerLevel {
if(!BaseLoggerImpl)
BaseLoggerImpl = require("./baseimpl").default;
return BaseLoggerImpl.MIN_LEVEL;
}
/**
* Return the filename of the logging implementation, when available
*/
static impl() {
return NullLogger.active.filename;
}
/**
* Log with gears level
*
* @param messages The message data to log
*/
gears(...messages: any[]) {
NullLogger.log(LoggerLevel.Gears, this, messages);
return this;
}
/**
* Measure the duration a function takes to execuse.
* If the function returns a promise, waits for the promise to complete.
*
* @param name The name of the timer
* @param impl The function implementation to measure
*/
timer(name: string, impl: (logger: NullLogger) => void | Promise) {
var logger = this.extend(name);
NullLogger.log(LoggerLevel.Timer, logger, ["Running function", name]);
var start = +new Date;
const promise = impl(logger);
if(promise instanceof Promise) {
promise.catch(function(err) {
NullLogger.log(LoggerLevel.Error, logger, ["Function", name, "errored:", err]);
});
promise.finally(function() {
NullLogger.log(LoggerLevel.Timer, logger, ["Function", name, "took " + ((+new Date) - start) + "ms."]);
});
} else
NullLogger.log(LoggerLevel.Timer, logger, ["Function", name, "took " + ((+new Date) - start) + "ms."]);
return this;
}
/**
* Measure the duration a function takes to execuse, in a inherently asynchronious way.
*
* @param name The name of the timer
* @param impl The function implementation to measure
*/
timerAsync(name: string, impl: (logger: NullLogger, cb: (err?: Error) => void) => void) {
var logger = this.extend(name);
NullLogger.log(LoggerLevel.Timer, logger, ["Starting function", name]);
var start = +new Date;
impl(logger, function(err?: Error) {
if(err instanceof Error)
NullLogger.log(LoggerLevel.Error, logger, ["Function", name, "errored:", err]);
NullLogger.log(LoggerLevel.Timer, logger, ["Function", name, "took " + ((+new Date) - start) + "ms."]);
});
return this;
}
/**
* Log with performance level
*
* @param messages The message data to log
*/
performance(...messages: any[]) {
NullLogger.log(LoggerLevel.Performance, this, messages);
return this;
}
/**
* Log with performance level
*
* @param messages The message data to log
*/
perf(...messages: any[]) {
NullLogger.log(LoggerLevel.Performance, this, messages);
return this;
}
/**
* Log with debugging level
*
* @param messages The message data to log
*/
debugging(...messages: any[]) {
NullLogger.log(LoggerLevel.Debugging, this, messages);
return this;
}
/**
* Log with debugging level
*
* @param messages The message data to log
*/
debug(...messages: any[]) {
NullLogger.log(LoggerLevel.Debugging, this, messages);
return this;
}
/**
* Log with information level
*
* @param messages The message data to log
*/
info(...messages: any[]) {
NullLogger.log(LoggerLevel.Information, this, messages);
return this;
}
/**
* Log with information level
*
* @param messages The message data to log
*/
information(...messages: any[]) {
NullLogger.log(LoggerLevel.Information, this, messages);
return this;
}
/**
* Log with warning level
*
* @param messages The message data to log
*/
warn(...messages: any[]) {
NullLogger.log(LoggerLevel.Warning, this, messages);
return this;
}
/**
* Log with warning level
*
* @param messages The message data to log
*/
warning(...messages: any[]) {
NullLogger.log(LoggerLevel.Warning, this, messages);
return this;
}
/**
* Log with error level
*
* @param messages The message data to log
*/
error(...messages: any[]) {
NullLogger.log(LoggerLevel.Error, this, messages);
return this;
}
/**
* Log with error level, and exit with code 1 after
*
* @param messages The message data to log
*/
fatal(...messages: any[]) {
NullLogger.log(LoggerLevel.Fatal, this, messages);
process.exit(1);
}
/**
* Return a new NullLogger that extends this one
*
* @param messages The message data to log
*/
extend(...scopes: string[]): NullLogger {
var merged = this.scopes.slice(0);
merged.push.apply(merged, scopes);
var logger = new NullLogger();
(logger as any).scopes = merged;
return logger;
}
/**
* Execute within a group, using a new temporary NullLogger
*
* @param messages The message data to log
*/
group(name: string, impl: (logger: NullLogger) => void) {
impl(this.extend(name));
return this;
}
/**
* Update a specific scope at a specific index
*
* @param messages The message data to log
*/
updateScopeName(scope: string, index = -1) {
if (index < 0)
this.scopes[this.scopes.length + index] = scope;
else
this.scopes[index] = scope;
delete this.scopeCache;
return this;
}
/**
* Return a specific scope at a specific index
*
* @param messages The message data to log
*/
scopeName(index: number = -1) {
if (index < 0)
return this.scopes[this.scopes.length + index];
else
return this.scopes[index];
}
static useWithDeathHandler(scriptToRun: string, ondeath?: (signal?, err?) => void, implementation?: () => void) {
try {
require('death')(function(signal, err) {
if(ondeath)
ondeath(signal, err);
});
} catch(e) {
}
}
readonly isDeathRun = false;
}