Closed fufuok closed 3 years ago
示例, 1 秒可能有几万个错误. 但记录了 5 个.
21:41:55 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:56 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:56 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:56 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:56 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:56 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
21:41:57 WRN client.go:36 > Failed to write Tunnel E="timeout: rpc Client's send queue is full"
采样功能的确不是特别好做,每秒输出 N 个这个的确没有实现。在高并发时候,我一般是使用概率输出,就是输出 N% 的日志。所以我在这个库里面还暴露了 Fastrand 函数。
// 输出 5% 的日志
if log.Fastrand(100) < 5 {
log.Info().Msg("a sample log")
}
事实上对于高并发的日志,我会用一个专门的 Logger + FileWriter 去存它. 一个真实的例子如下
trafficLogger := log.Logger{Writer: &log.FileWriter{...}} // 大约如此
if log.Fastrand(100) < 5 {
trafficLogger .Log().Msg("a sample log")
}
对于支持每秒 N 个的这个需求,其实是每次都要调用一个 timer ,我觉得很难实现的高效,所以就没做。
这个需求其实之前也有建议,我都准备好了参考对象了,在这里 https://github.com/vitessio/vitess/blob/v2.1.1/go/ratelimiter/ratelimiter.go
但是一直没有下决心去做(因为可能最终是实现出来的结果不够简洁),我再琢磨琢磨。
youtube 这个版本的 ratelimit 是我所知的最高效的 ratelimiter 实现(因为它本质就是一个计数器)。但是还是对性能造成比较明显的影响,因为设计 time.Now() 和 mutex.Lock(),相比较 Fastrand 的方案,后者性能要好很多。
好的好的. 了解了. 谢谢. 新项目转到这个日志库. 我觉得挺棒~~
您好吖.
很喜欢干净整洁的库, 高性能无依赖是天花板. 功能也很全面.
不过, 看了一圈没发现上面的日志采样功能, 在一些高并发场景我们可能更希望1秒有几个日志即可. 或意外产生错误时很可能疯狂记录错误日志, 此时也希望仅采样错误来记录.
如果已有此功能或简单方案, 请贴下范例.
若无, 请问有计划吗?
我感觉这样就完全可以替代我心中理想的日志库了.
谢谢~~