mirror of
https://github.com/idootop/mi-gpt.git
synced 2025-04-06 22:08:23 +00:00
feat: add Logger
This commit is contained in:
parent
7ad50322fe
commit
2dc65da0fe
3
TODO.md
3
TODO.md
|
@ -2,3 +2,6 @@
|
|||
- ✅ Stream response
|
||||
- ✅ Deactivate Xiaoai
|
||||
- ✅ Update long/short memories
|
||||
- ✅ Logger
|
||||
- Docker
|
||||
- Npm export
|
|
@ -4,6 +4,7 @@ import { readJSON, writeJSON } from "../../utils/io";
|
|||
import { DeepPartial } from "../../utils/type";
|
||||
import { RoomCRUD, getRoomID } from "../db/room";
|
||||
import { UserCRUD } from "../db/user";
|
||||
import { Logger } from "../../utils/log";
|
||||
|
||||
const kDefaultMaster = {
|
||||
name: "用户",
|
||||
|
@ -27,6 +28,7 @@ export interface IBotConfig {
|
|||
}
|
||||
|
||||
class _BotConfig {
|
||||
private _logger = Logger.create({ tag: "BotConfig" });
|
||||
private botIndex?: IBotIndex;
|
||||
|
||||
private _index_path = ".bot.json";
|
||||
|
@ -44,12 +46,12 @@ class _BotConfig {
|
|||
// create db records
|
||||
const bot = await UserCRUD.addOrUpdate(kDefaultBot);
|
||||
if (!bot) {
|
||||
console.error("❌ create bot failed");
|
||||
this._logger.error("create bot failed");
|
||||
return undefined;
|
||||
}
|
||||
const master = await UserCRUD.addOrUpdate(kDefaultMaster);
|
||||
if (!master) {
|
||||
console.error("❌ create master failed");
|
||||
this._logger.error("create master failed");
|
||||
return undefined;
|
||||
}
|
||||
const defaultRoomName = `${master.name}和${bot.name}的私聊`;
|
||||
|
@ -59,7 +61,7 @@ class _BotConfig {
|
|||
description: defaultRoomName,
|
||||
});
|
||||
if (!room) {
|
||||
console.error("❌ create room failed");
|
||||
this._logger.error("create room failed");
|
||||
return undefined;
|
||||
}
|
||||
this.botIndex = {
|
||||
|
@ -70,17 +72,17 @@ class _BotConfig {
|
|||
}
|
||||
const bot = await UserCRUD.get(this.botIndex!.botId);
|
||||
if (!bot) {
|
||||
console.error("❌ find bot failed");
|
||||
this._logger.error("find bot failed");
|
||||
return undefined;
|
||||
}
|
||||
const master = await UserCRUD.get(this.botIndex!.masterId);
|
||||
if (!master) {
|
||||
console.error("❌ find master failed");
|
||||
this._logger.error("find master failed");
|
||||
return undefined;
|
||||
}
|
||||
const room = await RoomCRUD.get(getRoomID([bot, master]));
|
||||
if (!room) {
|
||||
console.error("❌ find room failed");
|
||||
this._logger.error("find room failed");
|
||||
return undefined;
|
||||
}
|
||||
return { bot, master, room };
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import { PrismaClient } from "@prisma/client";
|
||||
import { Logger } from "../../utils/log";
|
||||
|
||||
export const k404 = -404;
|
||||
|
||||
export const kPrisma = new PrismaClient();
|
||||
|
||||
export const kDBLogger = Logger.create({ tag: "DB" });
|
||||
export function runWithDB(main: () => Promise<void>) {
|
||||
main()
|
||||
.then(async () => {
|
||||
await kPrisma.$disconnect();
|
||||
})
|
||||
.catch(async (e) => {
|
||||
console.error(e);
|
||||
kDBLogger.error(e);
|
||||
await kPrisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { LongTermMemory, Room, User } from "@prisma/client";
|
||||
import { removeEmpty } from "../../utils/base";
|
||||
import { getSkipWithCursor, k404, kPrisma } from "./index";
|
||||
import { getSkipWithCursor, k404, kDBLogger, kPrisma } from "./index";
|
||||
|
||||
class _LongTermMemoryCRUD {
|
||||
async count(options?: { cursorId?: number; room?: Room; owner?: User }) {
|
||||
|
@ -14,14 +14,14 @@ class _LongTermMemoryCRUD {
|
|||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get longTermMemory count failed", e);
|
||||
kDBLogger.error("get longTermMemory count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
async get(id: number) {
|
||||
return kPrisma.longTermMemory.findFirst({ where: { id } }).catch((e) => {
|
||||
console.error("❌ get long term memory failed", id, e);
|
||||
kDBLogger.error("get long term memory failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class _LongTermMemoryCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get long term memories failed", options, e);
|
||||
kDBLogger.error("get long term memories failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? memories.reverse() : memories;
|
||||
|
@ -82,7 +82,7 @@ class _LongTermMemoryCRUD {
|
|||
update: data,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ add longTermMemory to db failed", longTermMemory, e);
|
||||
kDBLogger.error("add longTermMemory to db failed", longTermMemory, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Room, ShortTermMemory, User } from "@prisma/client";
|
||||
import { removeEmpty } from "../../utils/base";
|
||||
import { getSkipWithCursor, k404, kPrisma } from "./index";
|
||||
import { getSkipWithCursor, k404, kDBLogger, kPrisma } from "./index";
|
||||
|
||||
class _ShortTermMemoryCRUD {
|
||||
async count(options?: { cursorId?: number; room?: Room; owner?: User }) {
|
||||
|
@ -14,14 +14,14 @@ class _ShortTermMemoryCRUD {
|
|||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get shortTermMemory count failed", e);
|
||||
kDBLogger.error("get shortTermMemory count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
async get(id: number) {
|
||||
return kPrisma.shortTermMemory.findFirst({ where: { id } }).catch((e) => {
|
||||
console.error("❌ get short term memory failed", id, e);
|
||||
kDBLogger.error("get short term memory failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class _ShortTermMemoryCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get short term memories failed", options, e);
|
||||
kDBLogger.error("get short term memories failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? memories.reverse() : memories;
|
||||
|
@ -82,11 +82,7 @@ class _ShortTermMemoryCRUD {
|
|||
update: data,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
"❌ add shortTermMemory to db failed",
|
||||
shortTermMemory,
|
||||
e
|
||||
);
|
||||
kDBLogger.error("add shortTermMemory to db failed", shortTermMemory, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Memory, Prisma, Room, User } from "@prisma/client";
|
||||
import { getSkipWithCursor, k404, kPrisma } from "./index";
|
||||
import { removeEmpty } from "../../utils/base";
|
||||
import { getSkipWithCursor, k404, kDBLogger, kPrisma } from "./index";
|
||||
|
||||
class _MemoryCRUD {
|
||||
async count(options?: { cursorId?: number; room?: Room; owner?: User }) {
|
||||
|
@ -14,7 +14,7 @@ class _MemoryCRUD {
|
|||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get memory count failed", e);
|
||||
kDBLogger.error("get memory count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class _MemoryCRUD {
|
|||
},
|
||||
} = options ?? {};
|
||||
return kPrisma.memory.findFirst({ where: { id }, include }).catch((e) => {
|
||||
console.error("❌ get memory failed", id, e);
|
||||
kDBLogger.error("get memory failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class _MemoryCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get memories failed", options, e);
|
||||
kDBLogger.error("get memories failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? memories.reverse() : memories;
|
||||
|
@ -98,7 +98,7 @@ class _MemoryCRUD {
|
|||
update: data,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ add memory to db failed", memory, e);
|
||||
kDBLogger.error("add memory to db failed", memory, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Message, Prisma, Room, User } from "@prisma/client";
|
||||
import { removeEmpty } from "../../utils/base";
|
||||
import { getSkipWithCursor, k404, kPrisma } from "./index";
|
||||
import { getSkipWithCursor, k404, kDBLogger, kPrisma } from "./index";
|
||||
|
||||
class _MessageCRUD {
|
||||
async count(options?: { cursorId?: number; room?: Room; sender?: User }) {
|
||||
|
@ -14,7 +14,7 @@ class _MessageCRUD {
|
|||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get message count failed", e);
|
||||
kDBLogger.error("get message count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class _MessageCRUD {
|
|||
) {
|
||||
const { include = { sender: true } } = options ?? {};
|
||||
return kPrisma.message.findFirst({ where: { id }, include }).catch((e) => {
|
||||
console.error("❌ get message failed", id, e);
|
||||
kDBLogger.error("get message failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class _MessageCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get messages failed", options, e);
|
||||
kDBLogger.error("get messages failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? messages.reverse() : messages;
|
||||
|
@ -89,7 +89,7 @@ class _MessageCRUD {
|
|||
update: data,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ add message to db failed", message, e);
|
||||
kDBLogger.error("add message to db failed", message, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Prisma, Room, User } from "@prisma/client";
|
||||
import { k404, kPrisma, getSkipWithCursor } from "./index";
|
||||
import { k404, kPrisma, getSkipWithCursor, kDBLogger } from "./index";
|
||||
|
||||
export function getRoomID(users: User[]) {
|
||||
return users
|
||||
|
@ -22,7 +22,7 @@ class _RoomCRUD {
|
|||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get room count failed", e);
|
||||
kDBLogger.error("get room count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class _RoomCRUD {
|
|||
) {
|
||||
const { include = { members: true } } = options ?? {};
|
||||
return kPrisma.room.findFirst({ where: { id } }).catch((e) => {
|
||||
console.error("❌ get room failed", id, e);
|
||||
kDBLogger.error("get room failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class _RoomCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get rooms failed", options, e);
|
||||
kDBLogger.error("get rooms failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? rooms.reverse() : rooms;
|
||||
|
@ -89,7 +89,7 @@ class _RoomCRUD {
|
|||
update: room,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ add room to db failed", room, e);
|
||||
kDBLogger.error("add room to db failed", room, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Prisma, User } from "@prisma/client";
|
||||
import { getSkipWithCursor, k404, kPrisma } from "./index";
|
||||
import { getSkipWithCursor, k404, kDBLogger, kPrisma } from "./index";
|
||||
|
||||
class _UserCRUD {
|
||||
async count() {
|
||||
return kPrisma.user.count().catch((e) => {
|
||||
console.error("❌ get user count failed", e);
|
||||
kDBLogger.error("get user count failed", e);
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class _UserCRUD {
|
|||
) {
|
||||
const { include = { rooms: false } } = options ?? {};
|
||||
return kPrisma.user.findFirst({ where: { id }, include }).catch((e) => {
|
||||
console.error("❌ get user failed", id, e);
|
||||
kDBLogger.error("get user failed", id, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class _UserCRUD {
|
|||
...getSkipWithCursor(skip, cursorId),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ get users failed", options, e);
|
||||
kDBLogger.error("get users failed", options, e);
|
||||
return [];
|
||||
});
|
||||
return order === "desc" ? users.reverse() : users;
|
||||
|
@ -68,7 +68,7 @@ class _UserCRUD {
|
|||
update: user,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ add user to db failed", user, e);
|
||||
kDBLogger.error("add user to db failed", user, e);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import axios, { AxiosRequestConfig, CreateAxiosDefaults } from "axios";
|
||||
import { HttpsProxyAgent } from "https-proxy-agent";
|
||||
import { isNotEmpty } from "../utils/is";
|
||||
import { Logger } from "../utils/log";
|
||||
|
||||
export const kProxyAgent = new HttpsProxyAgent(
|
||||
process.env.HTTP_PROXY ?? "http://127.0.0.1:7890"
|
||||
|
@ -29,6 +30,7 @@ type RequestConfig = AxiosRequestConfig<any> & {
|
|||
cookies?: Record<string, string | number | boolean | undefined>;
|
||||
};
|
||||
|
||||
const _logger = Logger.create({ tag: "Http" });
|
||||
_http.interceptors.response.use(
|
||||
(res) => {
|
||||
const config: any = res.config;
|
||||
|
@ -45,8 +47,8 @@ _http.interceptors.response.use(
|
|||
code: error.code ?? "UNKNOWN CODE",
|
||||
message: error.message ?? "UNKNOWN ERROR",
|
||||
};
|
||||
console.error(
|
||||
"❌ Network request failed:",
|
||||
_logger.error(
|
||||
"Network request failed:",
|
||||
apiError.code,
|
||||
apiError.message,
|
||||
error
|
||||
|
|
|
@ -8,6 +8,7 @@ import { kEnvs } from "../utils/env";
|
|||
import { kProxyAgent } from "./http";
|
||||
import { withDefault } from "../utils/base";
|
||||
import { ChatCompletionCreateParamsBase } from "openai/resources/chat/completions";
|
||||
import { Logger } from "../utils/log";
|
||||
|
||||
export interface ChatOptions {
|
||||
user: string;
|
||||
|
@ -19,6 +20,7 @@ export interface ChatOptions {
|
|||
}
|
||||
|
||||
class OpenAIClient {
|
||||
private _logger = Logger.create({ tag: "OpenAI" });
|
||||
private _client = new OpenAI({
|
||||
httpAgent: kProxyAgent,
|
||||
apiKey: kEnvs.OPENAI_API_KEY!,
|
||||
|
@ -44,9 +46,8 @@ class OpenAIClient {
|
|||
requestId,
|
||||
model = kEnvs.OPENAI_MODEL ?? "gpt-3.5-turbo-0125",
|
||||
} = options;
|
||||
console.log(
|
||||
`
|
||||
🔥🔥🔥 onAskAI start
|
||||
this._logger.log(
|
||||
`🔥 onAskAI
|
||||
🤖️ System: ${system ?? "None"}
|
||||
😊 User: ${user}
|
||||
`.trim()
|
||||
|
@ -71,16 +72,11 @@ class OpenAIClient {
|
|||
{ signal }
|
||||
)
|
||||
.catch((e) => {
|
||||
console.error("❌ openai chat failed", e);
|
||||
this._logger.error("openai chat failed", e);
|
||||
return null;
|
||||
});
|
||||
const message = chatCompletion?.choices?.[0]?.message;
|
||||
console.log(
|
||||
`
|
||||
✅✅✅ onAskAI end
|
||||
🤖️ Answer: ${message?.content ?? "None"}
|
||||
`.trim()
|
||||
);
|
||||
this._logger.success(`🤖️ Answer: ${message?.content ?? "None"}`.trim());
|
||||
return message;
|
||||
}
|
||||
|
||||
|
@ -98,9 +94,8 @@ class OpenAIClient {
|
|||
onStream,
|
||||
model = kEnvs.OPENAI_MODEL ?? "gpt-3.5-turbo-0125",
|
||||
} = options;
|
||||
console.log(
|
||||
`
|
||||
🔥🔥🔥 onAskAI start
|
||||
this._logger.log(
|
||||
`🔥 onAskAI
|
||||
🤖️ System: ${system ?? "None"}
|
||||
😊 User: ${user}
|
||||
`.trim()
|
||||
|
@ -117,7 +112,7 @@ class OpenAIClient {
|
|||
response_format: jsonMode ? { type: "json_object" } : undefined,
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("❌ openai chat failed", e);
|
||||
this._logger.error("❌ openai chat failed", e);
|
||||
return null;
|
||||
});
|
||||
if (!stream) {
|
||||
|
@ -140,12 +135,7 @@ class OpenAIClient {
|
|||
content += text;
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
`
|
||||
✅✅✅ onAskAI end
|
||||
🤖️ Answer: ${content ?? "None"}
|
||||
`.trim()
|
||||
);
|
||||
this._logger.success(`🤖️ Answer: ${content ?? "None"}`.trim());
|
||||
return withDefault(content, undefined);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { assert } from "console";
|
||||
import {
|
||||
MiIOT,
|
||||
MiNA,
|
||||
MiServiceConfig,
|
||||
getMiIOT,
|
||||
getMiNA,
|
||||
MiNA,
|
||||
MiIOT,
|
||||
} from "mi-service-lite";
|
||||
import { sleep } from "../../utils/base";
|
||||
import { Logger } from "../../utils/log";
|
||||
import { Http } from "../http";
|
||||
import { StreamResponse } from "./stream";
|
||||
|
||||
|
@ -26,6 +26,7 @@ export type BaseSpeakerConfig = MiServiceConfig & {
|
|||
};
|
||||
|
||||
export class BaseSpeaker {
|
||||
logger = Logger.create({ tag: "Speaker" });
|
||||
MiNA?: MiNA;
|
||||
MiIOT?: MiIOT;
|
||||
|
||||
|
@ -42,7 +43,7 @@ export class BaseSpeaker {
|
|||
async initMiServices() {
|
||||
this.MiNA = await getMiNA(this.config);
|
||||
this.MiIOT = await getMiIOT(this.config);
|
||||
assert(!!this.MiNA && !!this.MiIOT, "❌ init Mi Services failed");
|
||||
this.logger.assert(!!this.MiNA && !!this.MiIOT, "init Mi Services failed");
|
||||
}
|
||||
|
||||
wakeUp() {
|
||||
|
@ -169,7 +170,7 @@ export class BaseSpeaker {
|
|||
await this.unWakeUp();
|
||||
}
|
||||
await this.MiNA!.play(args);
|
||||
console.log("✅ " + ttsText ?? audio);
|
||||
this.logger.success(ttsText ?? audio);
|
||||
// 等待回答播放完毕
|
||||
while (true) {
|
||||
const res = await this.MiNA!.getStatus();
|
||||
|
|
|
@ -64,13 +64,13 @@ export class Speaker extends BaseSpeaker {
|
|||
if (!this.MiNA) {
|
||||
this.stop();
|
||||
}
|
||||
console.log("✅ 服务已启动...");
|
||||
this.logger.success("服务已启动...");
|
||||
this.activeKeepAliveMode();
|
||||
while (this.status === "running") {
|
||||
const nextMsg = await this.fetchNextMessage();
|
||||
if (nextMsg) {
|
||||
this.responding = false;
|
||||
console.log("🔥 " + nextMsg.text);
|
||||
this.logger.log("🔥 " + nextMsg.text);
|
||||
// 异步处理消息,不阻塞正常消息拉取
|
||||
this.onMessage(nextMsg);
|
||||
}
|
||||
|
|
110
src/utils/log.ts
Normal file
110
src/utils/log.ts
Normal file
|
@ -0,0 +1,110 @@
|
|||
import { toSet } from "./base";
|
||||
import { isString } from "./is";
|
||||
import { formatDateTime } from "./string";
|
||||
|
||||
class _LoggerManager {
|
||||
disable = false;
|
||||
_excludes: string[] = [];
|
||||
|
||||
excludes(tags: string[]) {
|
||||
this._excludes = toSet(this._excludes.concat(tags));
|
||||
}
|
||||
|
||||
includes(tags: string[]) {
|
||||
for (const tag of tags) {
|
||||
const idx = this._excludes.indexOf(tag);
|
||||
if (idx > -1) {
|
||||
this._excludes.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _getLogs(tag: string, ...args: any[]) {
|
||||
if (this.disable || this._excludes.includes(tag)) {
|
||||
return [];
|
||||
}
|
||||
const date = formatDateTime(new Date());
|
||||
let prefix = `${date} ${tag} `;
|
||||
if (args.length < 1) {
|
||||
args = [undefined];
|
||||
}
|
||||
if (isString(args[0])) {
|
||||
prefix += args[0];
|
||||
args = args.slice(1);
|
||||
}
|
||||
return [prefix, ...args];
|
||||
}
|
||||
|
||||
log(tag: string, args: any[] = []) {
|
||||
const logs = this._getLogs(tag, ...args);
|
||||
if (logs.length > 0) {
|
||||
console.log(...logs);
|
||||
}
|
||||
}
|
||||
|
||||
success(tag: string, args: any[]) {
|
||||
const logs = this._getLogs(tag + " ✅", ...args);
|
||||
if (logs.length > 0) {
|
||||
console.log(...logs);
|
||||
}
|
||||
}
|
||||
|
||||
error(tag: string, args: any[]) {
|
||||
const logs = this._getLogs(tag + " ❌", ...args);
|
||||
if (logs.length > 0) {
|
||||
console.error(...logs);
|
||||
}
|
||||
}
|
||||
|
||||
assert(tag: string, value: any, args: any[]) {
|
||||
const logs = this._getLogs(tag + " ❌", ...args);
|
||||
if (!value) {
|
||||
console.error(...logs);
|
||||
throw Error("❌ Assertion failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const LoggerManager = new _LoggerManager();
|
||||
|
||||
export interface LoggerConfig {
|
||||
tag?: string;
|
||||
disable?: boolean;
|
||||
}
|
||||
class _Logger {
|
||||
tag: string;
|
||||
disable: boolean;
|
||||
constructor(config?: LoggerConfig) {
|
||||
const { tag = "default", disable = false } = config ?? {};
|
||||
this.tag = tag;
|
||||
this.disable = disable;
|
||||
}
|
||||
|
||||
create(config?: LoggerConfig) {
|
||||
return new _Logger(config);
|
||||
}
|
||||
|
||||
log(...args: any[]) {
|
||||
if (!this.disable) {
|
||||
LoggerManager.log(this.tag, args);
|
||||
}
|
||||
}
|
||||
|
||||
success(...args: any[]) {
|
||||
if (!this.disable) {
|
||||
LoggerManager.success(this.tag, args);
|
||||
}
|
||||
}
|
||||
|
||||
error(...args: any[]) {
|
||||
if (!this.disable) {
|
||||
LoggerManager.error(this.tag, args);
|
||||
}
|
||||
}
|
||||
|
||||
assert(value: any, ...args: any[]) {
|
||||
LoggerManager.assert(this.tag, value, args);
|
||||
}
|
||||
}
|
||||
|
||||
export const Logger = new _Logger();
|
|
@ -52,3 +52,14 @@ export function formatMsg(msg: {
|
|||
const { name, text, timestamp } = msg;
|
||||
return `${toUTC8Time(new Date(timestamp))} ${name}: ${text}`;
|
||||
}
|
||||
|
||||
export function formatDateTime(date: Date) {
|
||||
const year = 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 `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { testDB } from "./db";
|
|||
import { testSpeaker } from "./speaker";
|
||||
import { testOpenAI } from "./openai";
|
||||
import { testMyBot } from "./bot";
|
||||
import { testLog } from "./log";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
|
@ -14,7 +15,8 @@ async function main() {
|
|||
// testDB();
|
||||
// testSpeaker();
|
||||
// testOpenAI();
|
||||
testMyBot();
|
||||
// testMyBot();
|
||||
testLog();
|
||||
}
|
||||
|
||||
runWithDB(main);
|
||||
|
|
9
tests/log.ts
Normal file
9
tests/log.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { Logger } from "../src/utils/log";
|
||||
|
||||
export function testLog() {
|
||||
Logger.log("你好", ["世界"], { hello: "world!" });
|
||||
Logger.success("你好", ["世界"], { hello: "world!" });
|
||||
Logger.error("你好", ["世界"], { hello: "world!" });
|
||||
Logger.assert(true, "你好 111", ["世界"], { hello: "world!" });
|
||||
Logger.assert(false, "你好 222", ["世界"], { hello: "world!" });
|
||||
}
|
Loading…
Reference in New Issue
Block a user