Commit f8937c53 authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Update log rotation settings.

parent 6a024821
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
- Separate configuration for maximum number of concurrent join requests to authoritative matches.
- New runtime function to kick users from a group.
- Clients sending data to an invalid match ID will now receive an uncollated error.
- Optional log file rotation.

### Changed
- Rename stream 'descriptor' field to 'subcontext' to avoid protocol naming conflict.
+12 −12
Original line number Diff line number Diff line
@@ -304,15 +304,15 @@ func (c *config) GetLeaderboard() *LeaderboardConfig {

// LoggerConfig is configuration relevant to logging levels and output.
type LoggerConfig struct {
	Level      string `yaml:"level" json:"level" usage:"Log level to set. Valid values are 'debug', 'info', 'warn', 'error'."`
	Stdout     bool   `yaml:"stdout" json:"stdout" usage:"Log to standard console output (as well as to a file if set)."`
	Level    string `yaml:"level" json:"level" usage:"Log level to set. Valid values are 'debug', 'info', 'warn', 'error'. Default 'info'."`
	Stdout   bool   `yaml:"stdout" json:"stdout" usage:"Log to standard console output (as well as to a file if set). Default true."`
	File     string `yaml:"file" json:"file" usage:"Log output to a file (as well as stdout if set). Make sure that the directory and the file is writable."`
	Rotating   bool   `yaml:"rotating" json:"rotating" usage:"Rotate log files. Default is false."`
	// reference: https://godoc.org/gopkg.in/natefinch/lumberjack.v2
	MaxSize    int    `yaml:"maxsize" json:"maxsize" usage:"The maximum size in megabytes of the log file before it gets rotated. It defaults to 100 megabytes."`
	MaxAge     int    ` yaml:"maxage" json:"maxage" usage:"The maximum number of days to retain old log files based on the timestamp encoded in their filename. The default is not to remove old log files based on age."`
	MaxBackups int    `yaml:"maxbackups" json:"maxbackups" usage:"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.)"`
	LocalTime  bool   `yaml:"localtime" json:"localtime" usage:"This determines if the time used for formatting the timestamps in backup files is the computer's local time.  The default is to use UTC time."`
	Rotation bool   `yaml:"rotation" json:"rotation" usage:"Rotate log files. Default is false."`
	// Reference: https://godoc.org/gopkg.in/natefinch/lumberjack.v2
	MaxSize    int  `yaml:"max_size" json:"max_size" usage:"The maximum size in megabytes of the log file before it gets rotated. It defaults to 100 megabytes."`
	MaxAge     int  `yaml:"max_age" json:"max_age" usage:"The maximum number of days to retain old log files based on the timestamp encoded in their filename. The default is not to remove old log files based on age."`
	MaxBackups int  `yaml:"max_backups" json:"max_backups" usage:"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.)"`
	LocalTime  bool `yaml:"local_time" json:"local_time" usage:"This determines if the time used for formatting the timestamps in backup files is the computer's local time. The default is to use UTC time."`
	Compress   bool `yaml:"compress" json:"compress" usage:"This determines if the rotated log files should be compressed using gzip."`
}

@@ -322,8 +322,8 @@ func NewLoggerConfig() *LoggerConfig {
		Level:      "info",
		Stdout:     true,
		File:       "",
		Rotating:   false,
		MaxSize:    0,
		Rotation:   false,
		MaxSize:    100,
		MaxAge:     0,
		MaxBackups: 0,
		LocalTime:  false,
+32 −37
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ func SetupLogging(tmpLogger *zap.Logger, config Config) (*zap.Logger, *zap.Logge

	consoleLogger := NewJSONLogger(os.Stdout, zapLevel)
	var fileLogger *zap.Logger
	if config.GetLogger().Rotating {
	if config.GetLogger().Rotation {
		fileLogger = NewRotatingJSONFileLogger(consoleLogger, config, zapLevel)
	} else {
		fileLogger = NewJSONFileLogger(consoleLogger, config.GetLogger().File, zapLevel)
@@ -62,12 +62,12 @@ func SetupLogging(tmpLogger *zap.Logger, config Config) (*zap.Logger, *zap.Logge
	return consoleLogger, consoleLogger
}

func NewJSONFileLogger(consoleLogger *zap.Logger, fpath string, level zapcore.Level) *zap.Logger {
	if len(fpath) == 0 {
func NewJSONFileLogger(consoleLogger *zap.Logger, fileName string, level zapcore.Level) *zap.Logger {
	if len(fileName) == 0 {
		return nil
	}

	output, err := os.OpenFile(fpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
	output, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		consoleLogger.Fatal("Could not create log file", zap.Error(err))
		return nil
@@ -76,6 +76,33 @@ func NewJSONFileLogger(consoleLogger *zap.Logger, fpath string, level zapcore.Le
	return NewJSONLogger(output, level)
}

func NewRotatingJSONFileLogger(consoleLogger *zap.Logger, config Config, level zapcore.Level) *zap.Logger {
	fileName := config.GetLogger().File
	if len(fileName) == 0 {
		consoleLogger.Fatal("Rotating log file is enabled but log file name is empty")
		return nil
	}
	if err := os.MkdirAll(fileName, 0755); err != nil {
		consoleLogger.Fatal("Could not create log directory", zap.Error(err))
		return nil
	}

	jsonEncoder := newJSONEncoder()

	// lumberjack.Logger is already safe for concurrent use, so we don't need to lock it.
	writeSyncer := zapcore.AddSync(&lumberjack.Logger{
		Filename:   fileName,
		MaxSize:    config.GetLogger().MaxSize,
		MaxAge:     config.GetLogger().MaxAge,
		MaxBackups: config.GetLogger().MaxBackups,
		LocalTime:  config.GetLogger().LocalTime,
		Compress:   config.GetLogger().Compress,
	})
	core := zapcore.NewCore(jsonEncoder, writeSyncer, level)
	options := []zap.Option{zap.AddStacktrace(zap.ErrorLevel)}
	return zap.New(core, options...)
}

func NewMultiLogger(loggers ...*zap.Logger) *zap.Logger {
	cores := make([]zapcore.Core, 0, len(loggers))
	for _, logger := range loggers {
@@ -95,6 +122,7 @@ func NewJSONLogger(output *os.File, level zapcore.Level) *zap.Logger {
	return zap.New(core, options...)
}

// Create a new JSON log encoder with the correct settings.
func newJSONEncoder() zapcore.Encoder {
	return zapcore.NewJSONEncoder(zapcore.EncoderConfig{
		TimeKey:        "ts",
@@ -109,36 +137,3 @@ func newJSONEncoder() zapcore.Encoder {
		EncodeCaller:   zapcore.ShortCallerEncoder,
	})
}

func NewRotatingJSONFileLogger(consoleLogger *zap.Logger, config Config, level zapcore.Level) *zap.Logger {
	fpath := config.GetLogger().File
	if len(fpath) == 0 {
		consoleLogger.Fatal("Rotating log file is enabled. But log file name is empty.")
		return nil
	}

	output, err := os.OpenFile(fpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		consoleLogger.Fatal("Could not create log file", zap.Error(err))
		return nil
	}
	output.Close()

	jsonEncoder := newJSONEncoder()
	// lumberjack.Logger is already safe for concurrent use, so we don't need to lock it.
	w := zapcore.AddSync(&lumberjack.Logger{
		Filename:   fpath,
		MaxSize:    config.GetLogger().MaxSize,
		MaxAge:     config.GetLogger().MaxAge,
		MaxBackups: config.GetLogger().MaxBackups,
		LocalTime:  config.GetLogger().LocalTime,
		Compress:   config.GetLogger().Compress,
	})
	core := zapcore.NewCore(
		jsonEncoder,
		w,
		level,
	)
	options := []zap.Option{zap.AddStacktrace(zap.ErrorLevel)}
	return zap.New(core, options...)
}