mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			228 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package logging
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| )
 | |
| 
 | |
| // Use this abstraction to ensure thread-safe access to the logger's io.Writer
 | |
| // (which could change at runtime)
 | |
| type loggerWriter struct {
 | |
| 	sync.RWMutex
 | |
| 	output io.Writer
 | |
| }
 | |
| 
 | |
| func (lw *loggerWriter) SetOutput(output io.Writer) {
 | |
| 	lw.Lock()
 | |
| 	defer lw.Unlock()
 | |
| 	lw.output = output
 | |
| }
 | |
| 
 | |
| func (lw *loggerWriter) Write(data []byte) (int, error) {
 | |
| 	lw.RLock()
 | |
| 	defer lw.RUnlock()
 | |
| 	return lw.output.Write(data)
 | |
| }
 | |
| 
 | |
| // DefaultLeveledLogger encapsulates functionality for providing logging at
 | |
| // user-defined levels
 | |
| type DefaultLeveledLogger struct {
 | |
| 	level  LogLevel
 | |
| 	writer *loggerWriter
 | |
| 	trace  *log.Logger
 | |
| 	debug  *log.Logger
 | |
| 	info   *log.Logger
 | |
| 	warn   *log.Logger
 | |
| 	err    *log.Logger
 | |
| }
 | |
| 
 | |
| // WithTraceLogger is a chainable configuration function which sets the
 | |
| // Trace-level logger
 | |
| func (ll *DefaultLeveledLogger) WithTraceLogger(log *log.Logger) *DefaultLeveledLogger {
 | |
| 	ll.trace = log
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| // WithDebugLogger is a chainable configuration function which sets the
 | |
| // Debug-level logger
 | |
| func (ll *DefaultLeveledLogger) WithDebugLogger(log *log.Logger) *DefaultLeveledLogger {
 | |
| 	ll.debug = log
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| // WithInfoLogger is a chainable configuration function which sets the
 | |
| // Info-level logger
 | |
| func (ll *DefaultLeveledLogger) WithInfoLogger(log *log.Logger) *DefaultLeveledLogger {
 | |
| 	ll.info = log
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| // WithWarnLogger is a chainable configuration function which sets the
 | |
| // Warn-level logger
 | |
| func (ll *DefaultLeveledLogger) WithWarnLogger(log *log.Logger) *DefaultLeveledLogger {
 | |
| 	ll.warn = log
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| // WithErrorLogger is a chainable configuration function which sets the
 | |
| // Error-level logger
 | |
| func (ll *DefaultLeveledLogger) WithErrorLogger(log *log.Logger) *DefaultLeveledLogger {
 | |
| 	ll.err = log
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| // WithOutput is a chainable configuration function which sets the logger's
 | |
| // logging output to the supplied io.Writer
 | |
| func (ll *DefaultLeveledLogger) WithOutput(output io.Writer) *DefaultLeveledLogger {
 | |
| 	ll.writer.SetOutput(output)
 | |
| 	return ll
 | |
| }
 | |
| 
 | |
| func (ll *DefaultLeveledLogger) logf(logger *log.Logger, level LogLevel, format string, args ...interface{}) {
 | |
| 	if ll.level.Get() < level {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	callDepth := 3 // this frame + wrapper func + caller
 | |
| 	msg := fmt.Sprintf(format, args...)
 | |
| 	if err := logger.Output(callDepth, msg); err != nil {
 | |
| 		fmt.Fprintf(os.Stderr, "Unable to log: %s", err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // SetLevel sets the logger's logging level
 | |
| func (ll *DefaultLeveledLogger) SetLevel(newLevel LogLevel) {
 | |
| 	ll.level.Set(newLevel)
 | |
| }
 | |
| 
 | |
| // Trace emits the preformatted message if the logger is at or below LogLevelTrace
 | |
| func (ll *DefaultLeveledLogger) Trace(msg string) {
 | |
| 	ll.logf(ll.trace, LogLevelTrace, msg)
 | |
| }
 | |
| 
 | |
| // Tracef formats and emits a message if the logger is at or below LogLevelTrace
 | |
| func (ll *DefaultLeveledLogger) Tracef(format string, args ...interface{}) {
 | |
| 	ll.logf(ll.trace, LogLevelTrace, format, args...)
 | |
| }
 | |
| 
 | |
| // Debug emits the preformatted message if the logger is at or below LogLevelDebug
 | |
| func (ll *DefaultLeveledLogger) Debug(msg string) {
 | |
| 	ll.logf(ll.debug, LogLevelDebug, msg)
 | |
| }
 | |
| 
 | |
| // Debugf formats and emits a message if the logger is at or below LogLevelDebug
 | |
| func (ll *DefaultLeveledLogger) Debugf(format string, args ...interface{}) {
 | |
| 	ll.logf(ll.debug, LogLevelDebug, format, args...)
 | |
| }
 | |
| 
 | |
| // Info emits the preformatted message if the logger is at or below LogLevelInfo
 | |
| func (ll *DefaultLeveledLogger) Info(msg string) {
 | |
| 	ll.logf(ll.info, LogLevelInfo, msg)
 | |
| }
 | |
| 
 | |
| // Infof formats and emits a message if the logger is at or below LogLevelInfo
 | |
| func (ll *DefaultLeveledLogger) Infof(format string, args ...interface{}) {
 | |
| 	ll.logf(ll.info, LogLevelInfo, format, args...)
 | |
| }
 | |
| 
 | |
| // Warn emits the preformatted message if the logger is at or below LogLevelWarn
 | |
| func (ll *DefaultLeveledLogger) Warn(msg string) {
 | |
| 	ll.logf(ll.warn, LogLevelWarn, msg)
 | |
| }
 | |
| 
 | |
| // Warnf formats and emits a message if the logger is at or below LogLevelWarn
 | |
| func (ll *DefaultLeveledLogger) Warnf(format string, args ...interface{}) {
 | |
| 	ll.logf(ll.warn, LogLevelWarn, format, args...)
 | |
| }
 | |
| 
 | |
| // Error emits the preformatted message if the logger is at or below LogLevelError
 | |
| func (ll *DefaultLeveledLogger) Error(msg string) {
 | |
| 	ll.logf(ll.err, LogLevelError, msg)
 | |
| }
 | |
| 
 | |
| // Errorf formats and emits a message if the logger is at or below LogLevelError
 | |
| func (ll *DefaultLeveledLogger) Errorf(format string, args ...interface{}) {
 | |
| 	ll.logf(ll.err, LogLevelError, format, args...)
 | |
| }
 | |
| 
 | |
| // NewDefaultLeveledLoggerForScope returns a configured LeveledLogger
 | |
| func NewDefaultLeveledLoggerForScope(scope string, level LogLevel, writer io.Writer) *DefaultLeveledLogger {
 | |
| 	if writer == nil {
 | |
| 		writer = os.Stdout
 | |
| 	}
 | |
| 	logger := &DefaultLeveledLogger{
 | |
| 		writer: &loggerWriter{output: writer},
 | |
| 		level:  level,
 | |
| 	}
 | |
| 	return logger.
 | |
| 		WithTraceLogger(log.New(logger.writer, fmt.Sprintf("%s TRACE: ", scope), log.Lmicroseconds|log.Lshortfile)).
 | |
| 		WithDebugLogger(log.New(logger.writer, fmt.Sprintf("%s DEBUG: ", scope), log.Lmicroseconds|log.Lshortfile)).
 | |
| 		WithInfoLogger(log.New(logger.writer, fmt.Sprintf("%s INFO: ", scope), log.LstdFlags)).
 | |
| 		WithWarnLogger(log.New(logger.writer, fmt.Sprintf("%s WARNING: ", scope), log.LstdFlags)).
 | |
| 		WithErrorLogger(log.New(logger.writer, fmt.Sprintf("%s ERROR: ", scope), log.LstdFlags))
 | |
| }
 | |
| 
 | |
| // DefaultLoggerFactory define levels by scopes and creates new DefaultLeveledLogger
 | |
| type DefaultLoggerFactory struct {
 | |
| 	Writer          io.Writer
 | |
| 	DefaultLogLevel LogLevel
 | |
| 	ScopeLevels     map[string]LogLevel
 | |
| }
 | |
| 
 | |
| // NewDefaultLoggerFactory creates a new DefaultLoggerFactory
 | |
| func NewDefaultLoggerFactory() *DefaultLoggerFactory {
 | |
| 	factory := DefaultLoggerFactory{}
 | |
| 	factory.DefaultLogLevel = LogLevelError
 | |
| 	factory.ScopeLevels = make(map[string]LogLevel)
 | |
| 	factory.Writer = os.Stdout
 | |
| 
 | |
| 	logLevels := map[string]LogLevel{
 | |
| 		"DISABLE": LogLevelDisabled,
 | |
| 		"ERROR":   LogLevelError,
 | |
| 		"WARN":    LogLevelWarn,
 | |
| 		"INFO":    LogLevelInfo,
 | |
| 		"DEBUG":   LogLevelDebug,
 | |
| 		"TRACE":   LogLevelTrace,
 | |
| 	}
 | |
| 
 | |
| 	for name, level := range logLevels {
 | |
| 		env := os.Getenv(fmt.Sprintf("PION_LOG_%s", name))
 | |
| 
 | |
| 		if env == "" {
 | |
| 			env = os.Getenv(fmt.Sprintf("PIONS_LOG_%s", name))
 | |
| 		}
 | |
| 
 | |
| 		if env == "" {
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if strings.ToLower(env) == "all" {
 | |
| 			factory.DefaultLogLevel = level
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		scopes := strings.Split(strings.ToLower(env), ",")
 | |
| 		for _, scope := range scopes {
 | |
| 			factory.ScopeLevels[scope] = level
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return &factory
 | |
| }
 | |
| 
 | |
| // NewLogger returns a configured LeveledLogger for the given , argsscope
 | |
| func (f *DefaultLoggerFactory) NewLogger(scope string) LeveledLogger {
 | |
| 	logLevel := f.DefaultLogLevel
 | |
| 	if f.ScopeLevels != nil {
 | |
| 		scopeLevel, found := f.ScopeLevels[scope]
 | |
| 
 | |
| 		if found {
 | |
| 			logLevel = scopeLevel
 | |
| 		}
 | |
| 	}
 | |
| 	return NewDefaultLeveledLoggerForScope(scope, logLevel, f.Writer)
 | |
| }
 |