aboutsummaryrefslogtreecommitdiffstats
path: root/modules/tailmsg/talimsg.go
blob: aafc98e2d2d06c52b5f2f1aa75ee1a655b489fbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package tailmsg

import (
	"sync"
	"time"
)

type MsgRecord struct {
	Time    time.Time
	Content string
}

type MsgRecorder interface {
	Record(content string)
	GetRecords() []*MsgRecord
}

type memoryMsgRecorder struct {
	mu    sync.RWMutex
	msgs  []*MsgRecord
	limit int
}

// TODO: use redis for a clustered environment

func (m *memoryMsgRecorder) Record(content string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.msgs = append(m.msgs, &MsgRecord{
		Time:    time.Now(),
		Content: content,
	})
	if len(m.msgs) > m.limit {
		m.msgs = m.msgs[len(m.msgs)-m.limit:]
	}
}

func (m *memoryMsgRecorder) GetRecords() []*MsgRecord {
	m.mu.RLock()
	defer m.mu.RUnlock()
	ret := make([]*MsgRecord, len(m.msgs))
	copy(ret, m.msgs)
	return ret
}

func NewMsgRecorder(limit int) MsgRecorder {
	return &memoryMsgRecorder{
		limit: limit,
	}
}

type Manager struct {
	traceRecorder MsgRecorder
	logRecorder   MsgRecorder
}

func (m *Manager) GetTraceRecorder() MsgRecorder {
	return m.traceRecorder
}

func (m *Manager) GetLogRecorder() MsgRecorder {
	return m.logRecorder
}

var GetManager = sync.OnceValue(func() *Manager {
	return &Manager{
		traceRecorder: NewMsgRecorder(100),
		logRecorder:   NewMsgRecorder(1000),
	}
})