UNPKG

realm-object-server

Version:

Realm Object Server

244 lines 7.96 kB
"use strict"; 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