-
-
Save toefel18/7f0b82127a4576d3a7d7b13d013b0f8b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package log | |
import ( | |
"go.uber.org/zap" | |
"go.uber.org/zap/zapcore" | |
"gopkg.in/natefinch/lumberjack.v2" | |
"os" | |
"path" | |
) | |
// Configuration for logging | |
type Config struct { | |
// EncodeLogsAsJson makes the log framework log JSON | |
EncodeLogsAsJson bool | |
// FileLoggingEnabled makes the framework log to a file | |
// the fields below can be skipped if this value is false! | |
FileLoggingEnabled bool | |
// Directory to log to to when filelogging is enabled | |
Directory string | |
// Filename is the name of the logfile which will be placed inside the directory | |
Filename string | |
// MaxSize the max size in MB of the logfile before it's rolled | |
MaxSize int | |
// MaxBackups the max number of rolled files to keep | |
MaxBackups int | |
// MaxAge the max age in days to keep a logfile | |
MaxAge int | |
} | |
// How to log, by example: | |
// logger.Info("Importing new file, zap.String("source", filename), zap.Int("size", 1024)) | |
// To log a stacktrace: | |
// logger.Error("It went wrong, zap.Stack()) | |
// DefaultZapLogger is the default logger instance that should be used to log | |
// It's assigned a default value here for tests (which do not call log.Configure()) | |
var DefaultZapLogger = newZapLogger(false, os.Stdout) | |
// Debug Log a message at the debug level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Debug(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Debug(msg, fields...) | |
} | |
// Info log a message at the info level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Info(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Info(msg, fields...) | |
} | |
// Warn log a message at the warn level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Warn(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Warn(msg, fields...) | |
} | |
// Error Log a message at the error level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Error(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Error(msg, fields...) | |
} | |
// Panic Log a message at the Panic level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Panic(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Panic(msg, fields...) | |
} | |
// Fatal Log a message at the fatal level. Messages include any context that's | |
// accumulated on the logger, as well as any fields added at the log site. | |
// | |
// Use zap.String(key, value), zap.Int(key, value) to log fields. These fields | |
// will be marshalled as JSON in the logfile and key value pairs in the console! | |
func Fatal(msg string, fields ...zapcore.Field) { | |
DefaultZapLogger.Fatal(msg, fields...) | |
} | |
// AtLevel logs the message at a specific log level | |
func AtLevel(level zapcore.Level, msg string, fields ...zapcore.Field) { | |
switch level { | |
case zapcore.DebugLevel: | |
Debug(msg, fields...) | |
case zapcore.PanicLevel: | |
Panic(msg, fields...) | |
case zapcore.ErrorLevel: | |
Error(msg, fields...) | |
case zapcore.WarnLevel: | |
Warn(msg, fields...) | |
case zapcore.InfoLevel: | |
Info(msg, fields...) | |
case zapcore.FatalLevel: | |
Fatal(msg, fields...) | |
default: | |
Warn("Logging at unkown level", zap.Any("level", level)) | |
Warn(msg, fields...) | |
} | |
} | |
// Configure sets up the logging framework | |
// | |
// In production, the container logs will be collected and file logging should be disabled. However, | |
// during development it's nicer to see logs as text and optionally write to a file when debugging | |
// problems in the containerized pipeline | |
// | |
// The output log file will be located at /var/log/auth-service/auth-service.log and | |
// will be rolled when it reaches 20MB with a maximum of 1 backup. | |
func Configure(config Config) { | |
writers := []zapcore.WriteSyncer{os.Stdout} | |
if config.FileLoggingEnabled { | |
writers = append(writers, newRollingFile(config)) | |
} | |
DefaultZapLogger = newZapLogger(config.EncodeLogsAsJson, zapcore.NewMultiWriteSyncer(writers...)) | |
zap.RedirectStdLog(DefaultZapLogger) | |
Info("logging configured", | |
zap.Bool("fileLogging", config.FileLoggingEnabled), | |
zap.Bool("jsonLogOutput", config.EncodeLogsAsJson), | |
zap.String("logDirectory", config.Directory), | |
zap.String("fileName", config.Filename), | |
zap.Int("maxSizeMB", config.MaxSize), | |
zap.Int("maxBackups", config.MaxBackups), | |
zap.Int("maxAgeInDays", config.MaxAge)) | |
} | |
func newRollingFile(config Config) zapcore.WriteSyncer { | |
if err := os.MkdirAll(config.Directory, 0); err != nil { | |
Error("failed create log directory", zap.Error(err), zap.String("path", config.Directory)) | |
return nil | |
} | |
return zapcore.AddSync(&lumberjack.Logger{ | |
Filename: path.Join(config.Directory, config.Filename), | |
MaxSize: config.MaxSize, //megabytes | |
MaxAge: config.MaxAge, //days | |
MaxBackups: config.MaxBackups, //files | |
}) | |
} | |
func newZapLogger(encodeAsJSON bool, output zapcore.WriteSyncer) *zap.Logger { | |
encCfg := zapcore.EncoderConfig{ | |
TimeKey: "@timestamp", | |
LevelKey: "level", | |
NameKey: "logger", | |
CallerKey: "caller", | |
MessageKey: "msg", | |
StacktraceKey: "stacktrace", | |
EncodeLevel: zapcore.LowercaseLevelEncoder, | |
EncodeTime: zapcore.ISO8601TimeEncoder, | |
EncodeDuration: zapcore.NanosDurationEncoder, | |
} | |
encoder := zapcore.NewConsoleEncoder(encCfg) | |
if encodeAsJSON { | |
encoder = zapcore.NewJSONEncoder(encCfg) | |
} | |
return zap.New(zapcore.NewCore(encoder, output, zap.NewAtomicLevel())) | |
} |
works well . Execllent job.
bug: Cannot print the caller field...
if the permission is set to o744 it would be much better else we cannot enter the directory and access the file as usual as expected
os.MkdirAll(config.Directory, 0744)
how to print the caller field?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
workable now?