Files
diachron/express/logging.ts

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 };