summaryrefslogtreecommitdiffhomepage
path: root/packages/observability-collector/src/collector.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/observability-collector/src/collector.ts')
-rw-r--r--packages/observability-collector/src/collector.ts194
1 files changed, 97 insertions, 97 deletions
diff --git a/packages/observability-collector/src/collector.ts b/packages/observability-collector/src/collector.ts
index 157c379..2842915 100644
--- a/packages/observability-collector/src/collector.ts
+++ b/packages/observability-collector/src/collector.ts
@@ -4,39 +4,39 @@ import type { TraceStore } from "@dispatch/trace-store";
// --- Pure core (no I/O) ---
export function shouldPrune(now: number, lastPruneAt: number, intervalMs: number): boolean {
- return now - lastPruneAt >= intervalMs;
+ return now - lastPruneAt >= intervalMs;
}
export interface Logger {
- readonly info: (...args: readonly unknown[]) => void;
- readonly debug: (...args: readonly unknown[]) => void;
+ readonly info: (...args: readonly unknown[]) => void;
+ readonly debug: (...args: readonly unknown[]) => void;
}
export function splitLines(buffer: string): { lines: string[]; remainder: string } {
- const lines: string[] = [];
- let start = 0;
-
- for (let i = 0; i < buffer.length; i++) {
- if (buffer[i] === "\n") {
- lines.push(buffer.slice(start, i));
- start = i + 1;
- }
- }
-
- const remainder = buffer.slice(start);
- return { lines, remainder };
+ const lines: string[] = [];
+ let start = 0;
+
+ for (let i = 0; i < buffer.length; i++) {
+ if (buffer[i] === "\n") {
+ lines.push(buffer.slice(start, i));
+ start = i + 1;
+ }
+ }
+
+ const remainder = buffer.slice(start);
+ return { lines, remainder };
}
// --- Drain step (the unit of work) ---
export interface DrainOpts {
- readonly journalPath: string;
- readonly offset: number;
- readonly store: TraceStore;
+ readonly journalPath: string;
+ readonly offset: number;
+ readonly store: TraceStore;
}
export interface DrainResult {
- readonly newOffset: number;
+ readonly newOffset: number;
}
/**
@@ -46,46 +46,46 @@ export interface DrainResult {
* consumed complete lines (excluding any held remainder).
*/
export function drainOnce(opts: DrainOpts): DrainResult {
- const { journalPath, offset, store } = opts;
-
- let content: string;
- try {
- content = readFileFromOffset(journalPath, offset);
- } catch {
- return { newOffset: offset };
- }
-
- if (content.length === 0) {
- return { newOffset: offset };
- }
-
- const { lines } = splitLines(content);
-
- if (lines.length === 0) {
- return { newOffset: offset };
- }
-
- const records: LogRecord[] = [];
- for (const line of lines) {
- const trimmed = line.trim();
- if (trimmed.length === 0) continue;
- try {
- const parsed: LogRecord = JSON.parse(trimmed);
- records.push(parsed);
- } catch (err) {
- console.warn("[observability-collector] skipping malformed line:", err);
- }
- }
-
- if (records.length > 0) {
- store.insertRecords(records);
- }
-
- const consumedBytes = Buffer.byteLength(
- lines.join("\n") + (lines.length > 0 ? "\n" : ""),
- "utf8",
- );
- return { newOffset: offset + consumedBytes };
+ const { journalPath, offset, store } = opts;
+
+ let content: string;
+ try {
+ content = readFileFromOffset(journalPath, offset);
+ } catch {
+ return { newOffset: offset };
+ }
+
+ if (content.length === 0) {
+ return { newOffset: offset };
+ }
+
+ const { lines } = splitLines(content);
+
+ if (lines.length === 0) {
+ return { newOffset: offset };
+ }
+
+ const records: LogRecord[] = [];
+ for (const line of lines) {
+ const trimmed = line.trim();
+ if (trimmed.length === 0) continue;
+ try {
+ const parsed: LogRecord = JSON.parse(trimmed);
+ records.push(parsed);
+ } catch (err) {
+ console.warn("[observability-collector] skipping malformed line:", err);
+ }
+ }
+
+ if (records.length > 0) {
+ store.insertRecords(records);
+ }
+
+ const consumedBytes = Buffer.byteLength(
+ lines.join("\n") + (lines.length > 0 ? "\n" : ""),
+ "utf8",
+ );
+ return { newOffset: offset + consumedBytes };
}
// --- Offset persistence ---
@@ -94,73 +94,73 @@ export function drainOnce(opts: DrainOpts): DrainResult {
* Read the resume offset from a sidecar file. Returns 0 if missing.
*/
export function readOffset(sidecarPath: string): number {
- try {
- const content = readFileUtf8(sidecarPath).trim();
- const parsed = Number(content);
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
- } catch {
- return 0;
- }
+ try {
+ const content = readFileUtf8(sidecarPath).trim();
+ const parsed = Number(content);
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
+ } catch {
+ return 0;
+ }
}
/**
* Persist the resume offset to a sidecar file.
*/
export function writeOffset(sidecarPath: string, offset: number): void {
- writeFileUtf8(sidecarPath, String(offset));
+ writeFileUtf8(sidecarPath, String(offset));
}
// --- I/O abstraction (injected at edges, default = real fs) ---
export interface FsOps {
- readonly readFileFromOffset: (path: string, offset: number) => string;
- readonly readFileUtf8: (path: string) => string;
- readonly writeFileUtf8: (path: string, data: string) => void;
+ readonly readFileFromOffset: (path: string, offset: number) => string;
+ readonly readFileUtf8: (path: string) => string;
+ readonly writeFileUtf8: (path: string, data: string) => void;
}
let fsOps: FsOps = createDefaultFsOps();
export function setFsOps(ops: FsOps): void {
- fsOps = ops;
+ fsOps = ops;
}
export function resetFsOps(): void {
- fsOps = createDefaultFsOps();
+ fsOps = createDefaultFsOps();
}
function readFileFromOffset(path: string, offset: number): string {
- return fsOps.readFileFromOffset(path, offset);
+ return fsOps.readFileFromOffset(path, offset);
}
function readFileUtf8(path: string): string {
- return fsOps.readFileUtf8(path);
+ return fsOps.readFileUtf8(path);
}
function writeFileUtf8(path: string, data: string): void {
- fsOps.writeFileUtf8(path, data);
+ fsOps.writeFileUtf8(path, data);
}
function createDefaultFsOps(): FsOps {
- const fs = require("node:fs") as typeof import("node:fs");
- return {
- readFileFromOffset(path: string, offset: number): string {
- const fd = fs.openSync(path, "r");
- try {
- const stat = fs.fstatSync(fd);
- const bytesToRead = stat.size - offset;
- if (bytesToRead <= 0) return "";
- const buf = Buffer.alloc(bytesToRead);
- fs.readSync(fd, buf, 0, bytesToRead, offset);
- return buf.toString("utf8");
- } finally {
- fs.closeSync(fd);
- }
- },
- readFileUtf8(path: string): string {
- return fs.readFileSync(path, "utf8");
- },
- writeFileUtf8(path: string, data: string): void {
- fs.writeFileSync(path, data, "utf8");
- },
- };
+ const fs = require("node:fs") as typeof import("node:fs");
+ return {
+ readFileFromOffset(path: string, offset: number): string {
+ const fd = fs.openSync(path, "r");
+ try {
+ const stat = fs.fstatSync(fd);
+ const bytesToRead = stat.size - offset;
+ if (bytesToRead <= 0) return "";
+ const buf = Buffer.alloc(bytesToRead);
+ fs.readSync(fd, buf, 0, bytesToRead, offset);
+ return buf.toString("utf8");
+ } finally {
+ fs.closeSync(fd);
+ }
+ },
+ readFileUtf8(path: string): string {
+ return fs.readFileSync(path, "utf8");
+ },
+ writeFileUtf8(path: string, data: string): void {
+ fs.writeFileSync(path, data, "utf8");
+ },
+ };
}