hazo_logs 1.0.14 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/lib/log-tail.d.ts +11 -0
- package/dist/lib/log-tail.d.ts.map +1 -0
- package/dist/lib/log-tail.js +161 -0
- package/dist/lib/log-tail.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/ui/api/log-stream-api-handler.d.ts +14 -0
- package/dist/ui/api/log-stream-api-handler.d.ts.map +1 -0
- package/dist/ui/api/log-stream-api-handler.js +53 -0
- package/dist/ui/api/log-stream-api-handler.js.map +1 -0
- package/dist/ui/server.d.ts +2 -0
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/ui/server.js +1 -0
- package/dist/ui/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -562,6 +562,31 @@ const authHandler = withLogAuth(handler, async (request) => {
|
|
|
562
562
|
});
|
|
563
563
|
```
|
|
564
564
|
|
|
565
|
+
## Live tail (v1.1+)
|
|
566
|
+
|
|
567
|
+
`tailLogs` watches the active rotating log file and emits new entries as they are written. Filters mirror `readLogs`. Use it directly for in-process consumers:
|
|
568
|
+
|
|
569
|
+
```ts
|
|
570
|
+
import { tailLogs } from "hazo_logs/server";
|
|
571
|
+
|
|
572
|
+
const ctrl = new AbortController();
|
|
573
|
+
for await (const entry of tailLogs({ reference: ["job-123"], signal: ctrl.signal })) {
|
|
574
|
+
console.log(entry.message);
|
|
575
|
+
}
|
|
576
|
+
// later: ctrl.abort();
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
For SSE-over-HTTP (admin UIs, dashboards), use `createLogStreamApiHandler`:
|
|
580
|
+
|
|
581
|
+
```ts
|
|
582
|
+
import { createLogStreamApiHandler } from "hazo_logs/ui/server";
|
|
583
|
+
|
|
584
|
+
// Next.js app router
|
|
585
|
+
export const GET = createLogStreamApiHandler({ reference: ["job-123"] });
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Clients consume via the standard `EventSource` API. The stream closes when the client disconnects.
|
|
589
|
+
|
|
565
590
|
## Log File Format
|
|
566
591
|
|
|
567
592
|
Logs are stored as newline-delimited JSON:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LogEntry, LogLevel } from "./types.js";
|
|
2
|
+
export interface TailOptions {
|
|
3
|
+
reference?: string[];
|
|
4
|
+
sessionId?: string[];
|
|
5
|
+
level?: LogLevel[];
|
|
6
|
+
package?: string[];
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
logDirectory?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function tailLogs(opts?: TailOptions): AsyncIterable<LogEntry>;
|
|
11
|
+
//# sourceMappingURL=log-tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-tail.d.ts","sourceRoot":"","sources":["../../src/lib/log-tail.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAWD,wBAAgB,QAAQ,CAAC,IAAI,GAAE,WAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC,CAoIxE"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { promises as fsp, watch, statSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { loadConfig } from "./config_loader.js";
|
|
4
|
+
function todayDateString() {
|
|
5
|
+
const d = new Date();
|
|
6
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
7
|
+
}
|
|
8
|
+
function activeLogFile(logDir) {
|
|
9
|
+
return join(logDir, `hazo-${todayDateString()}.log`);
|
|
10
|
+
}
|
|
11
|
+
export function tailLogs(opts = {}) {
|
|
12
|
+
const logDir = opts.logDirectory ?? loadConfig().log_directory;
|
|
13
|
+
return {
|
|
14
|
+
[Symbol.asyncIterator]() {
|
|
15
|
+
const buffer = [];
|
|
16
|
+
const wakers = [];
|
|
17
|
+
let done = false;
|
|
18
|
+
let position = 0;
|
|
19
|
+
let watcher;
|
|
20
|
+
let pollInterval;
|
|
21
|
+
let rolloverInterval;
|
|
22
|
+
let leftover = "";
|
|
23
|
+
let readChain = Promise.resolve();
|
|
24
|
+
let filePath = activeLogFile(logDir);
|
|
25
|
+
// Start at end-of-file: tail only NEW lines, not history.
|
|
26
|
+
try {
|
|
27
|
+
position = statSync(filePath).size;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
position = 0;
|
|
31
|
+
}
|
|
32
|
+
function matches(e) {
|
|
33
|
+
if (opts.reference?.length && !opts.reference.includes(e.reference))
|
|
34
|
+
return false;
|
|
35
|
+
if (opts.sessionId?.length && !opts.sessionId.includes(e.sessionId))
|
|
36
|
+
return false;
|
|
37
|
+
if (opts.level?.length && !opts.level.includes(e.level))
|
|
38
|
+
return false;
|
|
39
|
+
if (opts.package?.length && !opts.package.includes(e.package))
|
|
40
|
+
return false;
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
function deliver(entry) {
|
|
44
|
+
const w = wakers.shift();
|
|
45
|
+
if (w)
|
|
46
|
+
w({ value: entry, done: false });
|
|
47
|
+
else
|
|
48
|
+
buffer.push(entry);
|
|
49
|
+
}
|
|
50
|
+
function finish() {
|
|
51
|
+
if (done)
|
|
52
|
+
return;
|
|
53
|
+
done = true;
|
|
54
|
+
if (rolloverInterval) {
|
|
55
|
+
clearInterval(rolloverInterval);
|
|
56
|
+
rolloverInterval = undefined;
|
|
57
|
+
}
|
|
58
|
+
if (pollInterval) {
|
|
59
|
+
clearInterval(pollInterval);
|
|
60
|
+
pollInterval = undefined;
|
|
61
|
+
}
|
|
62
|
+
watcher?.close();
|
|
63
|
+
while (wakers.length)
|
|
64
|
+
wakers.shift()({ value: undefined, done: true });
|
|
65
|
+
}
|
|
66
|
+
function scheduleRead() {
|
|
67
|
+
readChain = readChain.then(readDelta).catch(() => { });
|
|
68
|
+
}
|
|
69
|
+
async function readDelta() {
|
|
70
|
+
try {
|
|
71
|
+
const st = await fsp.stat(filePath);
|
|
72
|
+
if (st.size < position) {
|
|
73
|
+
// truncation / rotation — restart from current end
|
|
74
|
+
position = st.size;
|
|
75
|
+
leftover = "";
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (st.size === position)
|
|
79
|
+
return;
|
|
80
|
+
const fh = await fsp.open(filePath, "r");
|
|
81
|
+
const len = st.size - position;
|
|
82
|
+
const buf = Buffer.alloc(len);
|
|
83
|
+
await fh.read(buf, 0, len, position);
|
|
84
|
+
await fh.close();
|
|
85
|
+
position = st.size;
|
|
86
|
+
const text = leftover + buf.toString("utf8");
|
|
87
|
+
const lines = text.split("\n");
|
|
88
|
+
leftover = lines.pop() ?? "";
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const trimmed = line.trim();
|
|
91
|
+
if (!trimmed)
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
const parsed = JSON.parse(trimmed);
|
|
95
|
+
if (matches(parsed))
|
|
96
|
+
deliver(parsed);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// skip malformed lines
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// file may not exist yet; ignore
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function startWatcher() {
|
|
108
|
+
try {
|
|
109
|
+
watcher = watch(filePath, scheduleRead);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// file doesn't exist yet — poll until it appears
|
|
113
|
+
pollInterval = setInterval(async () => {
|
|
114
|
+
try {
|
|
115
|
+
await fsp.stat(filePath);
|
|
116
|
+
if (pollInterval)
|
|
117
|
+
clearInterval(pollInterval);
|
|
118
|
+
pollInterval = undefined;
|
|
119
|
+
startWatcher();
|
|
120
|
+
await readDelta();
|
|
121
|
+
}
|
|
122
|
+
catch { /* keep polling */ }
|
|
123
|
+
}, 200);
|
|
124
|
+
pollInterval?.unref?.();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
startWatcher();
|
|
128
|
+
let currentPath = filePath;
|
|
129
|
+
rolloverInterval = setInterval(() => {
|
|
130
|
+
const newPath = activeLogFile(logDir);
|
|
131
|
+
if (newPath !== currentPath) {
|
|
132
|
+
watcher?.close();
|
|
133
|
+
currentPath = newPath;
|
|
134
|
+
filePath = newPath;
|
|
135
|
+
position = 0;
|
|
136
|
+
leftover = "";
|
|
137
|
+
startWatcher();
|
|
138
|
+
void scheduleRead();
|
|
139
|
+
}
|
|
140
|
+
}, 60_000);
|
|
141
|
+
rolloverInterval?.unref?.();
|
|
142
|
+
opts.signal?.addEventListener("abort", finish);
|
|
143
|
+
if (opts.signal?.aborted)
|
|
144
|
+
finish();
|
|
145
|
+
return {
|
|
146
|
+
async next() {
|
|
147
|
+
if (buffer.length)
|
|
148
|
+
return { value: buffer.shift(), done: false };
|
|
149
|
+
if (done)
|
|
150
|
+
return { value: undefined, done: true };
|
|
151
|
+
return new Promise((resolve) => { wakers.push(resolve); });
|
|
152
|
+
},
|
|
153
|
+
async return() {
|
|
154
|
+
finish();
|
|
155
|
+
return { value: undefined, done: true };
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=log-tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-tail.js","sourceRoot":"","sources":["../../src/lib/log-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,KAAK,EAAkB,QAAQ,EAAE,MAAM,IAAI,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWhD,SAAS,eAAe;IACtB,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACnH,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,eAAe,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAoB,EAAE;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC,aAAa,CAAC;IAE/D,OAAO;QACL,CAAC,MAAM,CAAC,aAAa,CAAC;YACpB,MAAM,MAAM,GAAe,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAiD,EAAE,CAAC;YAChE,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,OAA8B,CAAC;YACnC,IAAI,YAAwC,CAAC;YAC7C,IAAI,gBAA4C,CAAC;YACjD,IAAI,QAAQ,GAAG,EAAE,CAAC;YAClB,IAAI,SAAS,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;YAEjD,IAAI,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAErC,0DAA0D;YAC1D,IAAI,CAAC;gBAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,QAAQ,GAAG,CAAC,CAAC;YAAC,CAAC;YAEnE,SAAS,OAAO,CAAC,CAAW;gBAC1B,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAE,CAAS,CAAC,SAAS,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC3F,IAAI,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAE,CAAS,CAAC,SAAS,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC3F,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAiB,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAClF,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC5E,OAAO,IAAI,CAAC;YACd,CAAC;YAED,SAAS,OAAO,CAAC,KAAe;gBAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC;oBAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;;oBACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;YAED,SAAS,MAAM;gBACb,IAAI,IAAI;oBAAE,OAAO;gBACjB,IAAI,GAAG,IAAI,CAAC;gBACZ,IAAI,gBAAgB,EAAE,CAAC;oBAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;oBAAC,gBAAgB,GAAG,SAAS,CAAC;gBAAC,CAAC;gBACxF,IAAI,YAAY,EAAE,CAAC;oBAAC,aAAa,CAAC,YAAY,CAAC,CAAC;oBAAC,YAAY,GAAG,SAAS,CAAC;gBAAC,CAAC;gBAC5E,OAAO,EAAE,KAAK,EAAE,CAAC;gBACjB,OAAO,MAAM,CAAC,MAAM;oBAAE,MAAM,CAAC,KAAK,EAAG,CAAC,EAAE,KAAK,EAAE,SAAgC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjG,CAAC;YAED,SAAS,YAAY;gBACnB,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACxD,CAAC;YAED,KAAK,UAAU,SAAS;gBACtB,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACpC,IAAI,EAAE,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;wBACvB,mDAAmD;wBACnD,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;wBACnB,QAAQ,GAAG,EAAE,CAAC;wBACd,OAAO;oBACT,CAAC;oBACD,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ;wBAAE,OAAO;oBACjC,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;oBACzC,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,QAAQ,CAAC;oBAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC9B,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;oBACrC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;oBACjB,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC;oBACnB,MAAM,IAAI,GAAG,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC/B,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;oBAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;wBAC5B,IAAI,CAAC,OAAO;4BAAE,SAAS;wBACvB,IAAI,CAAC;4BACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;4BAC/C,IAAI,OAAO,CAAC,MAAM,CAAC;gCAAE,OAAO,CAAC,MAAM,CAAC,CAAC;wBACvC,CAAC;wBAAC,MAAM,CAAC;4BACP,uBAAuB;wBACzB,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,iCAAiC;gBACnC,CAAC;YACH,CAAC;YAED,SAAS,YAAY;gBACnB,IAAI,CAAC;oBACH,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC1C,CAAC;gBAAC,MAAM,CAAC;oBACP,iDAAiD;oBACjD,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;wBACpC,IAAI,CAAC;4BACH,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;4BACzB,IAAI,YAAY;gCAAE,aAAa,CAAC,YAAY,CAAC,CAAC;4BAC9C,YAAY,GAAG,SAAS,CAAC;4BACzB,YAAY,EAAE,CAAC;4BACf,MAAM,SAAS,EAAE,CAAC;wBACpB,CAAC;wBAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;oBAChC,CAAC,EAAE,GAAG,CAAC,CAAC;oBACR,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;YACH,CAAC;YAED,YAAY,EAAE,CAAC;YAEf,IAAI,WAAW,GAAG,QAAQ,CAAC;YAC3B,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;gBAClC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;gBACtC,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;oBAC5B,OAAO,EAAE,KAAK,EAAE,CAAC;oBACjB,WAAW,GAAG,OAAO,CAAC;oBACtB,QAAQ,GAAG,OAAO,CAAC;oBACnB,QAAQ,GAAG,CAAC,CAAC;oBACb,QAAQ,GAAG,EAAE,CAAC;oBACd,YAAY,EAAE,CAAC;oBACf,KAAK,YAAY,EAAE,CAAC;gBACtB,CAAC;YACH,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,gBAAgB,EAAE,KAAK,EAAE,EAAE,CAAC;YAE5B,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM,EAAE,CAAC;YAEnC,OAAO;gBACL,KAAK,CAAC,IAAI;oBACR,IAAI,MAAM,CAAC,MAAM;wBAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oBAClE,IAAI,IAAI;wBAAE,OAAO,EAAE,KAAK,EAAE,SAAgC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;oBACzE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,CAAC;gBACD,KAAK,CAAC,MAAM;oBACV,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,KAAK,EAAE,SAAgC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBACjE,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -21,4 +21,6 @@ export { generateSessionId, startSession, startSessionAsync, runWithLogContext,
|
|
|
21
21
|
export { readLogs, getAvailableLogDates, getUniquePackages, getUniqueExecutionIds, getUniqueSessionIds, getUniqueReferences, } from './lib/log-reader.js';
|
|
22
22
|
export type { Logger, LogLevel, LogData, LogEntry, LogContext, HazoLogConfig, PackageLoggerOptions, LogOrigin, } from './lib/types.js';
|
|
23
23
|
export type { ReadLogsOptions, LogQueryResult } from './lib/log-reader.js';
|
|
24
|
+
export { tailLogs } from "./lib/log-tail.js";
|
|
25
|
+
export type { TailOptions } from "./lib/log-tail.js";
|
|
24
26
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,MAAM,EACN,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,MAAM,EACN,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -22,4 +22,5 @@ export { loadConfig } from './lib/config_loader.js';
|
|
|
22
22
|
export { generateSessionId, startSession, startSessionAsync, runWithLogContext, runWithLogContextAsync, getLogContext, withSession, withContext, } from './lib/context/log-context.js';
|
|
23
23
|
// Log reader (uses fs, readline)
|
|
24
24
|
export { readLogs, getAvailableLogDates, getUniquePackages, getUniqueExecutionIds, getUniqueSessionIds, getUniqueReferences, } from './lib/log-reader.js';
|
|
25
|
+
export { tailLogs } from "./lib/log-tail.js";
|
|
25
26
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,aAAa,CAAC;AAErB,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAEtC,iCAAiC;AACjC,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,aAAa,CAAC;AAErB,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,uCAAuC;AACvC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,8BAA8B,CAAC;AAEtC,iCAAiC;AACjC,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAgB7B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LogLevel } from "../../lib/types.js";
|
|
2
|
+
export interface LogStreamApiOptions {
|
|
3
|
+
reference?: string[];
|
|
4
|
+
sessionId?: string[];
|
|
5
|
+
level?: LogLevel[];
|
|
6
|
+
package?: string[];
|
|
7
|
+
logDirectory?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Returns a Web-API handler that streams tailLogs() output as Server-Sent Events.
|
|
11
|
+
* Honours the request's AbortSignal (closes the underlying watcher when the client disconnects).
|
|
12
|
+
*/
|
|
13
|
+
export declare function createLogStreamApiHandler(opts?: LogStreamApiOptions): (req: Request) => Promise<Response>;
|
|
14
|
+
//# sourceMappingURL=log-stream-api-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-stream-api-handler.d.ts","sourceRoot":"","sources":["../../../src/ui/api/log-stream-api-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,GAAE,mBAAwB,IACxC,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CA4C/D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// NOTE: Intentionally NOT importing 'server-only' here, matching sibling
|
|
2
|
+
// handlers (log-api-handler.ts, client-log-handler.ts). The server-only
|
|
3
|
+
// guard lives at the aggregator (src/ui/server.ts) so this file can be
|
|
4
|
+
// unit-tested directly under vitest.
|
|
5
|
+
import { tailLogs } from "../../lib/log-tail.js";
|
|
6
|
+
/**
|
|
7
|
+
* Returns a Web-API handler that streams tailLogs() output as Server-Sent Events.
|
|
8
|
+
* Honours the request's AbortSignal (closes the underlying watcher when the client disconnects).
|
|
9
|
+
*/
|
|
10
|
+
export function createLogStreamApiHandler(opts = {}) {
|
|
11
|
+
return async function handler(req) {
|
|
12
|
+
const ctrl = new AbortController();
|
|
13
|
+
req.signal.addEventListener("abort", () => ctrl.abort());
|
|
14
|
+
// Allow per-request overrides via query string.
|
|
15
|
+
const url = new URL(req.url);
|
|
16
|
+
const ref = url.searchParams.getAll("reference");
|
|
17
|
+
const sess = url.searchParams.getAll("sessionId");
|
|
18
|
+
const lvl = url.searchParams.getAll("level");
|
|
19
|
+
const pkg = url.searchParams.getAll("package");
|
|
20
|
+
const tailOpts = {
|
|
21
|
+
reference: ref.length ? ref : opts.reference,
|
|
22
|
+
sessionId: sess.length ? sess : opts.sessionId,
|
|
23
|
+
level: lvl.length ? lvl : opts.level,
|
|
24
|
+
package: pkg.length ? pkg : opts.package,
|
|
25
|
+
logDirectory: opts.logDirectory,
|
|
26
|
+
signal: ctrl.signal,
|
|
27
|
+
};
|
|
28
|
+
const encoder = new TextEncoder();
|
|
29
|
+
const stream = new ReadableStream({
|
|
30
|
+
async start(controller) {
|
|
31
|
+
try {
|
|
32
|
+
for await (const entry of tailLogs(tailOpts)) {
|
|
33
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(entry)}\n\n`));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
controller.enqueue(encoder.encode(`event: error\ndata: ${JSON.stringify({ error: String(err) })}\n\n`));
|
|
38
|
+
}
|
|
39
|
+
controller.close();
|
|
40
|
+
},
|
|
41
|
+
cancel() { ctrl.abort(); },
|
|
42
|
+
});
|
|
43
|
+
return new Response(stream, {
|
|
44
|
+
status: 200,
|
|
45
|
+
headers: {
|
|
46
|
+
"content-type": "text/event-stream",
|
|
47
|
+
"cache-control": "no-cache",
|
|
48
|
+
"connection": "keep-alive",
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=log-stream-api-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-stream-api-handler.js","sourceRoot":"","sources":["../../../src/ui/api/log-stream-api-handler.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,wEAAwE;AACxE,uEAAuE;AACvE,qCAAqC;AACrC,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAWnE;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAA4B,EAAE;IACtE,OAAO,KAAK,UAAU,OAAO,CAAC,GAAY;QACxC,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;QACnC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAEzD,gDAAgD;QAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAe,CAAC;QAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAgB;YAC5B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS;YAC5C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS;YAC9C,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;YACpC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;YACxC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAa;YAC5C,KAAK,CAAC,KAAK,CAAC,UAAU;gBACpB,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC7C,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC3E,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC1G,CAAC;gBACD,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;YACD,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;SAC3B,CAAC,CAAC;QAEH,OAAO,IAAI,QAAQ,CAAC,MAAM,EAAE;YAC1B,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACP,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,YAAY,EAAE,YAAY;aAC3B;SACF,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/ui/server.d.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import 'server-only';
|
|
10
10
|
export { createLogApiHandler } from './api/log-api-handler.js';
|
|
11
11
|
export { createClientLogHandler } from './api/client-log-handler.js';
|
|
12
|
+
export { createLogStreamApiHandler } from './api/log-stream-api-handler.js';
|
|
13
|
+
export type { LogStreamApiOptions } from './api/log-stream-api-handler.js';
|
|
12
14
|
export { withLogAuth } from './middleware/with-log-auth.js';
|
|
13
15
|
export type { LogApiConfig, LogApiHandler, AuthCheckFn, } from './types.js';
|
|
14
16
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/ui/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAG5D,YAAY,EACV,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/ui/server.js
CHANGED
|
@@ -10,6 +10,7 @@ import 'server-only';
|
|
|
10
10
|
// API Handlers
|
|
11
11
|
export { createLogApiHandler } from './api/log-api-handler.js';
|
|
12
12
|
export { createClientLogHandler } from './api/client-log-handler.js';
|
|
13
|
+
export { createLogStreamApiHandler } from './api/log-stream-api-handler.js';
|
|
13
14
|
// Middleware
|
|
14
15
|
export { withLogAuth } from './middleware/with-log-auth.js';
|
|
15
16
|
//# sourceMappingURL=server.js.map
|
package/dist/ui/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,aAAa,CAAC;AAErB,eAAe;AACf,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,aAAa,CAAC;AAErB,eAAe;AACf,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,aAAa;AACb,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC"}
|