simplest-fancy-logger
Version:
A lightweight and easy-to-use logging library for Node.js applications
124 lines (123 loc) • 4.07 kB
JavaScript
import fs from "fs";
import path from "path";
import chalk from "chalk";
const logLevels = {
error: 0,
warn: 1,
info: 2,
debug: 3,
};
const levelColors = {
error: "red",
warn: "yellow",
info: "green",
debug: "blue",
};
const levelEmojis = {
error: "❌",
warn: "⚠️",
info: "✅",
debug: "🐛",
};
class SimpleLogger {
logLevel;
logFile;
logFormat;
dateFormat;
maxFileSize;
maxFiles;
constructor(options = {}) {
this.logLevel = options.logLevel || "info";
this.logFile = options.logFile || null;
this.logFormat =
options.logFormat || "[{level}] [{timestamp}] - {message} - {emoji}";
this.dateFormat = options.dateFormat || "yyyy-mm-dd HH:MM:ss";
this.maxFileSize = options.maxFileSize || 1024 * 1024 * 10; // 10MB
this.maxFiles = options.maxFiles || 5;
}
log(level, message) {
if (logLevels[level] <= logLevels[this.logLevel]) {
const timestamp = this.formatDate(new Date());
const logMessage = this.formatMessage(timestamp, level, message);
console.log(logMessage);
if (this.logFile) {
this.writeToFile(logMessage);
}
}
}
formatDate(date) {
const year = String(date.getFullYear());
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return this.dateFormat
.replace("yyyy", year)
.replace("mm", month)
.replace("dd", day)
.replace("HH", hours)
.replace("MM", minutes)
.replace("ss", seconds);
}
formatMessage(timestamp, level, message) {
const levelColor = levelColors[level] || "white";
const levelEmoji = levelEmojis[level] || "";
const formattedMessage = this.logFormat
.replace("{timestamp}", chalk.magenta(timestamp))
.replace("{level}", chalk[levelColor](level.toUpperCase()))
.replace("{message}", message)
.replace("{emoji}", levelEmoji);
return formattedMessage;
}
writeToFile(logMessage) {
if (!this.logFile) {
return;
}
const fileSize = fs.existsSync(this.logFile)
? fs.statSync(this.logFile).size
: 0;
if (fileSize >= this.maxFileSize) {
this.rotateLogFile();
}
fs.appendFileSync(this.logFile, logMessage + "\n");
}
rotateLogFile() {
if (!this.logFile) {
return;
}
const extension = path.extname(this.logFile);
const baseName = path.basename(this.logFile, extension);
const dirName = path.dirname(this.logFile);
// Correcting the deletion and rotation logic
const oldestFile = path.join(dirName, `${baseName}.${this.maxFiles}${extension}`);
if (fs.existsSync(oldestFile)) {
fs.unlinkSync(oldestFile);
}
for (let i = this.maxFiles - 1; i > 0; i--) {
const currentFile = path.join(dirName, `${baseName}.${i}${extension}`);
const newFile = path.join(dirName, `${baseName}.${i + 1}${extension}`);
if (fs.existsSync(currentFile)) {
fs.renameSync(currentFile, newFile);
}
}
const newFirstFile = path.join(dirName, `${baseName}.1${extension}`);
if (fs.existsSync(this.logFile)) {
fs.renameSync(this.logFile, newFirstFile);
}
}
error(message) {
this.log("error", message);
}
warn(message) {
this.log("warn", message);
}
info(message) {
this.log("info", message);
}
debug(message) {
this.log("debug", message);
}
}
// module export default
export default SimpleLogger;