irontelemetry-go/breadcrumbs.go

97 lines
2.3 KiB
Go

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)
}