mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 04:14:01 +01:00 
			
		
		
		
	1. Add a OpenTelemetry-like shim-layer to collect traces 2. Add a simple builtin trace collector and exporter, end users could download the diagnosis report to get the traces. This PR's design is quite lightweight, no hard-dependency, and it is easy to improve or remove. We can try it on gitea.com first to see whether it works well, and fine tune the details. --------- Co-authored-by: silverwind <me@silverwind.io>
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// 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),
 | 
						|
	}
 | 
						|
})
 |