Open ilya1st opened 6 years ago
The compression and log cleanup is done in a different goroutine than logging. The main goroutine only blocks long enough to pass a boolean to the channel the compressor sits in. The only way this could block on the compression is if you manage to run past your max log size in the new file before the old file is finished compressing.
Yes, it may run in different gorotine but it uses same mutex as Logger.Write() use. That's why every gorotine which run Logger.Write() while rotate running will wait for Mutex.Unlock() call. So you can stop program execution during log rotation process. Here https://github.com/ilya1st/rotatewriter I've written implementation of rotation which lock/unlok Write() mutex only to replace new opened file. But without gzip and other things.
Hello,I am learning to use lumberjack and zap. However I met a question.When log file's size is over 2M(as code shown),it makes error and can't write log now: 2019-01-26 14:13:11.7670684 +0800 AWST m=+0.500000001 write error: can't rename log file: rename ./test.log test-2019-01-26T14-13-11.767.log: The process cannot access the file because it is being used by another process. The code data is shown: `var Logger zap.Logger // logpath 日志文件路径 // loglevel 日志级别 func initLogger(logpath string, loglevel string) zap.Logger { hook := lumberjack.Logger{ Filename: logpath, // 日志文件路径 MaxSize: 2, // megabytes MaxAge: 7, // days MaxBackups: 30, // 最多保留300个备份 Compress: true, // 是否压缩 disabled by default LocalTime: true, }
w := zapcore.AddSync(&hook)
// 设置日志级别,debug可以打印出info,debug,warn;info级别可以打印warn,info;warn只能打印warn
// debug->info->warn->error
var level zapcore.Level
switch loglevel {
case "debug":
level = zap.DebugLevel
case "info":
level = zap.InfoLevel
case "error":
level = zap.ErrorLevel
default:
level = zap.InfoLevel
}
encoderConfig := zap.NewProductionEncoderConfig()
// 时间格式
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(encoderConfig),
w,
level,
)
logger := zap.New(core)
logger.Info("DefaultLogger init success")
return logger
}
/日志模块的初始化/
func init() {
// 历史记录日志名字为:all-2018-11-15T07-45-51.763.log,服务重新启动,日志会追加,不会删除
Logger = initLogger("./test.log", "debug")
for i := 0; i < 24080; i++ {
Logger.Info("[RTCAudioService][SDK-ROOM][RoomId:10010][Uuid:123456]",zap.String("msg", callDelSessionFromMap del room success
))
Logger.Info(fmt.Sprint("[test log] ", i), zap.Int("line", 47))
//Logger.Info(fmt.Sprint("[Info log] ", i), zap.String("level", {"a":"4","b":"5"}
))
//Logger.Warn(fmt.Sprint("[Info log] ", i), zap.String("level", {"a":"7","b":"8"}
))
}
}` Can you help me figure out the reason that the error occurs?
@motaoyaoyao Please file a new issue.
So while you rename, gzip, reopen files logger Write blocks and wait while operation ends. This is not right way.
Right way is do that in the following order:
In this case you make Write to wait while switch file to new. And you need add another mutex to logger to guarantee that Logger.Rotate() operations running only once a time.