mirror of
https://github.com/certd/certd.git
synced 2026-04-23 19:57:27 +08:00
Merge branch 'refs/heads/v2-dev' into v2-dev-buy
# Conflicts: # docs/.vitepress/config.ts # packages/ui/certd-client/src/views/certd/pipeline/sub-domain/index.vue
This commit is contained in:
@@ -1,22 +1,4 @@
|
||||
import log4js, { LoggingEvent, Logger } from "log4js";
|
||||
|
||||
const OutputAppender = {
|
||||
configure: (config: any, layouts: any, findAppender: any, levels: any) => {
|
||||
let layout = layouts.basicLayout;
|
||||
if (config.layout) {
|
||||
layout = layouts.layout(config.layout.type, config.layout);
|
||||
}
|
||||
function customAppender(layout: any, timezoneOffset: any) {
|
||||
return (loggingEvent: LoggingEvent) => {
|
||||
if (loggingEvent.context.outputHandler?.write) {
|
||||
const text = `${layout(loggingEvent, timezoneOffset)}\n`;
|
||||
loggingEvent.context.outputHandler.write(text);
|
||||
}
|
||||
};
|
||||
}
|
||||
return customAppender(layout, config.timezoneOffset);
|
||||
},
|
||||
};
|
||||
import log4js, { CallStack, Level } from "log4js";
|
||||
|
||||
let logFilePath = "./logs/app.log";
|
||||
export function resetLogConfigure() {
|
||||
@@ -24,7 +6,6 @@ export function resetLogConfigure() {
|
||||
log4js.configure({
|
||||
appenders: {
|
||||
std: { type: "stdout" },
|
||||
output: { type: OutputAppender },
|
||||
file: {
|
||||
type: "dateFile",
|
||||
filename: logFilePath,
|
||||
@@ -33,7 +14,7 @@ export function resetLogConfigure() {
|
||||
numBackups: 3,
|
||||
},
|
||||
},
|
||||
categories: { default: { appenders: ["std", "file"], level: "info" }, pipeline: { appenders: ["std", "file", "output"], level: "info" } },
|
||||
categories: { default: { appenders: ["std", "file"], level: "info" }, pipeline: { appenders: ["std", "file"], level: "info" } },
|
||||
});
|
||||
}
|
||||
resetLogConfigure();
|
||||
@@ -44,15 +25,98 @@ export function resetLogFilePath(filePath: string) {
|
||||
resetLogConfigure();
|
||||
}
|
||||
export function buildLogger(write: (text: string) => void) {
|
||||
const logger = log4js.getLogger("pipeline");
|
||||
const _secrets: string[] = [];
|
||||
//@ts-ignore
|
||||
logger.addSecret = (secret: string) => {
|
||||
_secrets.push(secret);
|
||||
};
|
||||
logger.addContext("outputHandler", {
|
||||
write: (text: string) => {
|
||||
for (const item of _secrets) {
|
||||
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;
|
||||
}
|
||||
@@ -66,10 +130,88 @@ export function buildLogger(write: (text: string) => void) {
|
||||
text = text.replaceAll(item, "*".repeat(item.length));
|
||||
}
|
||||
}
|
||||
write(text);
|
||||
},
|
||||
});
|
||||
return logger;
|
||||
}
|
||||
text = `[${formatDateIntl()}] [${level.toUpperCase()}] - ${text} \n`;
|
||||
this.customWriter(text);
|
||||
}
|
||||
// @ts-ignore
|
||||
this.logger[level](...args);
|
||||
}
|
||||
|
||||
export type ILogger = Logger;
|
||||
_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 {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import axios, { AxiosHeaders, AxiosRequestConfig } from "axios";
|
||||
import { ILogger, logger } from "./util.log.js";
|
||||
import { Logger } from "log4js";
|
||||
import { HttpProxyAgent } from "http-proxy-agent";
|
||||
import { HttpsProxyAgent } from "https-proxy-agent";
|
||||
import nodeHttp from "http";
|
||||
@@ -8,6 +7,13 @@ import * as https from "node:https";
|
||||
import { merge } from "lodash-es";
|
||||
import { safePromise } from "./util.promise.js";
|
||||
import fs from "fs";
|
||||
|
||||
const errorMap: Record<string, string> = {
|
||||
"ssl3_get_record:wrong version number": "http协议错误,服务端要求http协议,请检查是否使用了https请求",
|
||||
"getaddrinfo EAI_AGAIN": "无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置",
|
||||
"self-signed certificate": "目标站点为自签名证书,请勾选忽略证书校验",
|
||||
};
|
||||
|
||||
export class HttpError extends Error {
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
@@ -22,11 +28,12 @@ export class HttpError extends Error {
|
||||
super(error.message || error.response?.statusText);
|
||||
|
||||
const message = error?.message;
|
||||
if (message && typeof message === "string") {
|
||||
if (message.indexOf && message.indexOf("ssl3_get_record:wrong version number") >= 0) {
|
||||
this.message = `${message}(http协议错误,服务端要求http协议,请检查是否使用了https请求)`;
|
||||
} else if (message.indexOf("getaddrinfo EAI_AGAIN") >= 0) {
|
||||
this.message = `${message}(无法解析域名,请检查网络连接或dns配置,更换docker-compose.yaml中dns配置)`;
|
||||
if (message && typeof message === "string" && message.indexOf) {
|
||||
for (const key in errorMap) {
|
||||
if (message.indexOf(key) > -1) {
|
||||
this.message = `${this.message}(${errorMap[key]})`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +91,7 @@ export function getGlobalAgents() {
|
||||
/**
|
||||
* @description 创建请求实例
|
||||
*/
|
||||
export function createAxiosService({ logger }: { logger: Logger }) {
|
||||
export function createAxiosService({ logger }: { logger: ILogger }) {
|
||||
// 创建一个 axios 实例
|
||||
const service = axios.create();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user