package irontelemetry import ( "sync" "time" ) // BreadcrumbManager manages a ring buffer of breadcrumbs type BreadcrumbManager struct { mu sync.RWMutex breadcrumbs []Breadcrumb maxBreadcrumbs int } // NewBreadcrumbManager creates a new BreadcrumbManager func NewBreadcrumbManager(maxBreadcrumbs int) *BreadcrumbManager { return &BreadcrumbManager{ breadcrumbs: make([]Breadcrumb, 0, maxBreadcrumbs), maxBreadcrumbs: maxBreadcrumbs, } } // Add adds a breadcrumb to the ring buffer func (bm *BreadcrumbManager) Add(breadcrumb Breadcrumb) { bm.mu.Lock() defer bm.mu.Unlock() if breadcrumb.Timestamp.IsZero() { breadcrumb.Timestamp = time.Now() } if len(bm.breadcrumbs) >= bm.maxBreadcrumbs { // Shift elements to make room (ring buffer behavior) copy(bm.breadcrumbs, bm.breadcrumbs[1:]) bm.breadcrumbs = bm.breadcrumbs[:len(bm.breadcrumbs)-1] } bm.breadcrumbs = append(bm.breadcrumbs, breadcrumb) } // AddSimple adds a simple breadcrumb with just a message and category func (bm *BreadcrumbManager) AddSimple(message string, category BreadcrumbCategory) { bm.Add(Breadcrumb{ Timestamp: time.Now(), Category: category, Message: message, Level: SeverityInfo, }) } // AddWithLevel adds a breadcrumb with a specific level func (bm *BreadcrumbManager) AddWithLevel(message string, category BreadcrumbCategory, level SeverityLevel) { bm.Add(Breadcrumb{ Timestamp: time.Now(), Category: category, Message: message, Level: level, }) } // AddWithData adds a breadcrumb with additional data func (bm *BreadcrumbManager) AddWithData(message string, category BreadcrumbCategory, level SeverityLevel, data map[string]any) { bm.Add(Breadcrumb{ Timestamp: time.Now(), Category: category, Message: message, Level: level, Data: data, }) } // GetAll returns a copy of all breadcrumbs func (bm *BreadcrumbManager) GetAll() []Breadcrumb { bm.mu.RLock() defer bm.mu.RUnlock() result := make([]Breadcrumb, len(bm.breadcrumbs)) copy(result, bm.breadcrumbs) return result } // Clear removes all breadcrumbs func (bm *BreadcrumbManager) Clear() { bm.mu.Lock() defer bm.mu.Unlock() bm.breadcrumbs = make([]Breadcrumb, 0, bm.maxBreadcrumbs) } // Count returns the number of breadcrumbs func (bm *BreadcrumbManager) Count() int { bm.mu.RLock() defer bm.mu.RUnlock() return len(bm.breadcrumbs) }