slog performance
yangdong-d opened this issue · comments
我在参照示例写了个slog输出到文件的demo,测试性能的时候发现和benchmark的表现相差很大
即便我放在同一个项目同一台机器上,slog的性能也远不如log4go(项目想替换掉的旧日志库)
是我的使用方法不对吗,求教
demo:
func slogDemo() {
type Obj struct {
a int
b int64
c string
d bool
}
str1 := "str1"
str2 := "str222222222222"
int1 := 1
int2 := 2
h1, err := handler.NewEmptyConfig().With(
handler.WithLogfile("./info.log"), //路径
handler.WithRotateTime(handler.EveryHour), //日志分割间隔
handler.WithLogLevels(slog.AllLevels), //日志level
handler.WithBuffSize(4 * 1024 * 1024), //buffer大小
handler.WithCompress(true), //是否压缩旧日志 zip
handler.WithBackupNum(24 * 3), //保留旧日志数量
handler.WithBuffMode(handler.BuffModeBite),
//handler.WithRenameFunc(), //RenameFunc build filename for rotate file
).CreateHandler()
if err != nil {
fmt.Printf("Create slog handler err: %#v", err)
return
}
f := slog.AsTextFormatter(h1.Formatter())
myTplt := "[{{datetime}}] [{{level}}] [{{caller}}] {{message}}\n"
f.SetTemplate(myTplt)
logs := slog.NewWithHandlers(h1)
start = time.Now().UnixNano()
for n := count;n > 0; n-- {
logs.Infof("message is %d %d %s %s %#v", int1, int2, str1, str2, obj)
}
end = time.Now().UnixNano()
fmt.Printf("\n slog total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
logs.MustFlush()
}
result:
slog total cost 784599471 ns
avg cost 7845 ns
count 100000
补充些更多的测试结果
zap sugar no format
total cost 213044652 ns
avg cost 2130 ns
count 100000
zap sugar format
total cost 397701153 ns
avg cost 3977 ns
count 100000
zap no format
total cost 215259103 ns
avg cost 2152 ns
count 100000
zap format
total cost 430643119 ns
avg cost 4306 ns
count 100000
slog no format
total cost 500610606 ns
avg cost 5006 ns
count 100000
slog format
total cost 771954584 ns
avg cost 7719 ns
count 100000
log4go no format
total cost 225615627 ns
avg cost 2256 ns
count 100000
log4go format
total cost 452465265 ns
avg cost 4524 ns
count 100000
:) 跟zap、zerolog 这类的日志库比较肯定会差很多,它使用的手动指定类型来使用日志 例如 zap.String(),zap.Int()
。使用上稍微有点麻烦,但是数据处理性能更好,扩展性也差了一点。
slog 使用的go fmt.SprintX 方法格式化各种类型数据(跟 logrus 类似),属于使用简单但是性能要差一些。
看你使用场景,配合 buffer 作为项目应用上的日志库 slog 或者 logrus 性能远远够用了;真实应用的性能瓶颈更多的是在 (file,net) io 上, 格式化数据这点损耗基本上可以忽略。
slog 在易于使用和性能的上,更偏向于使用方便(使用方便,易于扩展,内置好各种日志文件处理)。
额理解,但是zap sugar也是print风格下测的。
可以给下测试代码我本地测试一下 😄
可以给下测试代码我本地测试一下 😄
我是这么测的,log4go我们包装过的,不方便剥离出dome来,就没放代码里
type Obj struct {
a int
b int64
c string
d bool
}
str1 := "str1"
str2 := "str222222222222"
int1 := 1
int2 := 2
func testZapSugar() {
w := zapcore.AddSync(&lumberjack.Logger{
Filename: "./foosugar.log",
MaxSize: 500, // megabytes
MaxBackups: 3,
MaxAge: 28, // days
})
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
w,
zap.InfoLevel,
)
logger := zap.New(core)
sugar := logger.Sugar()
sugar.Info("message is msg")
count := 100000
start := time.Now().UnixNano()
for n := count;n > 0;n-- {
sugar.Info("message is msg")
}
end := time.Now().UnixNano()
fmt.Printf("\n zap sugar no format\n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
start = time.Now().UnixNano()
for n := count;n > 0;n-- {
sugar.Infof("message is %d %d %s %s %#v", int1, int2, str1, str2, obj)
}
end = time.Now().UnixNano()
fmt.Printf("\n zap sugar format\n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
sugar.Sync()
}
func testZap() {
w := zapcore.AddSync(&lumberjack.Logger{
Filename: "./foo.log",
MaxSize: 500, // megabytes
MaxBackups: 3,
MaxAge: 28, // days
})
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
w,
zap.InfoLevel,
)
logger := zap.New(core)
count := 100000
start := time.Now().UnixNano()
for n := count;n > 0;n-- {
logger.Info("message is msg")
}
end := time.Now().UnixNano()
fmt.Printf("\n zap no format\n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
start = time.Now().UnixNano()
for n := count;n > 0;n-- {
logger.Info("failed to fetch URL",
// Structured context as strongly typed Field values.
zap.Int("int1", int1),
zap.Int("int2", int2),
zap.String("str", str1),
zap.String("str2", str2),
zap.Any("backoff", obj),
)
}
end = time.Now().UnixNano()
fmt.Printf("\n zap format\n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
logger.Sync()
}
func testSlog() {
h1, err := handler.NewEmptyConfig().With(
handler.WithLogfile("./info.log"), //路径
handler.WithRotateTime(handler.EveryHour), //日志分割间隔
handler.WithLogLevels(slog.AllLevels), //日志level
handler.WithBuffSize(4 * 1024 * 1024), //buffer大小
handler.WithCompress(true), //是否压缩旧日志 zip
handler.WithBackupNum(24 * 3), //保留旧日志数量
handler.WithBuffMode(handler.BuffModeBite),
//handler.WithRenameFunc(), //RenameFunc build filename for rotate file
).CreateHandler()
if err != nil {
fmt.Printf("Create slog handler err: %#v", err)
return
}
f := slog.AsTextFormatter(h1.Formatter())
myTplt := "[{{datetime}}] [{{level}}] [{{caller}}] {{message}}\n"
f.SetTemplate(myTplt)
logs := slog.NewWithHandlers(h1)
count := 100000
start := time.Now().UnixNano()
for i := 0;i < count;i++ {
logs.Info("message is msg")
}
end := time.Now().UnixNano()
fmt.Printf("\n slog no format \n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
start = time.Now().UnixNano()
for n := count;n > 0; n-- {
logs.Infof("message is %d %d %s %s %#v", int1, int2, str1, str2, obj)
}
end = time.Now().UnixNano()
fmt.Printf("\n slog format \n total cost %d ns\n avg cost %d ns \n count %d \n", end - start, (end - start)/int64(count), count)
logs.MustFlush()
}
我用你的测试代码跑的。可以拉下slog 的最新版 v0.5.1
再试试。
=== RUN TestZapSugar
zap sugar no format
total cost 883854000 ns
avg cost 8838 ns
count 100000
zap sugar format
total cost 1058184000 ns
avg cost 10581 ns
count 100000
--- PASS: TestZapSugar (1.94s)
=== RUN TestZapLog
zap no format
total cost 793171000 ns
avg cost 7931 ns
count 100000
zap format
total cost 1070121000 ns
avg cost 10701 ns
count 100000
--- PASS: TestZapLog (1.86s)
=== RUN TestSlog
slog no format
total cost 486753000 ns
avg cost 4867 ns
count 100000
slog format
total cost 794033000 ns
avg cost 7940 ns
count 100000
--- PASS: TestSlog (1.28s)
PASS