summaryrefslogtreecommitdiff
path: root/plugins/logger
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/logger')
-rw-r--r--plugins/logger/config.go212
-rw-r--r--plugins/logger/encoder.go66
-rw-r--r--plugins/logger/enums.go12
-rw-r--r--plugins/logger/interface.go14
-rw-r--r--plugins/logger/plugin.go86
-rw-r--r--plugins/logger/std_log_adapter.go26
-rw-r--r--plugins/logger/zap_adapter.go79
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)...))
-}