mirror of https://github.com/jetkvm/kvm.git
263 lines
6.9 KiB
Go
263 lines
6.9 KiB
Go
// This is an internal package to patch the Pion logging library to use the
|
|
// zerolog instead of the log package.
|
|
package logging
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
var defaultOutput io.Writer = zerolog.ConsoleWriter{
|
|
Out: os.Stdout,
|
|
TimeFormat: time.RFC3339,
|
|
PartsOrder: []string{"time", "level", "scope", "message"},
|
|
FieldsExclude: []string{"scope"},
|
|
FormatPartValueByName: func(value interface{}, name string) string {
|
|
val := fmt.Sprintf("%s", value)
|
|
if name == "scope" {
|
|
if strings.HasPrefix(val, "jetkvm/") {
|
|
return val[7:]
|
|
} else {
|
|
// scope without prefix, we assume it's from the pion library
|
|
return fmt.Sprintf("pion/%s", val)
|
|
}
|
|
}
|
|
return val
|
|
},
|
|
}
|
|
|
|
func SetDefaultOutput(output io.Writer) {
|
|
defaultOutput = output
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
type zerologEventLogger func() *zerolog.Event
|
|
|
|
// DefaultLeveledLogger encapsulates functionality for providing logging at.
|
|
// user-defined levels.
|
|
type DefaultLeveledLogger struct {
|
|
level LogLevel
|
|
writer *zerolog.Logger
|
|
trace zerologEventLogger
|
|
debug zerologEventLogger
|
|
info zerologEventLogger
|
|
warn zerologEventLogger
|
|
err zerologEventLogger
|
|
}
|
|
|
|
func (ll *DefaultLeveledLogger) GetLogger() *zerolog.Logger {
|
|
return ll.writer
|
|
}
|
|
|
|
// WithTraceLogger is a chainable configuration function which sets the
|
|
// Trace-level logger.
|
|
func (ll *DefaultLeveledLogger) WithTraceLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
|
ll.trace = log
|
|
|
|
return ll
|
|
}
|
|
|
|
// WithDebugLogger is a chainable configuration function which sets the
|
|
// Debug-level logger.
|
|
func (ll *DefaultLeveledLogger) WithDebugLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
|
ll.debug = log
|
|
|
|
return ll
|
|
}
|
|
|
|
// WithInfoLogger is a chainable configuration function which sets the
|
|
// Info-level logger.
|
|
func (ll *DefaultLeveledLogger) WithInfoLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
|
ll.info = log
|
|
|
|
return ll
|
|
}
|
|
|
|
// WithWarnLogger is a chainable configuration function which sets the
|
|
// Warn-level logger.
|
|
func (ll *DefaultLeveledLogger) WithWarnLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
|
ll.warn = log
|
|
|
|
return ll
|
|
}
|
|
|
|
// WithErrorLogger is a chainable configuration function which sets the
|
|
// Error-level logger.
|
|
func (ll *DefaultLeveledLogger) WithErrorLogger(log zerologEventLogger) *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.Output(output)
|
|
|
|
return ll
|
|
}
|
|
|
|
// 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.trace().Msgf(msg)
|
|
}
|
|
|
|
// Tracef formats and emits a message if the logger is at or below LogLevelTrace.
|
|
func (ll *DefaultLeveledLogger) Tracef(format string, args ...interface{}) {
|
|
ll.trace().Msgf(format, args...)
|
|
}
|
|
|
|
// Debug emits the preformatted message if the logger is at or below LogLevelDebug.
|
|
func (ll *DefaultLeveledLogger) Debug(msg string) {
|
|
ll.debug().Msgf(msg)
|
|
}
|
|
|
|
// Debugf formats and emits a message if the logger is at or below LogLevelDebug.
|
|
func (ll *DefaultLeveledLogger) Debugf(format string, args ...interface{}) {
|
|
ll.debug().Msgf(format, args...)
|
|
}
|
|
|
|
// Info emits the preformatted message if the logger is at or below LogLevelInfo.
|
|
func (ll *DefaultLeveledLogger) Info(msg string) {
|
|
ll.info().Msgf(msg)
|
|
}
|
|
|
|
// Infof formats and emits a message if the logger is at or below LogLevelInfo.
|
|
func (ll *DefaultLeveledLogger) Infof(format string, args ...interface{}) {
|
|
ll.info().Msgf(format, args...)
|
|
}
|
|
|
|
// Warn emits the preformatted message if the logger is at or below LogLevelWarn.
|
|
func (ll *DefaultLeveledLogger) Warn(msg string) {
|
|
ll.warn().Msgf(msg)
|
|
}
|
|
|
|
// Warnf formats and emits a message if the logger is at or below LogLevelWarn.
|
|
func (ll *DefaultLeveledLogger) Warnf(format string, args ...interface{}) {
|
|
ll.warn().Msgf(format, args...)
|
|
}
|
|
|
|
// Error emits the preformatted message if the logger is at or below LogLevelError.
|
|
func (ll *DefaultLeveledLogger) Error(msg string) {
|
|
ll.err().Msgf(msg)
|
|
}
|
|
|
|
// Errorf formats and emits a message if the logger is at or below LogLevelError.
|
|
func (ll *DefaultLeveledLogger) Errorf(format string, args ...interface{}) {
|
|
ll.err().Msgf(format, args...)
|
|
}
|
|
|
|
// NewDefaultLeveledLoggerForScope returns a configured LeveledLogger.
|
|
func NewDefaultLeveledLoggerForScope(scope string, level LogLevel, writer io.Writer) *DefaultLeveledLogger {
|
|
if writer == nil {
|
|
writer = defaultOutput
|
|
}
|
|
zerologWriter := zerolog.New(writer).With().Timestamp().Str("scope", scope).Logger()
|
|
logger := &DefaultLeveledLogger{
|
|
writer: &zerologWriter,
|
|
level: level,
|
|
}
|
|
|
|
return logger.
|
|
WithTraceLogger(zerologWriter.Trace).
|
|
WithDebugLogger(zerologWriter.Debug).
|
|
WithInfoLogger(zerologWriter.Info).
|
|
WithWarnLogger(zerologWriter.Warn).
|
|
WithErrorLogger(zerologWriter.Error)
|
|
}
|
|
|
|
// 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 = defaultOutput
|
|
|
|
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" {
|
|
if factory.DefaultLogLevel < level {
|
|
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)
|
|
}
|