mirror of
https://github.com/certd/certd.git
synced 2026-04-14 20:40:53 +08:00
218 lines
5.4 KiB
TypeScript
218 lines
5.4 KiB
TypeScript
import log4js, { CallStack, Level } from "log4js";
|
|
|
|
let logFilePath = "./logs/app.log";
|
|
export function resetLogConfigure() {
|
|
// @ts-ignore
|
|
log4js.configure({
|
|
appenders: {
|
|
std: { type: "stdout" },
|
|
file: {
|
|
type: "dateFile",
|
|
filename: logFilePath,
|
|
keepFileExt: true,
|
|
compress: true,
|
|
numBackups: 3,
|
|
},
|
|
},
|
|
categories: { default: { appenders: ["std", "file"], level: "info" }, pipeline: { appenders: ["std", "file"], level: "info" } },
|
|
});
|
|
}
|
|
resetLogConfigure();
|
|
export const logger = log4js.getLogger("default");
|
|
|
|
export function resetLogFilePath(filePath: string) {
|
|
logFilePath = filePath;
|
|
resetLogConfigure();
|
|
}
|
|
export function buildLogger(write: (text: string) => void) {
|
|
return new PipelineLogger("pipeline", write);
|
|
}
|
|
|
|
export type ILogger = {
|
|
readonly category: string;
|
|
level: Level | string;
|
|
log(level: Level | string, ...args: any[]): void;
|
|
|
|
isLevelEnabled(level?: string): boolean;
|
|
|
|
isTraceEnabled(): boolean;
|
|
isDebugEnabled(): boolean;
|
|
isInfoEnabled(): boolean;
|
|
isWarnEnabled(): boolean;
|
|
isErrorEnabled(): boolean;
|
|
isFatalEnabled(): boolean;
|
|
|
|
_log(level: Level, data: any): void;
|
|
|
|
addContext(key: string, value: any): void;
|
|
|
|
removeContext(key: string): void;
|
|
|
|
clearContext(): void;
|
|
|
|
/**
|
|
* Replace the basic parse function with a new custom one
|
|
* - Note that linesToSkip will be based on the origin of the Error object in addition to the callStackLinesToSkip (at least 1)
|
|
* @param parseFunction the new parseFunction. Use `undefined` to reset to the base implementation
|
|
*/
|
|
setParseCallStackFunction(parseFunction: (error: Error, linesToSkip: number) => CallStack | undefined): void;
|
|
|
|
/**
|
|
* Adjust the value of linesToSkip when the parseFunction is called.
|
|
*
|
|
* Cannot be less than 0.
|
|
*/
|
|
callStackLinesToSkip: number;
|
|
|
|
trace(message: any, ...args: any[]): void;
|
|
|
|
debug(message: any, ...args: any[]): void;
|
|
|
|
info(message: any, ...args: any[]): void;
|
|
|
|
warn(message: any, ...args: any[]): void;
|
|
|
|
error(message: any, ...args: any[]): void;
|
|
|
|
fatal(message: any, ...args: any[]): void;
|
|
|
|
mark(message: any, ...args: any[]): void;
|
|
};
|
|
|
|
const locale = Intl.DateTimeFormat().resolvedOptions().locale;
|
|
const formatter = new Intl.DateTimeFormat(locale, {
|
|
year: "numeric",
|
|
month: "2-digit",
|
|
day: "2-digit",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
second: "2-digit",
|
|
hour12: false,
|
|
});
|
|
function formatDateIntl(date = new Date()) {
|
|
const milliseconds = date.getMilliseconds(); // 获取毫秒
|
|
const formattedMilliseconds = milliseconds.toString().padStart(3, "0");
|
|
return formatter.format(date) + "." + formattedMilliseconds;
|
|
}
|
|
|
|
// @ts-ignore
|
|
export class PipelineLogger implements ILogger {
|
|
callStackLinesToSkip: number = 3;
|
|
readonly category: string = "pipeline";
|
|
level: Level | string = "info";
|
|
_secrets: string[] = [];
|
|
logger: ILogger;
|
|
customWriter!: (text: string) => void;
|
|
|
|
constructor(name: string, write: (text: string) => void) {
|
|
this.customWriter = write;
|
|
this.logger = log4js.getLogger(name);
|
|
}
|
|
|
|
addSecret(secret: string) {
|
|
this._secrets.push(secret);
|
|
}
|
|
|
|
_doLog(level: string, ...args: any[]) {
|
|
let text = args.join(" ");
|
|
if (this.customWriter) {
|
|
for (const item of this._secrets) {
|
|
if (item == null) {
|
|
continue;
|
|
}
|
|
if (item.includes(text)) {
|
|
//整个包含
|
|
text = "*".repeat(text.length);
|
|
continue;
|
|
}
|
|
if (text.includes(item)) {
|
|
//换成同长度的*号, item可能有多行
|
|
text = text.replaceAll(item, "*".repeat(item.length));
|
|
}
|
|
}
|
|
text = `[${formatDateIntl()}] [${level.toUpperCase()}] - ${text} \n`;
|
|
this.customWriter(text);
|
|
}
|
|
// @ts-ignore
|
|
this.logger[level](...args);
|
|
}
|
|
|
|
_log(level: Level, data: any): void {}
|
|
|
|
addContext(key: string, value: any): void {}
|
|
|
|
clearContext(): void {}
|
|
|
|
debug(message: any, ...args: any[]): void {
|
|
if (this.isDebugEnabled()) {
|
|
this._doLog("debug", message, ...args);
|
|
}
|
|
}
|
|
|
|
error(message: any, ...args: any[]): void {
|
|
if (this.isErrorEnabled()) {
|
|
this._doLog("error", message, ...args);
|
|
}
|
|
}
|
|
|
|
fatal(message: any, ...args: any[]): void {
|
|
if (this.isFatalEnabled()) {
|
|
this._doLog("fatal", message, ...args);
|
|
}
|
|
}
|
|
|
|
info(message: any, ...args: any[]): void {
|
|
if (this.isInfoEnabled()) {
|
|
this._doLog("info", message, ...args);
|
|
}
|
|
}
|
|
|
|
trace(message: any, ...args: any[]): void {
|
|
if (this.isTraceEnabled()) {
|
|
this._doLog("trace", message, ...args);
|
|
}
|
|
}
|
|
|
|
warn(message: any, ...args: any[]): void {
|
|
if (this.isWarnEnabled()) {
|
|
this._doLog("warn", message, ...args);
|
|
}
|
|
}
|
|
|
|
isDebugEnabled(): boolean {
|
|
return logger.isDebugEnabled();
|
|
}
|
|
|
|
isErrorEnabled(): boolean {
|
|
return logger.isErrorEnabled();
|
|
}
|
|
|
|
isFatalEnabled(): boolean {
|
|
return logger.isFatalEnabled();
|
|
}
|
|
|
|
isInfoEnabled(): boolean {
|
|
return logger.isInfoEnabled();
|
|
}
|
|
|
|
isLevelEnabled(level?: string): boolean {
|
|
return logger.isLevelEnabled();
|
|
}
|
|
|
|
isTraceEnabled(): boolean {
|
|
return logger.isTraceEnabled();
|
|
}
|
|
|
|
isWarnEnabled(): boolean {
|
|
return logger.isWarnEnabled();
|
|
}
|
|
|
|
log(level: Level | string, ...args: any[]): void {}
|
|
|
|
mark(message: any, ...args: any[]): void {}
|
|
|
|
removeContext(key: string): void {}
|
|
|
|
setParseCallStackFunction(parseFunction: (error: Error, linesToSkip: number) => CallStack | undefined): void {}
|
|
}
|