realm-object-server
Version:
244 lines • 7.96 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const winston = require("winston");
const events = require("events");
const path = require("path");
const CircularBuffer = require("circular-buffer");
const util_1 = require("./util");
var SyncLogLevel;
(function (SyncLogLevel) {
SyncLogLevel[SyncLogLevel["all"] = 0] = "all";
SyncLogLevel[SyncLogLevel["trace"] = 1] = "trace";
SyncLogLevel[SyncLogLevel["debug"] = 2] = "debug";
SyncLogLevel[SyncLogLevel["detail"] = 3] = "detail";
SyncLogLevel[SyncLogLevel["info"] = 4] = "info";
SyncLogLevel[SyncLogLevel["warn"] = 5] = "warn";
SyncLogLevel[SyncLogLevel["error"] = 6] = "error";
SyncLogLevel[SyncLogLevel["fatal"] = 7] = "fatal";
SyncLogLevel[SyncLogLevel["off"] = 8] = "off";
})(SyncLogLevel = exports.SyncLogLevel || (exports.SyncLogLevel = {}));
exports.levels = util_1.mapEnum(SyncLogLevel, (cur) => 8 - SyncLogLevel[cur]);
const colors = {
all: "blue",
trace: "blue",
debug: "blue",
detail: "blue",
info: "green",
warn: "magenta",
error: "red",
fatal: "red",
off: "yellow",
};
class Logger extends events.EventEmitter {
withContext(ctx) {
return new Contextual(this, ctx);
}
close() {
this.removeAllListeners();
}
trace(msg, ctx) {
this.log("trace", msg, ctx);
}
debug(msg, ctx) {
this.log("debug", msg, ctx);
}
detail(msg, ctx) {
this.log("detail", msg, ctx);
}
info(msg, ctx) {
this.log("info", msg, ctx);
}
warn(msg, ctx) {
this.log("warn", msg, ctx);
}
error(msg, ctx) {
this.log("error", msg, ctx);
}
fatal(msg, ctx) {
this.log("fatal", msg, ctx);
}
getHiResTime() {
const now = new Date().getTime();
const epoch = Math.floor(now / 1000);
return [epoch, (now % 1000) * 1000 * 1000];
}
}
exports.Logger = Logger;
class MuteLogger extends Logger {
log(level, msg, ctx, hrt) {
this.emit("message", level, msg, ctx || {}, hrt);
}
}
exports.MuteLogger = MuteLogger;
class ThrowingLogger extends Logger {
constructor(levels = ["fatal", "error", "warn"]) {
super();
this.levels = levels;
}
log(level, msg, ctx) {
if (this.levels.indexOf(level) >= 0) {
throw new Error(`Unexpected log "${level}" entry: ${msg}`);
}
}
}
exports.ThrowingLogger = ThrowingLogger;
class Contextual extends Logger {
constructor(dst, ctx) {
super();
this.dst = dst;
this.ctx = Object.assign({}, ctx);
}
log(level, msg, ctx, hrt = this.getHiResTime()) {
const mergedCtx = Object.assign({}, this.ctx, ctx);
this.emit("message", level, msg, mergedCtx, hrt);
this.dst.log(level, msg, mergedCtx);
}
close() {
this.dst.close();
super.close();
}
}
const FileTransportConstructor = winston.transports.File;
class SighupFileTransport extends FileTransportConstructor {
constructor(options) {
super(options);
this.listener = this.sighup.bind(this);
process.on("SIGHUP", this.listener);
}
sighup() {
const self = this;
const filename = path.join(self.dirname, self._getFile(false));
fs.stat(filename, (err) => {
if (err && err.code === "ENOENT") {
self.reopenFile(filename);
}
});
}
reopenFile(filename) {
const self = this;
if (self._stream) {
self._stream.end();
self._stream.destroySoon();
}
const stream = fs.createWriteStream(filename, self.options);
stream.setMaxListeners(Infinity);
self._size = 0;
self._stream = stream;
self.once("flush", () => {
self.opening = false;
self.emit("open", filename);
});
self.flush();
}
close() {
process.removeListener("SIGHUP", this.listener);
super.close();
}
}
class WinstonLogger extends Logger {
constructor(level = "info", bufsize = 1000) {
super();
this.earlyMessagesSkipped = 0;
this.earlyMessages = new CircularBuffer(bufsize);
this.impl = new winston.Logger({
colors: colors,
level: level,
levels: exports.levels,
transports: [],
});
}
get logger() {
return this.impl;
}
emit(topic, level, msg, ctx, hrt) {
if (topic === "message" && this.earlyMessages) {
if (this.earlyMessages.size() === this.earlyMessages.capacity()) {
this.earlyMessagesSkipped++;
}
this.earlyMessages.enq({ level, msg, ctx, hrt });
return false;
}
else {
return super.emit(topic, level, msg, ctx, hrt);
}
}
dumpBuffer() {
const skipped = this.earlyMessagesSkipped;
if (skipped > 0) {
super.emit("message", "warn", `Skipped ${skipped} early log ${skipped > 1 ? "messages" : "message"}`, {});
}
while (this.earlyMessages.size() > 0) {
const { level, msg, ctx, hrt } = this.earlyMessages.deq();
super.emit("message", level, msg, ctx, hrt);
}
this.earlyMessages = null;
}
on(topic, listener) {
return this.addListener(topic, listener);
}
addListener(topic, listener) {
const res = super.addListener(topic, listener);
if (topic === "message" && this.earlyMessages) {
this.dumpBuffer();
}
return res;
}
log(level, msg, ctx = {}, hrt = this.getHiResTime()) {
let newMsg = msg;
const { service } = ctx, newCtx = __rest(ctx, ["service"]);
if (service) {
newMsg = `[${service}] ${msg}`;
}
this.emit("message", level, msg, ctx, hrt);
this.impl.log(level, newMsg, newCtx);
}
close() {
this.impl.close();
this.impl.unhandleExceptions();
super.close();
}
addConsole(options = {}) {
this.impl.add(winston.transports.Console, Object.assign({ json: (process.env.ROS_LOG_JSON === "1"), colorize: process.stdout.isTTY, timestamp: (process.env.ROS_LOG_TIMESTAMP === "1"), stderrLevels: util_1.enumValues(SyncLogLevel) }, options));
}
addFile(filename, options = {}) {
this.impl.add(SighupFileTransport, Object.assign({ json: (process.env.ROS_LOG_JSON === "1"), filename: filename, timestamp: (process.env.ROS_LOG_TIMESTAMP === "1"), handleExceptions: true, humanReadableUnhandledException: true }, options));
}
}
exports.WinstonLogger = WinstonLogger;
class ConsoleLogger extends WinstonLogger {
constructor(level, transportOptions) {
super(level);
this.addConsole(transportOptions);
}
}
exports.ConsoleLogger = ConsoleLogger;
class FileLogger extends WinstonLogger {
constructor(filename, level, transportOptions) {
super(level);
this.addFile(filename, transportOptions);
}
}
exports.FileLogger = FileLogger;
class FileConsoleLogger extends WinstonLogger {
constructor(filename, level, transportOptions = {}) {
super(level);
if (process.stdout.isTTY) {
this.addConsole(transportOptions.console);
}
if (filename) {
this.addFile(filename, transportOptions.file);
}
}
}
exports.FileConsoleLogger = FileConsoleLogger;
//# sourceMappingURL=Logger.js.map