@athenna/logger
Version:
The Athenna logging solution. Log in stdout, files and buckets.
179 lines (178 loc) • 4.54 kB
JavaScript
/**
* @athenna/logger
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import rTracer from 'cls-rtracer';
import { hostname } from 'node:os';
import { Is, Color } from '@athenna/common';
export class Formatter {
constructor() {
/**
* Holds the configuration object of formatter.
*/
this.configs = {};
}
/**
* Creates a new instance of Formatter.
*/
config(configs) {
this.configs = configs;
return this;
}
/**
* Create the PID for formatter.
*/
pid() {
return process.pid.toString();
}
/**
* Create the hostname for formatter.
*/
hostname() {
return hostname();
}
/**
* Get the level without any color or format.
*/
level() {
return this.configs.level;
}
/**
* Get the trace id for formatter.
*/
traceId() {
return (rTracer.id() || null);
}
/**
* Create the timestamp for formatter.
*/
timestamp() {
const localeStringOptions = {
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
day: '2-digit',
month: '2-digit'
};
return new Date(Date.now()).toLocaleString(undefined, localeStringOptions);
}
/**
* Transform the message to string.
*/
toString(message) {
if (Is.String(message)) {
return message;
}
if (Is.Object(message)) {
message = JSON.stringify(message);
}
return `${message}`;
}
/**
* Clean the message removing colors if clean
* option is true. If force is true, then colors
* will be removed even if configs clean option
* is false.
*/
clean(message, force = false) {
if (this.configs.clean || force) {
return Color.removeColors(message);
}
return message;
}
/**
* Apply all colors necessary to message.
*/
applyColors(message) {
message = this.toString(message);
return this.applyColorsByChalk(this.applyColorsByLevel(message));
}
/**
* Apply colors in message.
*/
applyColorsByChalk(message) {
if (!this.configs.chalk) {
return message;
}
return this.configs.chalk(message);
}
/**
* Apply colors in message by level.
*/
applyColorsByLevel(message) {
const level = this.configs.level;
return this.paintMessageByLevel(level, message);
}
/**
* Create the cli level string.
*/
cliLevel() {
const level = this.configs.level;
if (!Color[level]) {
return Color.bold(`[ ${level} ]`);
}
return Color[level].bold(`[ ${level} ]`);
}
/**
* Create the simple level string.
*/
simpleLevel() {
const level = this.configs.level;
if (!Color[level]) {
return Color.bold(`[${level.toUpperCase()}]`);
}
return Color[level].bold(`[${level.toUpperCase()}]`);
}
/**
* Create the message level emoji string.
*/
messageLevel() {
const level = this.configs.level;
return this.getEmojiByLevel(level, this.configs.customEmoji);
}
/**
* Get the emoji by level.
*/
getEmojiByLevel(level, customEmoji) {
if (customEmoji) {
return customEmoji;
}
const levelEmojis = {
trace: '\u{1F43E}',
debug: '\u{1F50E}',
info: '\u{2139}',
success: '\u{2705}',
warn: '\u{26A0}',
error: '\u{274C}',
fatal: '\u{1F6D1}'
};
if (!levelEmojis[level.toLowerCase()]) {
return '';
}
return levelEmojis[level.toLowerCase()];
}
/**
* Paint the message by level.
*/
paintMessageByLevel(level, message) {
const levelLower = level.toLowerCase();
const levelColors = {
trace: Color.trace,
debug: Color.debug,
info: Color.info,
success: Color.success,
warn: Color.warn,
error: Color.error,
fatal: Color.fatal
};
if (!levelColors[levelLower]) {
return message;
}
return levelColors[levelLower](message);
}
}