hookherald 0.6.6 → 0.6.8
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/package.json +1 -1
- package/src/dashboard.html +13 -0
- package/src/observability.ts +1 -1
- package/src/webhook-router.ts +5 -3
package/package.json
CHANGED
package/src/dashboard.html
CHANGED
|
@@ -159,6 +159,14 @@
|
|
|
159
159
|
padding: 0 8px 8px;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
.event-source {
|
|
163
|
+
color: var(--purple);
|
|
164
|
+
font-size: 11px;
|
|
165
|
+
overflow: hidden;
|
|
166
|
+
text-overflow: ellipsis;
|
|
167
|
+
white-space: nowrap;
|
|
168
|
+
}
|
|
169
|
+
|
|
162
170
|
.event-row {
|
|
163
171
|
display: grid;
|
|
164
172
|
grid-template-columns: 80px 1fr 80px 80px 50px;
|
|
@@ -183,6 +191,7 @@
|
|
|
183
191
|
display: inline-block;
|
|
184
192
|
}
|
|
185
193
|
.badge.webhook { background: #1f3a5f; color: var(--blue); }
|
|
194
|
+
.badge.watcher { background: #3b2f60; color: var(--purple); }
|
|
186
195
|
.badge.register { background: #1a3a2a; color: var(--green); }
|
|
187
196
|
.badge.unregister { background: #3a1a1a; color: var(--red); }
|
|
188
197
|
.badge.forwarded { background: #1a3a2a; color: var(--green); }
|
|
@@ -339,6 +348,7 @@
|
|
|
339
348
|
<select id="filterType">
|
|
340
349
|
<option value="">All types</option>
|
|
341
350
|
<option value="webhook">webhook</option>
|
|
351
|
+
<option value="watcher">watcher</option>
|
|
342
352
|
<option value="register">register</option>
|
|
343
353
|
<option value="unregister">unregister</option>
|
|
344
354
|
</select>
|
|
@@ -569,6 +579,9 @@ function renderEventDetail(ev) {
|
|
|
569
579
|
html += `<span class="key">Time</span><span class="val">${ev.timestamp}</span>`;
|
|
570
580
|
html += `<span class="key">Type</span><span class="val">${ev.type}</span>`;
|
|
571
581
|
html += `<span class="key">Slug</span><span class="val">${esc(ev.slug)}</span>`;
|
|
582
|
+
if (ev.type === 'watcher' && ev.payload && ev.payload.source) {
|
|
583
|
+
html += `<span class="key">Source</span><span class="val" style="color:var(--purple)">${esc(ev.payload.source)}</span>`;
|
|
584
|
+
}
|
|
572
585
|
html += `<span class="key">Decision</span><span class="val">${ev.routingDecision || 'n/a'}</span>`;
|
|
573
586
|
html += `<span class="key">Response</span><span class="val">${ev.responseStatus}</span>`;
|
|
574
587
|
html += `<span class="key">Duration</span><span class="val">${ev.durationMs}ms</span>`;
|
package/src/observability.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface TraceSpan {
|
|
|
17
17
|
export interface RouterEvent {
|
|
18
18
|
id: string;
|
|
19
19
|
timestamp: string;
|
|
20
|
-
type: "webhook" | "register" | "unregister" | "error";
|
|
20
|
+
type: "webhook" | "watcher" | "register" | "unregister" | "error";
|
|
21
21
|
slug: string;
|
|
22
22
|
routingDecision: "forwarded" | "no_route" | "unauthorized" | "invalid" | null;
|
|
23
23
|
downstreamPort?: number;
|
package/src/webhook-router.ts
CHANGED
|
@@ -277,6 +277,8 @@ async function handleWebhook(req: IncomingMessage, res: ServerResponse) {
|
|
|
277
277
|
return;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
const eventType = payload.source ? "watcher" : "webhook";
|
|
281
|
+
|
|
280
282
|
// Route lookup
|
|
281
283
|
const routeSpan = trace.span("route_lookup");
|
|
282
284
|
const routeInfo = routes.get(slug);
|
|
@@ -288,7 +290,7 @@ async function handleWebhook(req: IncomingMessage, res: ServerResponse) {
|
|
|
288
290
|
metrics.recordRequest(404);
|
|
289
291
|
metrics.recordWebhook("no_route", slug, durationMs);
|
|
290
292
|
|
|
291
|
-
const ev = createRouterEvent(
|
|
293
|
+
const ev = createRouterEvent(eventType, slug, {
|
|
292
294
|
id: traceId,
|
|
293
295
|
routingDecision: "no_route",
|
|
294
296
|
payload: truncatePayload(payload),
|
|
@@ -326,7 +328,7 @@ async function handleWebhook(req: IncomingMessage, res: ServerResponse) {
|
|
|
326
328
|
metrics.recordWebhook("forwarded", slug, durationMs);
|
|
327
329
|
log.info("forwarded", { slug, port: routeInfo.port, status: resp.status, durationMs, traceId });
|
|
328
330
|
|
|
329
|
-
const ev = createRouterEvent(
|
|
331
|
+
const ev = createRouterEvent(eventType, slug, {
|
|
330
332
|
id: traceId,
|
|
331
333
|
routingDecision: "forwarded",
|
|
332
334
|
downstreamPort: routeInfo.port,
|
|
@@ -353,7 +355,7 @@ async function handleWebhook(req: IncomingMessage, res: ServerResponse) {
|
|
|
353
355
|
metrics.recordWebhook("downstream_error", slug, durationMs);
|
|
354
356
|
log.error("forward failed", { slug, port: routeInfo.port, error: err.message, traceId });
|
|
355
357
|
|
|
356
|
-
const ev = createRouterEvent(
|
|
358
|
+
const ev = createRouterEvent(eventType, slug, {
|
|
357
359
|
id: traceId,
|
|
358
360
|
routingDecision: "forwarded",
|
|
359
361
|
downstreamPort: routeInfo.port,
|