@splode/obake
Version:
Check merchants for deals.
96 lines (83 loc) • 2.21 kB
text/typescript
import chalk from "chalk";
import { join } from "path";
import winston, { createLogger, format, transports } from "winston";
import { toSlashDate, toTime } from "./date";
import { ensureDirExists, getUserData } from "./file";
export default class Logger {
public constructor() {
this.logger = createLogger({
levels: winston.config.syslog.levels,
transports: [
new transports.Console({
format: format.combine(formatConsole()),
}),
],
});
}
private logger: winston.Logger;
public crit(msg: string): void {
this.logger.crit(msg);
}
public error(msg: string): void {
this.logger.error(msg);
}
public warn(msg: string): void {
this.logger.warning(msg);
}
public info(msg: string): void {
this.logger.info(msg);
}
public async withFile(): Promise<Logger> {
const userDir = getUserData();
const dataDir = join(userDir || "", "obake");
await ensureDirExists(dataDir).catch((err) => {
throw err;
});
this.logger.add(
new transports.File({
filename: join(dataDir, "obake.log"),
format: format.combine(
format.timestamp(),
format.uncolorize(),
formatFile()
),
maxsize: 16e6, // 16 MB
})
);
return this;
}
}
function formatLevel(level: string, color = false): string {
const l = level.toUpperCase();
if (!color) return l;
switch (level) {
case "crit":
return chalk.black.bgRed(l);
case "error":
return chalk.redBright(l);
case "info":
return chalk.blue(l);
case "warning":
return chalk.yellow(l);
default:
return l;
}
}
function formatConsole(): winston.Logform.Format {
return format.printf(({ level, message }) => {
const msg = `${formatLevel(level, true)}: ${message}`;
return msg;
});
}
function formatFile(): winston.Logform.Format {
return format.printf(({ level, message, timestamp }) => {
const msg = `${formatLevel(level)}: ${formatTimestamp(
timestamp
)} ${message}`;
return msg;
});
}
function formatTimestamp(ts: string): string {
const d = new Date(ts);
return `${toSlashDate(d)} ${toTime(d)}`;
}