New Go program (logger/) that: - Accepts POSTed JSON log messages via POST /log - Stores last N messages in a ring buffer (default 1M) - Retrieves logs via GET /logs with limit/before/after filters - Shows status via GET /status Also updates express/logging.ts to POST messages to the logger service. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
// internal-logging.ts
|
|
|
|
import { cli } from "./cli";
|
|
|
|
// FIXME: Move this to somewhere more appropriate
|
|
type AtLeastOne<T> = [T, ...T[]];
|
|
|
|
type MessageSource = "logging" | "diagnostic" | "user";
|
|
|
|
type Message = {
|
|
// FIXME: number probably isn't what we want here
|
|
timestamp?: number;
|
|
source: MessageSource;
|
|
|
|
text: AtLeastOne<string>;
|
|
};
|
|
|
|
const m1: Message = { timestamp: 123, source: "logging", text: ["foo"] };
|
|
const m2: Message = {
|
|
timestamp: 321,
|
|
source: "diagnostic",
|
|
text: ["ok", "whatever"],
|
|
};
|
|
|
|
type FilterArgument = {
|
|
limit?: number;
|
|
before?: number;
|
|
after?: number;
|
|
|
|
// FIXME: add offsets to use instead of or in addition to before/after
|
|
|
|
match?: (string | RegExp)[];
|
|
};
|
|
|
|
const loggerUrl = `http://${cli.logAddress.host}:${cli.logAddress.port}`;
|
|
|
|
const log = (message: Message) => {
|
|
const payload = {
|
|
timestamp: message.timestamp ?? Date.now(),
|
|
source: message.source,
|
|
text: message.text,
|
|
};
|
|
|
|
fetch(`${loggerUrl}/log`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(payload),
|
|
}).catch((err) => {
|
|
console.error("[logging] Failed to send log:", err.message);
|
|
});
|
|
};
|
|
|
|
const getLogs = async (filter: FilterArgument): Promise<Message[]> => {
|
|
const params = new URLSearchParams();
|
|
if (filter.limit) {
|
|
params.set("limit", String(filter.limit));
|
|
}
|
|
if (filter.before) {
|
|
- params.set("before", String(filter.before));
|
|
}
|
|
if (filter.after) {
|
|
params.set("after", String(filter.after));
|
|
}
|
|
|
|
const url = `${loggerUrl}/logs?${params.toString()}`;
|
|
const response = await fetch(url);
|
|
return response.json();
|
|
};
|
|
|
|
// FIXME: there's scope for more specialized functions although they
|
|
// probably should be defined in terms of the basic ones here.
|
|
|
|
export { getLogs, log };
|