package message import ( "fmt" "io" "sync" ) const timestampFmt = "2006-01-02 15:04:05" // History contains the history entries type History struct { sync.RWMutex entries []Message head int size int out io.Writer } // NewHistory constructs a new history of the given size func NewHistory(size int) *History { return &History{ entries: make([]Message, size), } } // Add adds the given entry to the entries in the history func (h *History) Add(entry Message) { h.Lock() defer h.Unlock() max := cap(h.entries) h.head = (h.head + 1) % max h.entries[h.head] = entry if h.size < max { h.size++ } if h.out != nil { fmt.Fprintf(h.out, "[%s] %s\n", entry.Timestamp().UTC().Format(timestampFmt), entry.String()) } } // Len returns the number of entries in the history func (h *History) Len() int { return h.size } // Get the entry with the given number func (h *History) Get(num int) []Message { h.RLock() defer h.RUnlock() max := cap(h.entries) if num > h.size { num = h.size } r := make([]Message, num) for i := 0; i < num; i++ { idx := (h.head - i) % max if idx < 0 { idx += max } r[num-i-1] = h.entries[idx] } return r } // SetOutput sets the output for logging added messages func (h *History) SetOutput(w io.Writer) { h.Lock() h.out = w h.Unlock() }