summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2021-06-09 13:32:34 +0300
committerValery Piashchynski <[email protected]>2021-06-09 13:32:34 +0300
commit3ec3306730455b6c5c423d130ebc322757661487 (patch)
tree1acfe544effb563a06e133a13be1faac6b3fddbb /plugins
parenta723cedba199a1c50dca05630b53139ee456ace8 (diff)
- Add support for the file logger with log rotation and compression
Signed-off-by: Valery Piashchynski <[email protected]>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/logger/config.go92
-rw-r--r--plugins/logger/enums.go12
-rw-r--r--plugins/logger/zap_adapter.go2
3 files changed, 98 insertions, 8 deletions
diff --git a/plugins/logger/config.go b/plugins/logger/config.go
index d2236cac..6ef56661 100644
--- a/plugins/logger/config.go
+++ b/plugins/logger/config.go
@@ -1,10 +1,12 @@
package logger
import (
+ "os"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
+ "gopkg.in/natefinch/lumberjack.v2"
)
// ChannelConfig configures loggers per channel.
@@ -13,9 +15,57 @@ type ChannelConfig struct {
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 string `mapstructure:"mode"`
+ 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
@@ -38,17 +88,20 @@ type Config struct {
// 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 strings.ToLower(cfg.Mode) {
- case "off", "none":
+ switch Mode(strings.ToLower(string(cfg.Mode))) {
+ case off, none:
return zap.NewNop(), nil
- case "production":
+ case production:
zCfg = zap.NewProductionConfig()
- case "development":
+ case development:
zCfg = zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Development: true,
@@ -72,7 +125,7 @@ func (cfg *Config) BuildLogger() (*zap.Logger, error) {
OutputPaths: []string{"stderr"},
ErrorOutputPaths: []string{"stderr"},
}
- case "raw":
+ case raw:
zCfg = zap.Config{
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
Encoding: "console",
@@ -120,13 +173,38 @@ func (cfg *Config) BuildLogger() (*zap.Logger, error) {
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"
+ cfg.Mode = development
}
if cfg.Level == "" {
cfg.Level = "debug"
diff --git a/plugins/logger/enums.go b/plugins/logger/enums.go
new file mode 100644
index 00000000..803eace0
--- /dev/null
+++ b/plugins/logger/enums.go
@@ -0,0 +1,12 @@
+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/zap_adapter.go b/plugins/logger/zap_adapter.go
index 6d865519..fab59844 100644
--- a/plugins/logger/zap_adapter.go
+++ b/plugins/logger/zap_adapter.go
@@ -10,7 +10,7 @@ type ZapAdapter struct {
zl *zap.Logger
}
-// Create NewZapAdapter which uses general log interface
+// NewZapAdapter ... which uses general log interface
func NewZapAdapter(zapLogger *zap.Logger) *ZapAdapter {
return &ZapAdapter{
zl: zapLogger.WithOptions(zap.AddCallerSkip(1)),