V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
hjweddie
V2EX  ›  分享创造

写了个轻量级 logging lib, 在高并发下比 logrus, seelog 等常用的库效率更佳

  •  
  •   hjweddie ·
    hjweddie · 2016-03-06 21:50:43 +08:00 · 8187 次点击
    这是一个创建于 3190 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在工作中负责开发 qps 较高的中间件过程中,发现原来使用的 seelog 中每次函数调用均会调用 runtime.Caller 及 runtime.FuncForPC 这两个极为耗时的操作(单 goroutine 下,每次需要 0.1~0.2ms),这意味着调用 n 次 seelog 的日志函数后,耗时将增加 n * (0.1~0.2)ms. 换用了 logrus 后情况有所缓解,而且也挺好用的(JSON 格式输出)。但是 logrus 不支持配置文件,这一点上没有 seelog 可以通过 xml 文件配置来的优雅。此时在想,有没两者优点合二为一的呢?

    另外,在 fmt 包格式化字符串的探索中,发现将格式化字符串和输出过程融合,而不等整个字符串格式化完再输出(一边格式化,一边输出),这样的效率会提高 20%左右,在亲测在 100 goroutines 的情况下提高更为可观。由此便有了这个库的初步构想。最后增加了 buf.io, timeCache, format const, bytes.buffer 等各种技巧的使用,使得日志输出效率极大的提高。最终用到线上环境中,运行稳定,中间件的处理能力也得到了满意的提升。

    期待感兴趣的大大们的建议~

    项目地址:
    https://github.com/YoungPioneers/blog4go

    Introduction

    BLog4go is an efficient logging library written in the Go programming language, providing logging hook, log rotate, filtering and formatting log message.

    BLog4go 是高性能日志库。创新地使用“边解析边输出”方法进行日志输出,同时支持回调函数、日志淘汰和配置文件。可以解决高并发,调用日志函数频繁的情境下,日志库造成的性能问题。

    Build Status
    Coverage Status
    GoDoc

    Features

    • Partially write to the bufio.Writer as soon as posible while formatting message to improve performance
    • Support different logging output file for different logging level
    • Support configure with files in xml format
    • Configurable logrotate strategy
    • Call user defined hook in asynchronous mode for every logging action
    • Adjustable message formatting
    • Configurable logging behavier when looging on the fly without restarting
    • Suit configuration to the environment when logging start
    • Try best to get every done in background
    • File writer can be configured according to given config file
    • Different output writers
      • Console writer
      • File writer
      • Socket writer

    Benchmark

    I do some benchmark on a HDD disk comparing amoung fmt,blog4go,seelog,logrus. Benchmark Code

    BenchmarkBlog4goSingleGoroutine-4                    1000000          1087 ns/op
    BenchmarkBlog4goMultiGoroutine-4                       30000         56569 ns/op
    BenchmarkFmtFormatSingleGoroutine-4                   300000          5104 ns/op
    BenchmarkFmtFormatWithTimecacheSingleGoroutine-4      300000          4256 ns/op
    BenchmarkFmtFormatWithTimecacheMultiGoroutine-4         3000        509579 ns/op
    BenchmarkLogrusSingleGoroutine-4                      100000         13757 ns/op
    BenchmarkLogrusWithTimecacheSingleGoroutine-4         100000         12752 ns/op
    BenchmarkLogrusWithTimecacheMultiGoroutine-4            1000       2049809 ns/op
    BenchmarkSeelogSingleGoroutine-4                       50000         32846 ns/op
    BenchmarkSeelogMultiGoroutine-4                         1000       3191334 ns/op
    

    It shows that blog4go can write log very fast, especially in situation with multi goroutines running at the same time~

    9 条回复    2016-07-17 21:59:25 +08:00
    zhengji
        1
    zhengji  
       2016-03-06 22:05:49 +08:00
    给作者赞一个
    zzn
        2
    zzn  
       2016-03-06 22:35:20 +08:00
    边解析边输出?什么鬼?
    hjweddie
        3
    hjweddie  
    OP
       2016-03-06 22:47:12 +08:00
    @zzn 就是格式化字符串的过程中,省略了字符串拼接的步骤,解析成功一部分就马上输出到对应的地方(bufio, console 等)
    Unknwon
        4
    Unknwon  
       2016-03-07 02:32:38 +08:00
    用 XML 配置表示有点蛋疼。。。
    hjweddie
        5
    hjweddie  
    OP
       2016-03-07 09:35:08 +08:00
    @Unknwon 嗯嗯,我本身也比较喜欢相对简洁的 yaml 。在编写代码的时候,持着尽量不依赖非官方库的原则,没有引用非官方的 yaml 的包。不知道可否介绍下 xml 外的实现方法呢? 另外我自己试过使用 json 格式的,配置文件写起来也觉得挺麻烦
    Unknwon
        6
    Unknwon  
       2016-03-07 14:38:15 +08:00
    @hjweddie 我看了一下你的示例配置。。我感觉用 INI 更简洁。。

    https://github.com/go-ini/ini 这个包还提供像 JSON, XML 那样直接映射到结构体的功能,你可以试试。(其实是个软广)
    hjweddie
        7
    hjweddie  
    OP
       2016-03-07 17:01:34 +08:00
    @Unknwon 谢谢你的建议,我会考虑下 ini,json,yaml 相关的配置方法
    kulle
        8
    kulle  
       2016-04-26 18:20:13 +08:00 via Android
    err := log.NewWriterFromConfigAsFile("blog4go_config.xml")
    defer log.Close()
    请问,如果我的程序用到 blog4go ,写一个全局变量存放这个 log ,是不是不需要关闭?
    hjweddie
        9
    hjweddie  
    OP
       2016-07-17 21:59:25 +08:00
    @kulle 需要调用 Close 方法来关闭的噢~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2829 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 03:56 · PVG 11:56 · LAX 19:56 · JFK 22:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.