142 lines · 3.3 KB · Go
RawDownload
// Copyright 2023 The Gitea Authors. All rights reserved.// SPDX-License-Identifier: MIT package log import (	"context"	"fmt"	"sync"	"sync/atomic") const DEFAULT = "default" // LoggerManager manages loggers and shared event writerstype LoggerManager struct {	ctx       context.Context	ctxCancel context.CancelFunc 	mu            sync.Mutex	writers       map[string]EventWriter	loggers       map[string]*LoggerImpl	defaultLogger atomic.Pointer[LoggerImpl] 	pauseMu   sync.RWMutex	pauseChan chan struct{}} // GetLogger returns a logger with the given name. If the logger doesn't exist, a new empty one will be created.func (m *LoggerManager) GetLogger(name string) *LoggerImpl {	if name == DEFAULT {		if logger := m.defaultLogger.Load(); logger != nil {			return logger		}	} 	m.mu.Lock()	defer m.mu.Unlock() 	logger := m.loggers[name]	if logger == nil {		logger = NewLoggerWithWriters(m.ctx, name)		m.loggers[name] = logger		if name == DEFAULT {			m.defaultLogger.Store(logger)		}	} 	return logger} // PauseAll pauses all event writersfunc (m *LoggerManager) PauseAll() {	m.pauseMu.Lock()	m.pauseChan = make(chan struct{})	m.pauseMu.Unlock()} // ResumeAll resumes all event writersfunc (m *LoggerManager) ResumeAll() {	m.pauseMu.Lock()	close(m.pauseChan)	m.pauseChan = nil	m.pauseMu.Unlock()} // GetPauseChan returns a channel for writer pausingfunc (m *LoggerManager) GetPauseChan() chan struct{} {	m.pauseMu.RLock()	defer m.pauseMu.RUnlock()	return m.pauseChan} // Close closes the logger manager, all loggers and writers will be closed, the messages are flushed.func (m *LoggerManager) Close() {	m.mu.Lock()	defer m.mu.Unlock() 	for _, logger := range m.loggers {		logger.Close()	}	m.loggers = map[string]*LoggerImpl{} 	for _, writer := range m.writers {		eventWriterStopWait(writer)	}	m.writers = map[string]EventWriter{} 	m.ctxCancel()} // DumpLoggers returns a map of all loggers and their event writers, for debugging and display purposes.func (m *LoggerManager) DumpLoggers() map[string]any {	m.mu.Lock()	defer m.mu.Unlock() 	dump := map[string]any{}	for name, logger := range m.loggers {		loggerDump := map[string]any{			"IsEnabled":    logger.IsEnabled(),			"EventWriters": logger.DumpWriters(),		}		dump[name] = loggerDump	}	return dump} // NewSharedWriter creates a new shared event writer, it can be used by multiple loggers, and a shared writer won't be closed if a logger is closed.func (m *LoggerManager) NewSharedWriter(writerName, writerType string, mode WriterMode) (writer EventWriter, err error) {	m.mu.Lock()	defer m.mu.Unlock() 	if _, ok := m.writers[writerName]; ok {		return nil, fmt.Errorf("log event writer %q has been added before", writerName)	} 	if writer, err = NewEventWriter(writerName, writerType, mode); err != nil {		return nil, err	} 	m.writers[writerName] = writer	eventWriterStartGo(m.ctx, writer, true)	return writer, nil} func (m *LoggerManager) GetSharedWriter(writerName string) EventWriter {	m.mu.Lock()	defer m.mu.Unlock()	return m.writers[writerName]} var loggerManager = NewManager() func GetManager() *LoggerManager {	return loggerManager} func NewManager() *LoggerManager {	m := &LoggerManager{writers: map[string]EventWriter{}, loggers: map[string]*LoggerImpl{}}	m.ctx, m.ctxCancel = newProcessTypedContext(context.Background(), "LoggerManager")	return m}