Socket
Socket
Sign inDemoInstall

@tsed/logger

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tsed/logger - npm Package Compare versions

Comparing version 5.15.0 to 5.16.0

lib/index.modern.js

6

lib/appenders/class/BaseAppender.d.ts

@@ -20,7 +20,7 @@ /**

*
* ts-log-debug can load appenders from outside the core appenders. The type config value is used as a require path if no matching appender can be found. For example, the following configuration will create an appender with decorators:
* `@tsed/logger` can load appenders from outside the core appenders. The type config value is used as a require path if no matching appender can be found. For example, the following configuration will create an appender with decorators:
*
* ```typescript
* // consoleAppender.ts
* import {Appender, BaseAppender, LogEvent} from "ts-log-debug";
* import {Appender, BaseAppender, LogEvent} from "@tsed/logger";
* const consoleLog = console.log.bind(console);

@@ -39,3 +39,3 @@ *

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
* import "./consoleAppender.ts"

@@ -42,0 +42,0 @@ *

@@ -22,3 +22,3 @@ /**

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
*

@@ -25,0 +25,0 @@ * const logger = new Logger("loggerName");

@@ -10,3 +10,3 @@ /**

*
* The file appender writes log events to a file. It supports an optional maximum file size, and will keep a configurable number of backups. When using the file appender, you should also call ts-log-debug.shutdown() when your application terminates, to ensure that any remaining asynchronous writes have finished. Although the file appender uses the streamroller library, this is included as a dependency of ts-log-debug so you do not need to include it yourself.
* The file appender writes log events to a file. It supports an optional maximum file size, and will keep a configurable number of backups. When using the file appender, you should also call `logger.shutdown()` when your application terminates, to ensure that any remaining asynchronous writes have finished. Although the file appender uses the streamroller library, this is included as a dependency of ts-log-debug so you do not need to include it yourself.
*

@@ -31,3 +31,3 @@ * ## Configuration

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
*

@@ -47,3 +47,3 @@ * const logger = new Logger("loggerName");

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
*

@@ -69,4 +69,4 @@ * const logger = new Logger("loggerName");

* ```typescript
* import { Logger } from 'ts-log-debug';
* export const logger = new Logger('Log Example');
* import { Logger } from "@tsed/logger";
* export const logger = new Logger("Log Example");
*

@@ -73,0 +73,0 @@ * logger.appenders

@@ -20,3 +20,3 @@ /**

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
*

@@ -23,0 +23,0 @@ * const logger = new Logger("loggerName");

@@ -20,3 +20,3 @@ /**

* ```typescript
* import {Logger} from "ts-log-debug";
* import {Logger} from "@tsed/logger";
*

@@ -23,0 +23,0 @@ * const logger = new Logger("loggerName");

@@ -0,1 +1,2 @@

import { Logger } from "./logger/class/Logger";
export * from "./core";

@@ -5,8 +6,3 @@ export * from "./appenders";

export * from "./logger";
import { Logger } from "./logger/class/Logger";
declare let $log: Logger;
declare const _default: {
$log: Logger;
};
export default _default;
export { $log };

@@ -1,18 +0,1500 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.$log = void 0;
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./core"), exports);
tslib_1.__exportStar(require("./appenders"), exports);
tslib_1.__exportStar(require("./layouts"), exports);
tslib_1.__exportStar(require("./logger"), exports);
const Logger_1 = require("./logger/class/Logger");
let $log = new Logger_1.Logger("default");
var tslib = require('tslib');
var Path = require('path');
var Os = require('os');
var Util = require('util');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () {
return e[k];
}
});
}
});
}
n['default'] = e;
return n;
}
var Path__namespace = /*#__PURE__*/_interopNamespace(Path);
var Os__namespace = /*#__PURE__*/_interopNamespace(Os);
var Util__namespace = /*#__PURE__*/_interopNamespace(Util);
const AppendersRegistry = new Map();
class LoggerAppenders {
constructor() {
this._appenders = new Map();
this._lvls = new Map();
}
get size() {
return this._appenders.size;
}
/**
* The `has() method returns a boolean indicating whether an element with the specified configuration name exists or not.
* @param name Required. The key of the element to test for presence in the Map object.`
* @returns {boolean}
*/
has(name) {
return this._appenders.has(name);
}
/**
* The `get() method returns a specified element from a loggerAppenders.
* @param name Required. The configuration of the element to return from the Map object.
* @returns {ILoggerAppender}
*/
get(name) {
return this._appenders.get(name);
}
/**
* The `set()` method adds or updates an element with a specified key and value to a loggerAppenders object.
* @param name Required. The key of the element to add to the loggerAppenders object.
* @param config Required. The config of the element to add to the loggerAppenders object.
* @returns {LoggerAppender}
*/
set(name, config) {
if (!AppendersRegistry.has(config.type)) {
const error = new Error(`Appender ${config.type} doesn't exists. Check your configuration:\n${JSON.stringify(config)}\n`);
error.name = "UNKNOW_APPENDER";
throw error;
}
const klass = AppendersRegistry.get(config.type).provide;
const instance = new klass(config);
this._appenders.set(name, {
name,
instance,
config
});
this._lvls.clear();
return this;
}
/**
* Remove all configuration that match with the `name`.
* @param name Required. The key of the element to remove from the loggerAppenders object.
* @returns {boolean} Returns true if an element in the Map object existed and has been removed, or false if the element does not exist.
*/
delete(name) {
let existed = this._appenders.delete(name);
if (existed) {
this._lvls.clear();
}
return existed;
}
/**
* The `clear() method removes all elements from a loggerAppenders object.
*/
clear() {
this._appenders.clear();
this._lvls.clear();
}
/**
* The `forEach()` method executes a provided function once per each key/value pair in the loggerAppenders object, in insertion order.
* @param callback Function to execute for each element.
* @param thisArg Value to use as this when executing callback.
*/
forEach(callback, thisArg) {
this._appenders.forEach(callback, thisArg);
}
/**
*
* @returns {Array}
*/
toArray() {
const array = [];
this._appenders.forEach(o => array.push(o));
return array;
}
/**
* Return all appenders that match with the given loggingLevel.
* @param loggingLevel
* @returns {[BaseAppender]}
*/
byLogLevel(loggingLevel) {
const level = loggingLevel.toString();
if (this._lvls.has(level)) {
return this._lvls.get(level);
}
const list = this.toArray().filter(appender => appender.config.levels ? appender.config.levels.find(level => level.toUpperCase() === loggingLevel.toString()) : true).map(appender => appender.instance);
this._lvls.set(loggingLevel.toString(), list);
return list;
}
}
function charRepeater(x, char = " ") {
let res = "";
while (x--) res += char;
return res;
}
/**
*
* @returns {string}
*/
function buildStartLine(fields, settings) {
let line = "┌";
let list = Object.keys(fields);
list.forEach((key, index) => {
if (index !== 0 && index !== list.length) {
line += "┬";
}
line += charRepeater(fields[key] + 2 * settings.padding, "─");
});
line += "┐";
return line;
}
/**
*
* @param fields
* @param settings
* @returns {string}
*/
function buildEndLine(fields, settings) {
let line = "└";
let list = Object.keys(fields);
list.forEach((key, index) => {
if (index !== 0 && index !== list.length) {
line += "┴";
}
line += charRepeater(fields[key] + 2 * settings.padding, "─");
});
line += "┘";
return line;
}
/**
*
* @param fields
* @param settings
* @param char
* @returns {string}
*/
function buildLine(fields, settings, char = "─") {
let line = "";
Object.keys(fields).forEach(key => {
line += "│";
line += charRepeater(fields[key] + 2 * settings.padding, char);
});
line += "│";
return line;
}
/**
*
*/
function buildLineData(scope, fields, settings) {
let line = "";
Object.keys(fields).forEach(key => {
line += "│ ";
line += scope[key];
line += charRepeater(fields[key] + 2 * (settings.padding - 1) - scope[key].length, " ");
line += " ";
});
line += "│";
return line;
}
/**
*
* @param list
* @param settings
* @returns {string}
*/
function drawTable(list, settings = {}) {
settings.padding = settings.padding || 1;
if (settings.header === undefined) {
settings.header = {};
Object.keys(list[0]).forEach(key => settings.header[key] = key);
}
const fields = {}; // Calculate width for each column
Object.keys(settings.header).forEach(key => fields[key] = settings.header[key].length);
list.forEach(route => {
Object.keys(fields).forEach(key => fields[key] = Math.max(("" + route[key]).length, fields[key]));
});
let output = "";
output += buildStartLine(fields, settings) + "\n";
output += buildLineData(settings.header, fields, settings) + "\n";
list.forEach(scope => {
output += buildLine(fields, settings) + "\n";
output += buildLineData(scope, fields, settings) + "\n";
});
output += buildEndLine(fields, settings);
return output;
}
class LogEvent {
/**
* Models a logging event.
* @constructor
* @param {String} _categoryName name of category
* @param {LogLevel} _level level of message
* @param {Array} _data objects to log
* @param _context
*/
constructor(_categoryName, _level, _data, _context) {
this._categoryName = _categoryName;
this._level = _level;
this._data = _data;
this._context = _context;
this._startTime = new Date();
}
get startTime() {
return this.data && this.data[0] && this.data[0].time ? this.data[0].time : this._startTime;
}
get categoryName() {
return this._categoryName;
}
get level() {
return this._level;
}
get formatedLevel() {
return (this.level.toString() + " ").slice(0, 5);
}
get data() {
return this._data;
}
set data(data) {
this._data = data;
}
get context() {
return this._context;
}
get cluster() {
return {};
}
get pid() {
return this.context.get("pid");
}
}
/**
* @module core
*/
/** */
class LogLevel {
constructor(level, levelStr) {
this.level = level;
this.levelStr = levelStr;
this.level = level;
this.levelStr = levelStr;
}
static getLevel(sArg, defaultLevel) {
if (sArg instanceof LogLevel) {
return sArg;
}
if (typeof sArg === "string") {
const index = sArg.toUpperCase();
return DEFAULT_LOG_LEVELS[index] || defaultLevel;
}
return this.getLevel(sArg.toString());
}
toString() {
return this.levelStr;
}
isLessThanOrEqualTo(otherLevel) {
if (typeof otherLevel === "string") {
otherLevel = LogLevel.getLevel(otherLevel);
}
return this.level <= otherLevel.level;
}
isGreaterThanOrEqualTo(otherLevel) {
if (typeof otherLevel === "string") {
otherLevel = LogLevel.getLevel(otherLevel);
}
return this.level >= otherLevel.level;
}
isEqualTo(otherLevel) {
if (typeof otherLevel === "string") {
otherLevel = LogLevel.getLevel(otherLevel);
}
return this.level === otherLevel.level;
}
}
const DEFAULT_LOG_LEVELS = {
ALL: new LogLevel(Number.MIN_VALUE, "ALL"),
TRACE: new LogLevel(5000, "TRACE"),
DEBUG: new LogLevel(10000, "DEBUG"),
INFO: new LogLevel(20000, "INFO"),
WARN: new LogLevel(30000, "WARN"),
ERROR: new LogLevel(40000, "ERROR"),
FATAL: new LogLevel(50000, "FATAL"),
MARK: new LogLevel(9007199254740992, "MARK"),
OFF: new LogLevel(Number.MAX_VALUE, "OFF")
};
function levels() {
return DEFAULT_LOG_LEVELS;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
class LogContext extends Map {
toJSON() {
return [...this.entries()].reduce((context, [key, value]) => {
return _extends({}, context, {
[key]: value
});
}, {});
}
}
class Logger {
/**
*
*/
constructor(_name = "default") {
this._name = _name;
this._appenders = new LoggerAppenders();
/**
*
*/
this._context = new LogContext();
this.level = "all";
}
get appenders() {
return this._appenders;
}
get level() {
return this._level.toString();
}
set level(level) {
this._level = LogLevel.getLevel(level, "debug");
}
get context() {
return this._context;
}
get name() {
return this._name;
}
set name(value) {
this._name = value;
}
/**
* Create stack trace the lines of least Logger.
* @returns {string}
*/
static createStack() {
const stack = new Error().stack.replace("Error\n", "");
return stack.split("\n").filter((line, index) => index >= 2).join("\n");
}
isLevelEnabled(otherLevel) {
return this._level.isLessThanOrEqualTo(otherLevel);
}
/**
* Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf() (the arguments are all passed to util.format()).
* @param data
* @returns {any}
*/
debug(...data) {
return this.write(levels().DEBUG, data);
}
/**
*
* @param data
* @returns {any}
*/
info(...data) {
return this.write(levels().INFO, data);
}
/**
*
* @param data
* @returns {any}
*/
warn(...data) {
return this.write(levels().WARN, data);
}
/**
* Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary
* message and all additional used as substitution values similar to printf() (the arguments are all
* passed to util.format()).
* @param data
* @param args
* @returns {any}
*/
error(...data) {
return this.write(levels().ERROR, data);
}
fatal(...data) {
return this.write(levels().FATAL, data);
}
/**
*
* @param data
* @returns {Logger}
*/
trace(...data) {
const stack = "\n" + Logger.createStack() + "\n";
data.push(stack);
return this.write(levels().TRACE, data);
}
/**
*
*/
start() {
this.level = "ALL";
return this;
}
/**
*
*/
stop() {
this.level = "OFF";
return this;
}
/**
*
* @returns {Promise<TAll[]>}
*/
shutdown() {
this.stop();
const promises = this.appenders.toArray().filter(appender => !!appender.instance.shutdown).map(appender => appender.instance.shutdown());
return Promise.all(promises);
}
/**
*
* @param list
* @param settings
*/
drawTable(list, settings = {}) {
return drawTable(list, settings);
}
/**
*
* @param list
* @param settings
* @returns {Logger}
*/
printTable(list, settings = {}) {
this.info(`\n${this.drawTable(list, settings)}`);
return this;
}
/**
*
* @returns {Logger}
*/
write(logLevel, data) {
if (!this.isLevelEnabled(logLevel)) return this;
const logEvent = new LogEvent(this._name, logLevel, data, this._context);
this.appenders.byLogLevel(logLevel).forEach(appender => {
appender.write(logEvent);
});
return this;
}
}
/**
* @module appenders
*/
function Appender(options) {
return target => {
target.prototype.appenderOptions = options;
target.$name = options.name;
AppendersRegistry.set(options.name, {
provide: target
});
};
}
const LayoutsRegistry = new Map();
class Layouts {
static get(name, config) {
if (typeof name !== "string") {
name = name.$name;
}
if (!LayoutsRegistry.has(name)) {
name = "colored";
console.warn(name + " layout doesn't exists");
}
const layoutKlass = LayoutsRegistry.get(name);
return new layoutKlass.provide(config);
}
}
/**
* ## BaseAppender
*
* `@tsed/logger` can load appenders from outside the core appenders. The type config value is used as a require path if no matching appender can be found. For example, the following configuration will create an appender with decorators:
*
* ```typescript
* // consoleAppender.ts
* import {Appender, BaseAppender, LogEvent} from "@tsed/logger";
* const consoleLog = console.log.bind(console);
*
* @ Appender({name: "console2"})
* export class ConsoleAppender extends BaseAppender {
* write(loggingEvent: LogEvent) {
* consoleLog(this.layout(loggingEvent, this.config.timezoneOffset));
* }
* }
* ```
*
* This appender can be use like this:
*
* ```typescript
* import {Logger} from "@tsed/logger";
* import "./consoleAppender.ts"
*
* const logger = new Logger("loggerName");
*
* logger.appenders
* .set("console-log", {
* type: "console2", level: ["debug", "info", "trace"]
* });
* ```
*
*
*/
class BaseAppender {
constructor(_config) {
this._config = _config;
this.appenderOptions = {
name: ""
};
this.configure(_config);
if (this["build"]) {
this["build"]();
}
}
get config() {
return this._config;
}
configure(config) {
Object.assign(this._config, config);
this._layout = Layouts.get(this.appenderOptions.defaultLayout || "colored", this._config);
if (this._config.layout) {
this._layout = Layouts.get(this._config.layout.type, this._config.layout);
}
return this;
}
/**
*
* @param args
*/
layout(...args) {
return this._layout.transform(...args);
}
}
/**
* ## Console Appender
*
* This appender uses node’s console object to write log events. It can also be used in the browser, if you’re using browserify or something similar. Be aware that writing a high volume of output to the console can make your application use a lot of memory. If you experience this problem, try switching to the stdout appender.
*
* ## Configuration
*
* * type - console
* * layout - object (optional, defaults to colouredLayout) - see layouts
*
* Note that all log events are output using console.log regardless of the event’s level (so ERROR events will not be logged using console.error)
*
* ## Example
*
* ```typescript
* import {Logger} from "@tsed/logger";
*
* const logger = new Logger("loggerName");
*
* logger.appenders.set("console", {
* type: "console",
* levels: ["debug", "info", "trace"]
* });
* ```
*
* @private
*/
exports.ConsoleAppender = class ConsoleAppender extends BaseAppender {
constructor() {
super(...arguments);
this.log = console.log.bind(console);
}
write(loggingEvent) {
this.log(this.layout(loggingEvent, this.config.timezoneOffset));
}
};
exports.ConsoleAppender = tslib.__decorate([Appender({
name: "console"
})], exports.ConsoleAppender);
/**
* @module appenders
*/
const streams = require("streamroller");
const eol$1 = Os__namespace.EOL || "\n";
/**
* ## File Appender
*
* The file appender writes log events to a file. It supports an optional maximum file size, and will keep a configurable number of backups. When using the file appender, you should also call `logger.shutdown()` when your application terminates, to ensure that any remaining asynchronous writes have finished. Although the file appender uses the streamroller library, this is included as a dependency of ts-log-debug so you do not need to include it yourself.
*
* ## Configuration
*
* * type - "file"
* * filename - string - the path of the file where you want your logs written.
* * maxLogSize - integer (optional) - the maximum size (in bytes) for the log file. If not specified, then no log rolling will happen.
* * backups - integer (optional, default value = 5) - the number of old log files to keep during log rolling.
* * layout - (optional, defaults to basic layout) - see layouts
*
* Any other configuration parameters will be passed to the underlying streamroller implementation (see also node.js core file streams):
*
* * encoding - string (default “utf-8”)
* * mode - integer (default 0644)
* * flags - string (default ‘a’)
* * compress - boolean (default false) - compress the backup files during rolling (backup files will have .gz extension)
*
* ## Example
*
* ```typescript
* import {Logger} from "@tsed/logger";
*
* const logger = new Logger("loggerName");
*
* logger.appenders.set("log-file", {
* type: "file",
* filename: "all-the-logs.log"
* });
* logger.debug('I will be logged in all-the-logs.log');
* ```
* > This example will result in a single log file (all-the-logs.log) containing the log messages.
*
* ## Example with log rolling (and compressed backups)
*
* ```typescript
* import {Logger} from "@tsed/logger";
*
* const logger = new Logger("loggerName");
*
* logger.appenders.set("log-file2", {
* type: "file",
* filename: "all-the-logs.log",
* maxLogSize: 10485760,
* backups: 3,
* compress: true
* });
* logger.debug('I will be logged in all-the-logs.log');
* ```
*
* :::
* This will result in one current log file (all-the-logs.log). When that reaches 10Mb in size, it will be renamed and compressed to all-the-logs.log.1.gz and a new file opened called all-the-logs.log. When all-the-logs.log reaches 10Mb again, then all-the-logs.log.1.gz will be renamed to all-the-logs.log.2.gz, and so on.
* :::
*
* ## Example with date rolling
*
* ```typescript
* import { Logger } from "@tsed/logger";
* export const logger = new Logger("Log Example");
*
* logger.appenders
* .set('file', {
* type: 'file',
* filename: `${__dirname}/../logs/myfile.log`,
* pattern: '.yyyy-MM-dd'
* });
* ```
*
*/
exports.FileAppender = class FileAppender extends BaseAppender {
/**
*
*/
reopen() {
return this.shutdown().then(() => {
this.build();
});
}
/**
*
*/
shutdown() {
process.removeListener("SIGHUP", this.listener);
return new Promise((resolve, reject) => {
this.writer.write("", "utf-8", () => {
this.writer.end(resolve);
});
});
}
/**
*
* @param loggingEvent
*/
write(loggingEvent) {
this.writer.write(this.layout(loggingEvent, this.config.timezoneOffset) + eol$1, "utf8");
}
build() {
let {
filename: file,
maxLogSize: logSize,
backups: numBackups,
pattern
} = this.config;
file = Path__namespace.normalize(file);
numBackups = numBackups === undefined ? 5 : numBackups; // there has to be at least one backup if logSize has been specified
numBackups = numBackups === 0 ? 1 : numBackups;
this.writer = this.openTheStream(file, logSize, numBackups, pattern, this.config); // On SIGHUP, close and reopen all files. This allows this appender to work with
// logrotate. Note that if you are using logrotate, you should not set
// `logSize`.
this.listener = () => this.reopen();
process.on("SIGHUP", this.listener);
}
/**
*
* @param file
* @param fileSize
* @param numFiles
* @param options
* @returns {streams.RollingFileStream}
*/
openTheStream(file, fileSize, numFiles, pattern, options) {
let stream = null;
if (pattern) {
stream = new streams.DateRollingFileStream(file, pattern, options);
} else {
stream = new streams.RollingFileStream(file, fileSize, numFiles, options);
}
stream.on("error", err => {
console.error("FileAppender - Writing to file %s, error happened ", file, err);
});
return stream;
}
};
exports.FileAppender = tslib.__decorate([Appender({
name: "file",
defaultLayout: "basic"
})], exports.FileAppender);
/**
* ## Standard Error Appender
*
* This appender writes all log events to the standard error stream.
*
* ## Configuration
*
* * type - stderr
* * layout - object (optional, defaults to colouredLayout) - see layouts
*
* ## Example
*
* ```typescript
* import {Logger} from "@tsed/logger";
*
* const logger = new Logger("loggerName");
*
* logger.appenders.set("log-error", {
* type: "stderr",
* levels: ["error", "warn", "fatal"]
* });
* ```
*
* @private
*/
exports.StderrAppender = class StderrAppender extends BaseAppender {
constructor() {
super(...arguments);
this.log = process.stderr.write.bind(process.stderr);
}
write(loggingEvent) {
this.log(`${this.layout(loggingEvent, this.config.timezoneOffset)}\n`);
}
};
exports.StderrAppender = tslib.__decorate([Appender({
name: "stderr"
})], exports.StderrAppender);
/**
* ## Standard Output Appender
*
* This appender writes all log events to the standard output stream.
*
* ## Configuration
*
* * type - stderr
* * layout - object (optional, defaults to colouredLayout) - see layouts
*
* ## Example
*
* ```typescript
* import {Logger} from "@tsed/logger";
*
* const logger = new Logger("loggerName");
*
* logger.appenders.set("log", {
* type: "stdout",
* levels: ["info", "trace", "debug"]
* });
* ```
*
* @private
*/
exports.StdoutAppender = class StdoutAppender extends BaseAppender {
constructor() {
super(...arguments);
this.log = process.stdout.write.bind(process.stdout);
}
write(loggingEvent) {
this.log(`${this.layout(loggingEvent, this.config.timezoneOffset)}\n`);
}
};
exports.StdoutAppender = tslib.__decorate([Appender({
name: "stdout"
})], exports.StdoutAppender);
exports.LOG_COLORS = void 0;
(function (LOG_COLORS) {
LOG_COLORS["ALL"] = "grey";
LOG_COLORS["INFO"] = "green";
LOG_COLORS["DEBUG"] = "cyan";
LOG_COLORS["WARN"] = "yellow";
LOG_COLORS["TRACE"] = "blue";
LOG_COLORS["ERROR"] = "red";
LOG_COLORS["FATAL"] = "magenta";
LOG_COLORS["OFF"] = "grey";
})(exports.LOG_COLORS || (exports.LOG_COLORS = {}));
class BaseLayout {
constructor(config) {
this.config = config;
}
}
function Layout(options) {
return target => {
target.$name = options.name;
LayoutsRegistry.set(options.name, {
provide: target
});
};
}
const styles = {
// styles
bold: [1, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
// grayscale
white: [37, 39],
grey: [90, 39],
black: [90, 39],
// colors
blue: [34, 39],
cyan: [36, 39],
green: [32, 39],
magenta: [35, 39],
red: [31, 39],
yellow: [33, 39]
};
function colorizeStart(style) {
return style ? `\x1B[${styles[style][0]}m` : "";
}
function colorizeEnd(style) {
return style ? `\x1B[${styles[style][1]}m` : "";
}
function colorize(str, style) {
return colorizeStart(style) + str + colorizeEnd(style);
}
function removeColors(str) {
return str.replace(/\[\d+m|\\u\d+b/gi, "");
}
const dateFormat$1 = require("date-format");
function timestampLevelAndCategory(loggingEvent, colour, timezoneOffset) {
return colorize(Util__namespace.format("[%s] [%s] [%s] - ", dateFormat$1.asString(loggingEvent.startTime, timezoneOffset), loggingEvent.formatedLevel, loggingEvent.categoryName), colour);
}
exports.BasicLayout = class BasicLayout extends BaseLayout {
/**
* BasicLayout is a simple layouts for storing the logs. The logs are stored
* in following format:
* <pre>
* [startTime] [logLevel] categoryName - message\n
* </pre>
*
* @author Stephan Strittmatter
*/
transform(loggingEvent, timezoneOffset) {
return timestampLevelAndCategory(loggingEvent, undefined, timezoneOffset) + Util__namespace.format(...[].concat(loggingEvent.data));
}
};
exports.BasicLayout = tslib.__decorate([Layout({
name: "basic"
})], exports.BasicLayout);
exports.ColoredLayout = class ColoredLayout extends BaseLayout {
/**
* colouredLayout - taken from masylum's fork.
* same as basicLayout, but with colours.
*/
transform(loggingEvent, timezoneOffset) {
const index = loggingEvent.level.toString();
const color = exports.LOG_COLORS[index];
return timestampLevelAndCategory(loggingEvent, color, timezoneOffset) + Util__namespace.format(...[].concat(loggingEvent.data));
}
};
exports.ColoredLayout = tslib.__decorate([Layout({
name: "colored"
})], exports.ColoredLayout);
exports.DummyLayout = class DummyLayout extends BaseLayout {
transform(loggingEvent, timezoneOffset) {
return loggingEvent.data[0];
}
};
exports.DummyLayout = tslib.__decorate([Layout({
name: "dummy"
})], exports.DummyLayout);
exports.MessagePassThroughLayout = class MessagePassThroughLayout extends BaseLayout {
transform(loggingEvent, timezoneOffset) {
return Util__namespace.format(...[].concat(loggingEvent.data));
}
};
exports.MessagePassThroughLayout = tslib.__decorate([Layout({
name: "messagePassThrough"
})], exports.MessagePassThroughLayout);
function truncate(truncation, toTruncate) {
let len;
if (truncation) {
len = parseInt(truncation.substr(1), 10);
return toTruncate.substring(0, len);
}
return toTruncate;
}
function pad(padding, toPad) {
let len;
if (padding) {
if (padding.charAt(0) === "-") {
len = parseInt(padding.substr(1), 10); // Right pad with spaces
while (toPad.length < len) {
toPad += " ";
}
} else {
len = parseInt(padding, 10); // Left pad with spaces
while (toPad.length < len) {
toPad = ` ${toPad}`;
}
}
}
return toPad;
}
function truncateAndPad(toTruncAndPad, truncation, padding) {
let replacement = toTruncAndPad;
replacement = truncate(truncation, replacement);
replacement = pad(padding, replacement);
return replacement;
}
/**
*
*/
const dateFormat = require("date-format");
const eol = Os__namespace.EOL || "\n";
class LayoutReplacer {
constructor(tokens, timezoneOffset) {
this.tokens = tokens;
this.timezoneOffset = timezoneOffset;
/**
*
* @param loggingEvent
* @param specifier
* @returns {any}
*/
this.categoryName = (loggingEvent, specifier) => {
let loggerName = loggingEvent.categoryName;
if (specifier) {
const precision = parseInt(specifier, 10);
const loggerNameBits = loggerName.split(".");
if (precision < loggerNameBits.length) {
loggerName = loggerNameBits.slice(loggerNameBits.length - precision).join(".");
}
}
return loggerName;
};
/**
*
* @param loggingEvent
* @param specifier
* @returns {any}
*/
this.formatAsDate = (loggingEvent, specifier) => {
let format = dateFormat.ISO8601_FORMAT;
if (specifier) {
format = specifier; // Pick up special cases
if (format === "ISO8601") {
format = dateFormat.ISO8601_FORMAT;
} else if (format === "ISO8601_WITH_TZ_OFFSET") {
format = dateFormat.ISO8601_WITH_TZ_OFFSET_FORMAT;
} else if (format === "ABSOLUTE") {
format = dateFormat.ABSOLUTETIME_FORMAT;
} else if (format === "DATE") {
format = dateFormat.DATETIME_FORMAT;
}
} // Format the date
return dateFormat.asString(format, loggingEvent.startTime, this.timezoneOffset);
};
/**
*
* @returns {string}
*/
this.hostname = () => {
return Os__namespace.hostname().toString();
};
/**
*
* @param loggingEvent
* @returns {any}
*/
this.formatMessage = loggingEvent => {
return Util__namespace.format(...loggingEvent.data);
};
/**
*
* @returns {string|string}
*/
this.endOfLine = () => {
return eol;
};
/**
*
* @param loggingEvent
* @returns {string}
*/
this.logLevel = loggingEvent => {
return loggingEvent.level.toString();
};
/**
*
* @param loggingEvent
* @returns {any}
*/
this.startTime = loggingEvent => {
return dateFormat.asString("hh:mm:ss", loggingEvent.startTime, this.timezoneOffset);
};
/**
*
* @param loggingEvent
* @returns {string}
*/
this.startColour = loggingEvent => {
const index = loggingEvent.level.toString();
return colorizeStart(exports.LOG_COLORS[index]);
};
/**
*
* @param loggingEvent
* @returns {string}
*/
this.endColour = loggingEvent => {
const index = loggingEvent.level.toString();
return colorizeEnd(exports.LOG_COLORS[index]);
};
/**
*
* @returns {string}
*/
this.percent = () => {
return "%";
};
/**
*
* @param loggingEvent
* @returns {string}
*/
this.pid = loggingEvent => {
return loggingEvent && loggingEvent.pid ? loggingEvent.pid.toString() : process.pid.toString();
};
/**
*
* @param loggingEvent
* @param specifier
* @returns {any}
*/
this.clusterInfo = (loggingEvent, specifier) => {
if (loggingEvent.cluster && specifier) {
return specifier.replace("%m", loggingEvent.cluster.master).replace("%w", loggingEvent.cluster.worker).replace("%i", loggingEvent.cluster.workerId);
} else if (loggingEvent.cluster) {
return `${loggingEvent.cluster.worker}@${loggingEvent.cluster.master}`;
}
return this.pid();
};
/**
*
* @param loggingEvent
* @param specifier
* @returns {any}
*/
this.userDefined = (loggingEvent, specifier) => {
if (typeof this.tokens[specifier] !== "undefined") {
return typeof this.tokens[specifier] === "function" ? this.tokens[specifier](loggingEvent) : this.tokens[specifier];
}
return null;
};
}
build() {
return {
c: this.categoryName,
d: this.formatAsDate,
h: this.hostname,
m: this.formatMessage,
n: this.endOfLine,
p: this.logLevel,
r: this.startTime,
"[": this.startColour,
"]": this.endColour,
y: this.clusterInfo,
z: this.pid,
"%": this.percent,
x: this.userDefined
};
}
}
const regex = /%(-?[0-9]+)?(\.?[0-9]+)?([[\]cdhmnprzxy%])(\{([^}]+)\})?|([^%]+)/;
const TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";
/**
* PatternLayout
* Format for specifiers is %[padding].[truncation][field]{[format]}
* e.g. %5.10p - left pad the log level by 5 characters, up to a max of 10
* Fields can be any of:
* - %r time in toLocaleTimeString format
* - %p log level
* - %c log category
* - %h hostname
* - %m log data
* - %d date in constious formats
* - %% %
* - %n newline
* - %z pid
* - %x{[tokenname]} add dynamic tokens to your log. Tokens are specified in the tokens parameter
* You can use %[ and %] to define a colored block.
*
* Tokens are specified as simple key:value objects.
* The key represents the token name whereas the value can be a string or function
* which is called to extract the value to put in the log message. If token is not
* found, it doesn't replace the field.
*
* A sample token would be: { 'pid' : function() { return process.pid; } }
*
* Takes a pattern string, array of tokens and returns a layouts function.
* @return {Function}
* @param pattern
* @param tokens
* @param timezoneOffset
*
* @authors ['Stephan Strittmatter', 'Jan Schmidle']
*/
exports.PatternLayout = class PatternLayout extends BaseLayout {
constructor(config) {
super(config);
this.replaceToken = (conversionCharacter, loggingEvent, specifier) => {
return this._replacers[conversionCharacter](loggingEvent, specifier);
};
this.pattern = config && config.pattern || TTCC_CONVERSION_PATTERN;
this.tokens = config && config.tokens;
this._replacers = new LayoutReplacer(this.tokens, this.config.timezoneOffset).build();
}
/**
*
* @param loggingEvent
* @param timezoneOffset
* @returns {string}
*/
transform(loggingEvent, timezoneOffset) {
let formattedString = "";
let result;
let searchString = this.pattern;
/* eslint no-cond-assign:0 */
while ((result = regex.exec(searchString)) !== null) {
// const matchedString = result[0];
const padding = result[1];
const truncation = result[2];
const conversionCharacter = result[3];
const specifier = result[5];
const text = result[6]; // Check if the pattern matched was just normal text
if (text) {
formattedString += text.toString();
} else {
// Create a raw replacement string based on the conversion
// character and specifier
const replacement = this.replaceToken(conversionCharacter, loggingEvent, specifier);
formattedString += truncateAndPad(replacement, truncation, padding);
}
searchString = searchString.substr(result.index + result[0].length);
}
return formattedString;
}
};
exports.PatternLayout = tslib.__decorate([Layout({
name: "pattern"
}), tslib.__metadata("design:paramtypes", [Object])], exports.PatternLayout);
exports.JsonLayout = class JsonLayout extends BaseLayout {
transform(loggingEvent, timezoneOffset) {
const log = _extends({}, loggingEvent.context.toJSON(), {
startTime: loggingEvent.startTime,
categoryName: loggingEvent.categoryName,
level: loggingEvent.level.toString()
});
log.data = loggingEvent.data.reduce((data, current) => {
if (typeof current === "object") {
Object.assign(log, current);
if (current.data) {
return [].concat(data, current.data);
}
return data;
}
return [...data, removeColors(Util__namespace.format(current))];
}, []);
return JSON.stringify(log) + (this.config["separator"] || "");
}
};
exports.JsonLayout = tslib.__decorate([Layout({
name: "json"
})], exports.JsonLayout);
let $log = new Logger("default");
$log.appenders.set("stdout", {
type: "stdout",
levels: ["info", "debug"]
}).set("stderr", {
type: "stderr",
levels: ["trace", "fatal", "error", "warn"]
});
exports.$log = $log;
$log.appenders
.set("stdout", { type: "stdout", levels: ["info", "debug"] })
.set("stderr", { type: "stderr", levels: ["trace", "fatal", "error", "warn"] });
exports.default = {
$log
};
//# sourceMappingURL=index.js.map
exports.Appender = Appender;
exports.BaseAppender = BaseAppender;
exports.BaseLayout = BaseLayout;
exports.Layout = Layout;
exports.Layouts = Layouts;
exports.LogContext = LogContext;
exports.LogEvent = LogEvent;
exports.LogLevel = LogLevel;
exports.Logger = Logger;
exports.LoggerAppenders = LoggerAppenders;
exports.colorize = colorize;
exports.colorizeEnd = colorizeEnd;
exports.colorizeStart = colorizeStart;
exports.levels = levels;
exports.removeColors = removeColors;
//# sourceMappingURL=index.js.map
{
"name": "@tsed/logger",
"version": "5.15.0",
"version": "5.16.0",
"description": "A multi channel logger written in TypeScript.",
"main": "./lib/index.js",
"typings": "./lib/index.d.ts",
"private": false,
"author": "Romain Lenzotti",
"license": "MIT",
"source": "./src/index.ts",
"main": "./lib/index.js",
"typings": "./lib/index.d.ts",
"exports": {
"require": "./lib/index.js",
"default": "./lib/index.modern.js"
},
"repository": "https://github.com/tsedio/logger",

@@ -23,4 +28,3 @@ "keywords": [

"scripts": {
"build": "tsc --build tsconfig.compile.json",
"build:doc": "tsc --build tsconfig.doc.json"
"build": "microbundle --target node --no-compress --format modern,cjs --tsconfig ./tsconfig.compile.json"
},

@@ -33,3 +37,3 @@ "dependencies": {

"streamroller": "^1.0.3",
"tslib": "2.1.0"
"tslib": "2.3.0"
},

@@ -36,0 +40,0 @@ "devDependencies": {},

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc