Documentation
¶
Overview ¶
Package commentator provides the Event Commentator pattern for domain-aware logging.
The Event Commentator subscribes to all EventBus events and produces insightful log messages that apply domain knowledge to explain what's happening in the system, similar to how a sports commentator adds context and analysis to events.
Index ¶
Constants ¶
const (
// ComponentName is the unique identifier for this component.
ComponentName = "commentator"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type EventCommentator ¶
type EventCommentator struct {
// contains filtered or unexported fields
}
EventCommentator provides domain-aware logging for all events flowing through the EventBus. It decouples logging from business logic.
func NewEventCommentator ¶
func NewEventCommentator(eventBus *busevents.EventBus, logger *slog.Logger, bufferSize int) *EventCommentator
NewEventCommentator creates a new Event Commentator.
Parameters:
- eventBus: The EventBus to subscribe to
- logger: The structured logger to use
- bufferSize: Ring buffer capacity (recommended: 1000)
Returns:
- *EventCommentator ready to start
func (*EventCommentator) Start ¶
func (ec *EventCommentator) Start(ctx context.Context) error
Start begins processing events from the EventBus.
This method blocks until the context is canceled. The component is already subscribed to the EventBus (subscription happens in constructor). Returns nil on graceful shutdown.
Example:
go commentator.Start(ctx)
type RingBuffer ¶
type RingBuffer struct {
// contains filtered or unexported fields
}
RingBuffer is a fixed-capacity circular buffer of recent events used by the commentator for cross-event correlation. Typical capacity: 1000 events.
The Find* queries run a linear scan over the buffer. They're called at most a handful of times per reconciliation-log-line against a buffer capped at ~1000 entries, so the scan cost is negligible and not worth maintaining secondary type/correlation indices (which also have to be cleaned up on wraparound). Old events fall out of every query automatically as the buffer overwrites their slots — there is no separate index to leak.
func NewRingBuffer ¶
func NewRingBuffer(capacity int) *RingBuffer
NewRingBuffer creates a new ring buffer with the specified capacity.
Parameters:
- capacity: Maximum number of events to store (recommended: 1000)
Returns:
- *RingBuffer ready for use
func (*RingBuffer) Add ¶
func (rb *RingBuffer) Add(event busevents.Event)
Add appends an event to the buffer.
If the buffer is full, the oldest event is overwritten (circular behavior).
This operation is O(1).
func (*RingBuffer) Capacity ¶
func (rb *RingBuffer) Capacity() int
Capacity returns the maximum capacity of the buffer.
func (*RingBuffer) FindByCorrelationID ¶
func (rb *RingBuffer) FindByCorrelationID(correlationID string, maxCount int) []busevents.Event
FindByCorrelationID returns events with the specified correlation ID, newest first.
Parameters:
- correlationID: The correlation ID to search for
- maxCount: Maximum number of events to return (0 = no limit)
Returns:
- Slice of events matching the correlation ID, newest first
Example:
// Find all events in a reconciliation cycle
events := rb.FindByCorrelationID("550e8400-e29b-41d4-a716-446655440000", 100)
func (*RingBuffer) FindByTypeInWindow ¶
FindByTypeInWindow returns events of the specified type within the time window, newest first.
Parameters:
- eventType: The event type to filter by
- window: Time duration to look back (e.g., 5 * time.Minute)
Returns:
- Slice of events matching the type and within the window, newest first
Example:
// Find all config validations in the last 5 minutes
events := rb.FindByTypeInWindow("config.validated", 5*time.Minute)