federer
Version:
Experiments in asynchronous federated learning and decentralized learning
86 lines • 3.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLogger = void 0;
const tslib_1 = require("tslib");
const winston = tslib_1.__importStar(require("winston"));
const root = tslib_1.__importStar(require("app-root-path"));
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const paths_1 = require("./paths");
const utils_1 = require("./utils");
const MAX_LABEL_LENGTH = 11;
/**
* Create a new logger.
*
* @param options Logger options
* @param consoleLabel If the options specify that the logs should be printed to
* console, the label prepended to each line of log
* @param filename If the options specify that the logs should be printed to a
* file, the name of the destination file
*/
function createLogger(options, consoleLabel, filename) {
const parsedOptions = parse(options);
return winston.createLogger({
level: parsedOptions.minLogLevel,
format: createLoggerFormat(parsedOptions, consoleLabel),
transports: createLoggerTransports(parsedOptions, filename),
});
}
exports.createLogger = createLogger;
/**
* Parses partial options into complete options.
*
* "Parsed" is used here in the sense of "Parse, don't validate".
* @see {@link https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/}
*
* @param options Partial options
* @returns Parsed options
*/
function parse(options) {
return {
logTarget: "console",
minLogLevel: "info",
...options,
};
}
/**
* Creates winston logger Transports, which specifies where to stream logs to.
*/
function createLoggerTransports(options, filename) {
switch (options.logTarget) {
case "none":
return [];
case "console":
return [new winston.transports.Console()];
case "file": {
const logDir = root.resolve("logs");
paths_1.mkdirp(logDir);
return [new winston.transports.File({ dirname: logDir, filename })];
}
}
}
/**
* Creates a winston logger Format, which specifies how to print a log line.
*/
function createLoggerFormat(options, consoleLabel) {
const formatJSON = (rest) => utils_1.isEmpty(rest) ? "" : JSON.stringify(rest, null, " ");
if (options.logTarget === "console") {
const emoji = {
silly: "🤡",
debug: chalk_1.default.green("🐛"),
info: chalk_1.default.blue("🛈"),
warn: chalk_1.default.yellow("⚠️"),
error: chalk_1.default.red("❌"),
};
return winston.format.printf(({ level, message, ...rest }) => {
const levelLabel = emoji[level] ?? chalk_1.default.grey(level);
const nodeLabel = `[${consoleLabel}]`.padEnd(MAX_LABEL_LENGTH + 2);
return `${nodeLabel} ${levelLabel} ${message} ${formatJSON(rest)}`;
});
}
else {
return winston.format.combine(winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }), winston.format.printf(({ timestamp, level, message, ...rest }) => {
return `[${timestamp}] ${level}: ${message} ${formatJSON(rest)}`;
}));
}
}
//# sourceMappingURL=log.js.map