gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package log
  4. import (
  5. "context"
  6. "fmt"
  7. "sync"
  8. "sync/atomic"
  9. )
  10. const DEFAULT = "default"
  11. // LoggerManager manages loggers and shared event writers
  12. type LoggerManager struct {
  13. ctx context.Context
  14. ctxCancel context.CancelFunc
  15. mu sync.Mutex
  16. writers map[string]EventWriter
  17. loggers map[string]*LoggerImpl
  18. defaultLogger atomic.Pointer[LoggerImpl]
  19. pauseMu sync.RWMutex
  20. pauseChan chan struct{}
  21. }
  22. // GetLogger returns a logger with the given name. If the logger doesn't exist, a new empty one will be created.
  23. func (m *LoggerManager) GetLogger(name string) *LoggerImpl {
  24. if name == DEFAULT {
  25. if logger := m.defaultLogger.Load(); logger != nil {
  26. return logger
  27. }
  28. }
  29. m.mu.Lock()
  30. defer m.mu.Unlock()
  31. logger := m.loggers[name]
  32. if logger == nil {
  33. logger = NewLoggerWithWriters(m.ctx, name)
  34. m.loggers[name] = logger
  35. if name == DEFAULT {
  36. m.defaultLogger.Store(logger)
  37. }
  38. }
  39. return logger
  40. }
  41. // PauseAll pauses all event writers
  42. func (m *LoggerManager) PauseAll() {
  43. m.pauseMu.Lock()
  44. m.pauseChan = make(chan struct{})
  45. m.pauseMu.Unlock()
  46. }
  47. // ResumeAll resumes all event writers
  48. func (m *LoggerManager) ResumeAll() {
  49. m.pauseMu.Lock()
  50. close(m.pauseChan)
  51. m.pauseChan = nil
  52. m.pauseMu.Unlock()
  53. }
  54. // GetPauseChan returns a channel for writer pausing
  55. func (m *LoggerManager) GetPauseChan() chan struct{} {
  56. m.pauseMu.RLock()
  57. defer m.pauseMu.RUnlock()
  58. return m.pauseChan
  59. }
  60. // Close closes the logger manager, all loggers and writers will be closed, the messages are flushed.
  61. func (m *LoggerManager) Close() {
  62. m.mu.Lock()
  63. defer m.mu.Unlock()
  64. for _, logger := range m.loggers {
  65. logger.Close()
  66. }
  67. m.loggers = map[string]*LoggerImpl{}
  68. for _, writer := range m.writers {
  69. eventWriterStopWait(writer)
  70. }
  71. m.writers = map[string]EventWriter{}
  72. m.ctxCancel()
  73. }
  74. // DumpLoggers returns a map of all loggers and their event writers, for debugging and display purposes.
  75. func (m *LoggerManager) DumpLoggers() map[string]any {
  76. m.mu.Lock()
  77. defer m.mu.Unlock()
  78. dump := map[string]any{}
  79. for name, logger := range m.loggers {
  80. loggerDump := map[string]any{
  81. "IsEnabled": logger.IsEnabled(),
  82. "EventWriters": logger.DumpWriters(),
  83. }
  84. dump[name] = loggerDump
  85. }
  86. return dump
  87. }
  88. // 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.
  89. func (m *LoggerManager) NewSharedWriter(writerName, writerType string, mode WriterMode) (writer EventWriter, err error) {
  90. m.mu.Lock()
  91. defer m.mu.Unlock()
  92. if _, ok := m.writers[writerName]; ok {
  93. return nil, fmt.Errorf("log event writer %q has been added before", writerName)
  94. }
  95. if writer, err = NewEventWriter(writerName, writerType, mode); err != nil {
  96. return nil, err
  97. }
  98. m.writers[writerName] = writer
  99. eventWriterStartGo(m.ctx, writer, true)
  100. return writer, nil
  101. }
  102. func (m *LoggerManager) GetSharedWriter(writerName string) EventWriter {
  103. m.mu.Lock()
  104. defer m.mu.Unlock()
  105. return m.writers[writerName]
  106. }
  107. var loggerManager = NewManager()
  108. func GetManager() *LoggerManager {
  109. return loggerManager
  110. }
  111. func NewManager() *LoggerManager {
  112. m := &LoggerManager{writers: map[string]EventWriter{}, loggers: map[string]*LoggerImpl{}}
  113. m.ctx, m.ctxCancel = newProcessTypedContext(context.Background(), "LoggerManager")
  114. return m
  115. }