Subscribers Panel
The Subscriber Delivery panel at /subscribers shows a real-time log of every message delivered to registered subscribers, including delivery status, topic breakdown, and timing. It uses SubscribersMonitor from @edge-stream/observability-react.
Route and Component
// Route in App.tsx
<Route path="/subscribers" element={<SubscribersPage />} />
// SubscribersPage source: packages/app-pages-react/src/SubscribersPage.tsx
export function SubscribersPage(): React.ReactElement {
return <SubscribersMonitor
className="page-container"
showSettings={true}
pollInterval={500}
maxLogs={100}
/>
}
// SubscribersMonitor from: @edge-stream/observability-react
SubscribersMonitor — How It Works
// Polls LoggingService every 500ms (same ring buffer as HooksMonitor):
useEffect(() => {
const interval = setInterval(() => {
const logs = loggingService.getRecentLogs(maxLogs);
setLogs(logs);
}, pollInterval);
return () => clearInterval(interval);
}, [maxLogs, pollInterval]);
// Flattens subscriber logs from all message activity logs:
const allSubscriberLogs = logs.flatMap((msg) => msg.subscriberLogs || []);
// Topic breakdown — a Map from topic string to array of subscriber logs:
const topicStats = new Map<string, SubscriberLog[]>();
for (const log of allSubscriberLogs) {
const existing = topicStats.get(log.topic) ?? [];
topicStats.set(log.topic, [...existing, log]);
}
// Global stats:
const stats = {
total: allSubscriberLogs.length,
delivered: allSubscriberLogs.filter((s) => s.status === 'delivered').length,
failed: allSubscriberLogs.filter((s) => s.status === 'failed').length,
pending: allSubscriberLogs.filter((s) => s.status === 'pending').length,
};
SubscriberLog Entry Fields
| Field | Type | Description |
|---|---|---|
| subscriberName | string | Identifier for the subscriber (typically the topic pattern registered) |
| topic | string | The exact topic string of the message delivered (e.g. workflow.step.completed) |
| status | string | delivered, failed, or pending |
| durationMs | number | Time from delivery attempt to completion in milliseconds |
| error | string? | Error message if the subscriber threw during delivery |
| messageId | string | Links to IEnvelope.meta.id — correlates with the Hooks Panel |
| serverId | string | Which registered server this message came from |
Topic Breakdown
The Subscribers Panel groups delivery logs by topic, showing how many messages each topic has delivered, failed, and the topics that are most active. This helps identify over-subscribed topics or topics with high failure rates.
// Per-topic stats displayed as a breakdown table:
// Topic | Delivered | Failed | Total
// workflow.step.completed | 42 | 0 | 42
// agent.message.received | 18 | 2 | 20
// system.health | 10 | 0 | 10
// ancp.heartbeat | 152 | 0 | 152
// Filter by topic (text match on topic string):
const filtered = allSubscriberLogs.filter((log) =>
log.topic.toLowerCase().includes(topicFilter.toLowerCase())
);
Delivery Status Reference
| Status | Color | Meaning |
|---|---|---|
| delivered | Green | Subscriber callback completed without throwing |
| failed | Red | Subscriber callback threw an error during execution |
| pending | Yellow | Delivery in progress (async subscriber not yet resolved) |
Difference Between Hooks Panel and Subscribers Panel
| Aspect | Hooks Panel | Subscribers Panel |
|---|---|---|
| What it monitors | Pipeline hook execution (transforms, validation, security) | Subscriber callback delivery (your application code) |
| Data source | MessageActivityLog.hookLogs[] | MessageActivityLog.subscriberLogs[] |
| Primary field | hookName + priority + result | topic + status + durationMs |
| Failure impact | Hook failure can stop/reroute the pipeline | Subscriber failure is logged but does not affect other subscribers |
| Filter by | Hook name (substring) | Topic (substring) |
Subscribers Reference Panel
The Subscribers Reference at /subscribers-reference shows all available subscriber types with their topic patterns and configuration. Use it to discover which topics are available for subscription in the current pipeline configuration:
// Route in App.tsx
<Route path="/subscribers-reference" element={<SubscribersReferencePage />} />
// SubscribersReferencePage: packages/app-pages-react/src/SubscribersReferencePage.tsx
// Sidebar label: "Available Subscribers"
// Also available via help:
<Route path="/help/subscribers" element={<SubscribersHelpPage />} />
Registering Subscribers to Log
Subscriber delivery is only logged when HookActivityLogger is present in the pipeline AND stream.subscribe() is called. Wildcard topic subscriptions generate one log entry per matching message:
import { HookActivityLogger } from 'edge-stream-js';
// Required: enables logging for both hooks and subscribers
server.incomingPipeline.addHook(new HookActivityLogger());
// Subscribe — each delivery is logged with status + duration:
stream.subscribe('bas', 'workflow.*', async (envelope) => {
// If this throws, status = 'failed' and error is captured
await processWorkflowEvent(envelope.body);
});
// Wildcard subscriptions show individual topic matches in the panel:
// workflow.step.started → delivered in 12ms
// workflow.step.completed → delivered in 8ms
// workflow.flow.stopped → delivered in 5ms
messageId field that appears in both Hooks Panel entries and Subscriber Panel entries to trace a specific message through the entire pipeline — from hook execution to subscriber delivery.