diff options
author | Valery Piashchynski <[email protected]> | 2021-09-16 17:12:37 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-09-16 17:12:37 +0300 |
commit | f3491c089b4da77fd8d2bc942a88b6b8d117a8a5 (patch) | |
tree | 32bfffb1f24eeee7b909747cc00a6a6b9fd3ee83 /plugins/logger | |
parent | 5d2cd55ab522d4f1e65a833f91146444465a32ac (diff) |
Move plugins to a separate repository
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'plugins/logger')
-rw-r--r-- | plugins/logger/config.go | 212 | ||||
-rw-r--r-- | plugins/logger/encoder.go | 66 | ||||
-rw-r--r-- | plugins/logger/enums.go | 12 | ||||
-rw-r--r-- | plugins/logger/interface.go | 14 | ||||
-rw-r--r-- | plugins/logger/plugin.go | 86 | ||||
-rw-r--r-- | plugins/logger/std_log_adapter.go | 26 | ||||
-rw-r--r-- | plugins/logger/zap_adapter.go | 79 |
7 files changed, 0 insertions, 495 deletions
diff --git a/plugins/logger/config.go b/plugins/logger/config.go deleted file mode 100644 index 6ef56661..00000000 --- a/plugins/logger/config.go +++ /dev/null @@ -1,212 +0,0 @@ -package logger - -import ( - "os" - "strings" - - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - "gopkg.in/natefinch/lumberjack.v2" -) - -// ChannelConfig configures loggers per channel. -type ChannelConfig struct { - // Dedicated channels per logger. By default logger allocated via named logger. - Channels map[string]Config `mapstructure:"channels"` -} - -// FileLoggerConfig structure represents configuration for the file logger -type FileLoggerConfig struct { - // Filename is the file to write logs to. Backup log files will be retained - // in the same directory. It uses <processname>-lumberjack.log in - // os.TempDir() if empty. - LogOutput string `mapstructure:"log_output"` - - // MaxSize is the maximum size in megabytes of the log file before it gets - // rotated. It defaults to 100 megabytes. - MaxSize int `mapstructure:"max_size"` - - // MaxAge is the maximum number of days to retain old log files based on the - // timestamp encoded in their filename. Note that a day is defined as 24 - // hours and may not exactly correspond to calendar days due to daylight - // savings, leap seconds, etc. The default is not to remove old log files - // based on age. - MaxAge int `mapstructure:"max_age"` - - // MaxBackups is the maximum number of old log files to retain. The default - // is to retain all old log files (though MaxAge may still cause them to get - // deleted.) - MaxBackups int `mapstructure:"max_backups"` - - // Compress determines if the rotated log files should be compressed - // using gzip. The default is not to perform compression. - Compress bool `mapstructure:"compress"` -} - -func (fl *FileLoggerConfig) InitDefaults() *FileLoggerConfig { - if fl.LogOutput == "" { - fl.LogOutput = os.TempDir() - } - - if fl.MaxSize == 0 { - fl.MaxSize = 100 - } - - if fl.MaxAge == 0 { - fl.MaxAge = 24 - } - - if fl.MaxBackups == 0 { - fl.MaxBackups = 10 - } - - return fl -} - -type Config struct { - // Mode configures logger based on some default template (development, production, off). - Mode Mode `mapstructure:"mode"` - - // Level is the minimum enabled logging level. Note that this is a dynamic - // level, so calling ChannelConfig.Level.SetLevel will atomically change the log - // level of all loggers descended from this config. - Level string `mapstructure:"level"` - - // Encoding sets the logger's encoding. InitDefault values are "json" and - // "console", as well as any third-party encodings registered via - // RegisterEncoder. - Encoding string `mapstructure:"encoding"` - - // Output is a list of URLs or file paths to write logging output to. - // See Open for details. - Output []string `mapstructure:"output"` - - // ErrorOutput is a list of URLs to write internal logger errors to. - // The default is standard error. - // - // Note that this setting only affects internal errors; for sample code that - // sends error-level logs to a different location from info- and debug-level - // logs, see the package-level AdvancedConfiguration example. - ErrorOutput []string `mapstructure:"errorOutput"` - - // File logger options - FileLogger *FileLoggerConfig `mapstructure:"file_logger_options"` -} - -// BuildLogger converts config into Zap configuration. -func (cfg *Config) BuildLogger() (*zap.Logger, error) { - var zCfg zap.Config - switch Mode(strings.ToLower(string(cfg.Mode))) { - case off, none: - return zap.NewNop(), nil - case production: - zCfg = zap.NewProductionConfig() - case development: - zCfg = zap.Config{ - Level: zap.NewAtomicLevelAt(zap.DebugLevel), - Development: true, - Encoding: "console", - EncoderConfig: zapcore.EncoderConfig{ - // Keys can be anything except the empty string. - TimeKey: "T", - LevelKey: "L", - NameKey: "N", - CallerKey: "C", - FunctionKey: zapcore.OmitKey, - MessageKey: "M", - StacktraceKey: "S", - LineEnding: zapcore.DefaultLineEnding, - EncodeLevel: ColoredLevelEncoder, - EncodeTime: zapcore.ISO8601TimeEncoder, - EncodeDuration: zapcore.StringDurationEncoder, - EncodeCaller: zapcore.ShortCallerEncoder, - EncodeName: ColoredNameEncoder, - }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - } - case raw: - zCfg = zap.Config{ - Level: zap.NewAtomicLevelAt(zap.InfoLevel), - Encoding: "console", - EncoderConfig: zapcore.EncoderConfig{ - MessageKey: "message", - }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - } - default: - zCfg = zap.Config{ - Level: zap.NewAtomicLevelAt(zap.DebugLevel), - Encoding: "console", - EncoderConfig: zapcore.EncoderConfig{ - MessageKey: "message", - LevelKey: "level", - TimeKey: "time", - NameKey: "name", - EncodeName: ColoredHashedNameEncoder, - EncodeLevel: ColoredLevelEncoder, - EncodeTime: UTCTimeEncoder, - EncodeCaller: zapcore.ShortCallerEncoder, - }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - } - } - - if cfg.Level != "" { - level := zap.NewAtomicLevel() - if err := level.UnmarshalText([]byte(cfg.Level)); err == nil { - zCfg.Level = level - } - } - - if cfg.Encoding != "" { - zCfg.Encoding = cfg.Encoding - } - - if len(cfg.Output) != 0 { - zCfg.OutputPaths = cfg.Output - } - - if len(cfg.ErrorOutput) != 0 { - zCfg.ErrorOutputPaths = cfg.ErrorOutput - } - - // if we also have a file logger specified in the config - // init it - // otherwise - return standard config - if cfg.FileLogger != nil { - // init absent options - cfg.FileLogger.InitDefaults() - - w := zapcore.AddSync( - &lumberjack.Logger{ - Filename: cfg.FileLogger.LogOutput, - MaxSize: cfg.FileLogger.MaxSize, - MaxAge: cfg.FileLogger.MaxAge, - MaxBackups: cfg.FileLogger.MaxBackups, - Compress: cfg.FileLogger.Compress, - }, - ) - - core := zapcore.NewCore( - zapcore.NewJSONEncoder(zCfg.EncoderConfig), - w, - zCfg.Level, - ) - return zap.New(core), nil - } - - return zCfg.Build() -} - -// InitDefault Initialize default logger -func (cfg *Config) InitDefault() { - if cfg.Mode == "" { - cfg.Mode = development - } - if cfg.Level == "" { - cfg.Level = "debug" - } -} diff --git a/plugins/logger/encoder.go b/plugins/logger/encoder.go deleted file mode 100644 index 4ff583c4..00000000 --- a/plugins/logger/encoder.go +++ /dev/null @@ -1,66 +0,0 @@ -package logger - -import ( - "hash/fnv" - "strings" - "time" - - "github.com/fatih/color" - "go.uber.org/zap/zapcore" -) - -var colorMap = []func(string, ...interface{}) string{ - color.HiYellowString, - color.HiGreenString, - color.HiBlueString, - color.HiRedString, - color.HiCyanString, - color.HiMagentaString, -} - -// ColoredLevelEncoder colorizes log levels. -func ColoredLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) { - switch level { - case zapcore.DebugLevel: - enc.AppendString(color.HiWhiteString(level.CapitalString())) - case zapcore.InfoLevel: - enc.AppendString(color.HiCyanString(level.CapitalString())) - case zapcore.WarnLevel: - enc.AppendString(color.HiYellowString(level.CapitalString())) - case zapcore.ErrorLevel, zapcore.DPanicLevel: - enc.AppendString(color.HiRedString(level.CapitalString())) - case zapcore.PanicLevel, zapcore.FatalLevel: - enc.AppendString(color.HiMagentaString(level.CapitalString())) - } -} - -// ColoredNameEncoder colorizes service names. -func ColoredNameEncoder(s string, enc zapcore.PrimitiveArrayEncoder) { - if len(s) < 12 { - s += strings.Repeat(" ", 12-len(s)) - } - - enc.AppendString(color.HiGreenString(s)) -} - -// ColoredHashedNameEncoder colorizes service names and assigns different colors to different names. -func ColoredHashedNameEncoder(s string, enc zapcore.PrimitiveArrayEncoder) { - if len(s) < 12 { - s += strings.Repeat(" ", 12-len(s)) - } - - colorID := stringHash(s, len(colorMap)) - enc.AppendString(colorMap[colorID](s)) -} - -// UTCTimeEncoder encodes time into short UTC specific timestamp. -func UTCTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { - enc.AppendString(t.UTC().Format("2006/01/02 15:04:05")) -} - -// returns string hash -func stringHash(name string, base int) int { - h := fnv.New32a() - _, _ = h.Write([]byte(name)) - return int(h.Sum32()) % base -} diff --git a/plugins/logger/enums.go b/plugins/logger/enums.go deleted file mode 100644 index 803eace0..00000000 --- a/plugins/logger/enums.go +++ /dev/null @@ -1,12 +0,0 @@ -package logger - -// Mode represents available logger modes -type Mode string - -const ( - none Mode = "none" - off Mode = "off" - production Mode = "production" - development Mode = "development" - raw Mode = "raw" -) diff --git a/plugins/logger/interface.go b/plugins/logger/interface.go deleted file mode 100644 index 827f9821..00000000 --- a/plugins/logger/interface.go +++ /dev/null @@ -1,14 +0,0 @@ -package logger - -// Logger is an general RR log interface -type Logger interface { - Debug(msg string, keyvals ...interface{}) - Info(msg string, keyvals ...interface{}) - Warn(msg string, keyvals ...interface{}) - Error(msg string, keyvals ...interface{}) -} - -// WithLogger creates a child logger and adds structured context to it -type WithLogger interface { - With(keyvals ...interface{}) Logger -} diff --git a/plugins/logger/plugin.go b/plugins/logger/plugin.go deleted file mode 100644 index ffbf7f5e..00000000 --- a/plugins/logger/plugin.go +++ /dev/null @@ -1,86 +0,0 @@ -package logger - -import ( - endure "github.com/spiral/endure/pkg/container" - "github.com/spiral/errors" - "github.com/spiral/roadrunner/v2/plugins/config" - "go.uber.org/zap" -) - -// PluginName declares plugin name. -const PluginName = "logs" - -// ZapLogger manages zap logger. -type ZapLogger struct { - base *zap.Logger - cfg *Config - channels ChannelConfig -} - -// Init logger service. -func (z *ZapLogger) Init(cfg config.Configurer) error { - const op = errors.Op("config_plugin_init") - var err error - // if not configured, configure with default params - if !cfg.Has(PluginName) { - z.cfg = &Config{} - z.cfg.InitDefault() - - z.base, err = z.cfg.BuildLogger() - if err != nil { - return errors.E(op, errors.Disabled, err) - } - - return nil - } - - err = cfg.UnmarshalKey(PluginName, &z.cfg) - if err != nil { - return errors.E(op, errors.Disabled, err) - } - - err = cfg.UnmarshalKey(PluginName, &z.channels) - if err != nil { - return errors.E(op, errors.Disabled, err) - } - - z.base, err = z.cfg.BuildLogger() - if err != nil { - return errors.E(op, errors.Disabled, err) - } - return nil -} - -// NamedLogger returns logger dedicated to the specific channel. Similar to Named() but also reads the core params. -func (z *ZapLogger) NamedLogger(name string) (Logger, error) { - if cfg, ok := z.channels.Channels[name]; ok { - l, err := cfg.BuildLogger() - if err != nil { - return nil, err - } - return NewZapAdapter(l.Named(name)), nil - } - - return NewZapAdapter(z.base.Named(name)), nil -} - -// ServiceLogger returns logger dedicated to the specific channel. Similar to Named() but also reads the core params. -func (z *ZapLogger) ServiceLogger(n endure.Named) (Logger, error) { - return z.NamedLogger(n.Name()) -} - -// Provides declares factory methods. -func (z *ZapLogger) Provides() []interface{} { - return []interface{}{ - z.ServiceLogger, - } -} - -// Name returns user-friendly plugin name -func (z *ZapLogger) Name() string { - return PluginName -} - -// Available interface implementation -func (z *ZapLogger) Available() { -} diff --git a/plugins/logger/std_log_adapter.go b/plugins/logger/std_log_adapter.go deleted file mode 100644 index 479aa565..00000000 --- a/plugins/logger/std_log_adapter.go +++ /dev/null @@ -1,26 +0,0 @@ -package logger - -import ( - "github.com/spiral/roadrunner/v2/utils" -) - -// StdLogAdapter can be passed to the http.Server or any place which required standard logger to redirect output -// to the logger plugin -type StdLogAdapter struct { - log Logger -} - -// Write io.Writer interface implementation -func (s *StdLogAdapter) Write(p []byte) (n int, err error) { - s.log.Error("server internal error", "message", utils.AsString(p)) - return len(p), nil -} - -// NewStdAdapter constructs StdLogAdapter -func NewStdAdapter(log Logger) *StdLogAdapter { - logAdapter := &StdLogAdapter{ - log: log, - } - - return logAdapter -} diff --git a/plugins/logger/zap_adapter.go b/plugins/logger/zap_adapter.go deleted file mode 100644 index 1c68cf25..00000000 --- a/plugins/logger/zap_adapter.go +++ /dev/null @@ -1,79 +0,0 @@ -package logger - -import ( - "fmt" - - "go.uber.org/zap" - core "go.uber.org/zap/zapcore" -) - -type ZapAdapter struct { - zl *zap.Logger -} - -// NewZapAdapter ... which uses general log interface -func NewZapAdapter(zapLogger *zap.Logger) *ZapAdapter { - return &ZapAdapter{ - zl: zapLogger.WithOptions(zap.AddCallerSkip(1)), - } -} - -func separateFields(keyVals []interface{}) ([]zap.Field, []interface{}) { - var fields []zap.Field - var pairedKeyVals []interface{} - - for key := range keyVals { - switch value := keyVals[key].(type) { - case zap.Field: - fields = append(fields, value) - case core.ObjectMarshaler: - fields = append(fields, zap.Inline(value)) - default: - pairedKeyVals = append(pairedKeyVals, value) - } - } - return fields, pairedKeyVals -} - -func (log *ZapAdapter) fields(keyvals []interface{}) []zap.Field { - // separate any zap fields from other structs - zapFields, keyvals := separateFields(keyvals) - - // we should have even number of keys and values - if len(keyvals)%2 != 0 { - return []zap.Field{zap.Error(fmt.Errorf("odd number of keyvals pairs: %v", keyvals))} - } - - fields := make([]zap.Field, 0, len(keyvals)/2+len(zapFields)) - for i := 0; i < len(keyvals); i += 2 { - key, ok := keyvals[i].(string) - if !ok { - key = fmt.Sprintf("%v", keyvals[i]) - } - fields = append(fields, zap.Any(key, keyvals[i+1])) - } - // add all the fields - fields = append(fields, zapFields...) - - return fields -} - -func (log *ZapAdapter) Debug(msg string, keyvals ...interface{}) { - log.zl.Debug(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Info(msg string, keyvals ...interface{}) { - log.zl.Info(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Warn(msg string, keyvals ...interface{}) { - log.zl.Warn(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Error(msg string, keyvals ...interface{}) { - log.zl.Error(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) With(keyvals ...interface{}) Logger { - return NewZapAdapter(log.zl.With(log.fields(keyvals)...)) -} |