Add backend log management
This commit is contained in:
72
tests/log-manager.test.ts
Normal file
72
tests/log-manager.test.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { readFile, rm, mkdtemp } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { appLogFilePath, clearAppLogs, listAppLogs, recordAppLog } from "@/lib/server/log-manager";
|
||||
|
||||
let runtimeDir = "";
|
||||
let previousRuntimeDir: string | undefined;
|
||||
let previousLogDir: string | undefined;
|
||||
|
||||
describe("server log manager", () => {
|
||||
beforeEach(async () => {
|
||||
runtimeDir = await mkdtemp(join(tmpdir(), "zhinian-logs-"));
|
||||
previousRuntimeDir = process.env.ZHINIAN_RUNTIME_DIR;
|
||||
previousLogDir = process.env.ZHINIAN_LOG_DIR;
|
||||
process.env.ZHINIAN_RUNTIME_DIR = runtimeDir;
|
||||
delete process.env.ZHINIAN_LOG_DIR;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
restoreEnv("ZHINIAN_RUNTIME_DIR", previousRuntimeDir);
|
||||
restoreEnv("ZHINIAN_LOG_DIR", previousLogDir);
|
||||
await rm(runtimeDir, { force: true, recursive: true });
|
||||
});
|
||||
|
||||
it("records, filters, and clears server logs", async () => {
|
||||
await recordAppLog({
|
||||
level: "error",
|
||||
source: "api.test",
|
||||
message: "EvoLink API_KEY=super-secret failed",
|
||||
error: new Error("token=abc123 failed"),
|
||||
status: 500,
|
||||
request: new Request("http://local.test/api/test?x=1", { method: "POST" }),
|
||||
details: {
|
||||
Authorization: "Bearer secret-token",
|
||||
nested: { password: "123456", prompt: "商品海报" }
|
||||
}
|
||||
});
|
||||
await recordAppLog({
|
||||
level: "warning",
|
||||
source: "worker.test",
|
||||
message: "retry scheduled"
|
||||
});
|
||||
|
||||
const errors = await listAppLogs({ level: "error", q: "evolink" });
|
||||
expect(errors).toHaveLength(1);
|
||||
expect(errors[0]).toMatchObject({
|
||||
level: "error",
|
||||
source: "api.test",
|
||||
status: 500,
|
||||
method: "POST",
|
||||
path: "/api/test?x=1"
|
||||
});
|
||||
expect(JSON.stringify(errors[0])).not.toContain("super-secret");
|
||||
expect(JSON.stringify(errors[0])).not.toContain("secret-token");
|
||||
expect(JSON.stringify(errors[0])).not.toContain("123456");
|
||||
|
||||
const raw = await readFile(appLogFilePath(), "utf8");
|
||||
expect(raw).toContain("retry scheduled");
|
||||
|
||||
await clearAppLogs();
|
||||
expect(await listAppLogs()).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
function restoreEnv(name: string, value: string | undefined) {
|
||||
if (value === undefined) {
|
||||
delete process.env[name];
|
||||
return;
|
||||
}
|
||||
process.env[name] = value;
|
||||
}
|
||||
Reference in New Issue
Block a user