openclaw / src /plugins /runtime /runtime-logging.test.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
4c76b0d verified
Raw
History Blame Contribute Delete
3.92 kB
// Runtime logging tests cover plugin runtime log routing and verbosity behavior.
import { beforeEach, describe, expect, it, vi } from "vitest";
const loggingMocks = vi.hoisted(() => {
const childLogger = {
debug: vi.fn(),
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
};
const isFileLogLevelEnabled = vi.fn((_level: string) => true);
return {
childLogger,
getChildLogger: vi.fn(() => childLogger),
isFileLogLevelEnabled,
};
});
vi.mock("../../globals.js", () => ({
shouldLogVerbose: vi.fn(() => false),
}));
vi.mock("../../logging.js", () => ({
getChildLogger: loggingMocks.getChildLogger,
isFileLogLevelEnabled: loggingMocks.isFileLogLevelEnabled,
}));
let createRuntimeLogging: typeof import("./runtime-logging.js").createRuntimeLogging;
beforeEach(async () => {
vi.clearAllMocks();
loggingMocks.getChildLogger.mockReturnValue(loggingMocks.childLogger);
loggingMocks.isFileLogLevelEnabled.mockReturnValue(true);
({ createRuntimeLogging } = await import("./runtime-logging.js"));
});
describe("createRuntimeLogging", () => {
it("forwards structured metadata to child loggers", () => {
const logging = createRuntimeLogging();
const logger = logging.getChildLogger({ plugin: "discord" }, { level: "warn" });
const meta = {
errorName: "Error",
errorCauseName: "TypeError",
};
logger.debug?.("debug details", meta);
logger.info("info details", meta);
logger.warn("warn details", meta);
logger.error("error details", meta);
expect(loggingMocks.getChildLogger).toHaveBeenCalledWith(
{ plugin: "discord" },
{ level: "warn" },
);
expect(loggingMocks.childLogger.debug).toHaveBeenCalledWith(meta, "debug details");
expect(loggingMocks.childLogger.info).toHaveBeenCalledWith(meta, "info details");
expect(loggingMocks.childLogger.warn).toHaveBeenCalledWith(meta, "warn details");
expect(loggingMocks.childLogger.error).toHaveBeenCalledWith(meta, "error details");
logger.info("message without metadata");
logger.warn("message with empty metadata", {});
expect(loggingMocks.childLogger.info).toHaveBeenLastCalledWith("message without metadata");
expect(loggingMocks.childLogger.warn).toHaveBeenLastCalledWith("message with empty metadata");
});
it("resolves the child logger per call so a runtime log-level change takes effect", () => {
const logging = createRuntimeLogging();
// Mirror a long-lived channel monitor: capture the logger once, log later.
const logger = logging.getChildLogger({ module: "mattermost" });
// Level is below debug when the monitor starts: the write is dropped.
loggingMocks.isFileLogLevelEnabled.mockReturnValue(false);
logger.debug?.("dropped before debug enabled");
expect(loggingMocks.childLogger.debug).not.toHaveBeenCalled();
expect(loggingMocks.getChildLogger).not.toHaveBeenCalled();
// Log level raised to debug on the running gateway: the same captured logger
// must now write, because it re-resolves the child logger per call.
loggingMocks.isFileLogLevelEnabled.mockReturnValue(true);
logger.debug?.("written after debug enabled");
expect(loggingMocks.getChildLogger).toHaveBeenCalledWith({ module: "mattermost" }, undefined);
expect(loggingMocks.childLogger.debug).toHaveBeenCalledWith("written after debug enabled");
});
it("pre-gates on the current file level when no override is set", () => {
loggingMocks.isFileLogLevelEnabled.mockImplementation((level: string) => level !== "debug");
const logging = createRuntimeLogging();
const logger = logging.getChildLogger({ module: "mattermost" });
logger.debug?.("debug suppressed at info");
logger.info("info written at info");
expect(loggingMocks.childLogger.debug).not.toHaveBeenCalled();
expect(loggingMocks.childLogger.info).toHaveBeenCalledWith("info written at info");
});
});