给!这是不是你想要的 Golang 日志库? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
gratonos
V2EX    分享创造

给!这是不是你想要的 Golang 日志库?

  •  
  •   gratoos 2019-01-20 17:30:24 +08:00 5836 次点击
    这是一个创建于 2488 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一直以来我都没有找到一个称心如意的 Go 日志库,从个人角度看来,有的库功能太过单一,有的库接口使用起来不够顺手,有的库专注的点不在自己需要的点上。(好吧,以上都是自己造轮子的借口。)于是,我结合自己近几年的一些想法和实际需求实现了一个(希望)可以让人眼前一亮的 Go 日志库 gxlog。gxlog 只依赖于标准库,简洁易用、功能丰富、灵活可扩展是它的设计目标。

    很多人只需要一些常规日志功能,比如:日志分级,日志信息(时间、文件名、行号、消息等)格式化,日志输出到控制台或文件,日志文件按天保存到子目录,日志文件大小到上限时创建新文件等。

    一部分人可能有一些特殊需求,比如:日志格式化为 JSON 等其他格式,日志输出对接 syslog 等后端系统,出错时不仅打印日志还要产生告警事件等。

    gxlog 用比较恰当合理的方式同时满足了上述核心需求和扩展需求:对于核心需求用户,gxlog 使用简单方便;对于扩展需求用户,gxlog 能进行灵活定制和扩展。

    gxlog 采用了插槽式结构,并且对格式化和输出进行了分离。gxlog 内置 8 个槽,每个槽可放置一个 formatter 和一个 writer,也可闲置。另外,gxlog 整体和每个槽都有独立的 level 和 filter。这样,日志格式和输出方式就可以灵活搭配,比如:槽 1 放 text formatter 和 file writer,槽 2 放 json formatter 和 syslog writer,槽 3 放 text formatter 和 file writer,但是 level 设置为 Error,额外单独保存错误日志。

    另外,有需要的用户也可把 event 或 hook 集成进 gxlog,比如:实现一个自定义 formatter,用来发送事件通知,然后把自定义的 formatter 和一个 null writer 放到槽 4,可选地设置槽 4 的 level 或 filter,这样就能在输出日志的同时进行一些额外的操作。

    formatter 方面,gxlog 内置了:

    • text formatter:可进行非常灵活的定制,并提供日志染色功能
    • json formatter:可定制省略字段
    • formatter function wrapper:类似于 http.HandlerFunc

    writer 方面,gxlog 内置了:

    • tcp/unixdomain socket writer:主要目的在于支持使用 netcat 在本机实时查看日志,代替"tail -f",因为日志文件大小超限会创建新文件,用"tail -f"不方便
    • file writer:支持文件分片、按日存放、文件删除检测、压缩、加密
    • syslog writer:支持自定义 level 到 severity 的映射
    • writer function wrapper:类似于 http.HandlerFunc
    • io.Writer wrapper:适配标准库的 Writer 接口
    • async wrapper:适配所有 writer 到异步模式
    • multi-writer wrapper:如果多个 writer 都需要以相同的格式输出,那么可以复合成一个 writer,避免重复格式化

    另外,gxlog 还提供了一些“酷炫”功能:

    • 日志标记:被标记日志以特殊颜色显示,适合调试时加的临时日志,让眼睛更轻松
    • 日志前缀:在不支持转义序列染色的系统上可以用来代替日志标记,只是效果没有那么好
    • 日志上下文:产生一个日志对象,该对象打印的日志都会带上设置的上下文字段
    • 动态上下文:产生一个日志对象,该对象打印的日志都会带上设置的上下文字段的当前值。此功能很适合用于调试,可以经过设置,使得某对象的方法被调用时,所打印的日志都自动带上该对象的所有字段的当前值
    • 日志输出限制:
      • 按数量限制:限制当前文件当前行的日志每 N 条只打印 n 条
      • 按时间限制:限制当前文件当前行的日志每 N 秒最多打印 n 条

    最后,gxlog 还提供了一些方便使用的辅助方法:

    • 计时辅助方法:更方便记录一段代码执行花费的时间
    • 错误辅助方法:出错时打印错误日志的同时返回一个格式化的错误
    • 自动回溯:默认在出现 Fatal 错误时自动打印当前协程堆栈

    项目目前已经有了比较高的完成度,其中有详细的文档和使用示例。_examples 目录下的示例可以"go run"看效果。欢迎大家试用、提建议、做贡献。感觉项目合自己胃口的,请猛击 Star 。 项目地址: https://github.com/gxlog/gxlog

    后面预计会增加一些配套工具,如压缩加密的日志文件的解压解密、为之前未染色的日志增加染色。根据配置文件初始化日志实例的功能目前也在考虑。

    题外话:vim (通过插件)和 emacs (内置命令支持)都是可以解析转义序列表示的颜色的,有需要的不妨也为要写入文件的日志打开染色功能,让眼睛更轻松。

    几张跑示例的截图:

    basic

    auxiliary

    formatters

    5 条回复    2019-01-23 16:19:30 +08:00
    dabaibai
        1
    dabaibai  
       2019-01-21 19:59:47 +08:00
    马克一下
    Comdex
        2
    Comdex  
       2019-01-22 23:16:58 +08:00 via Android
    性能如何?
    gratonos
        3
    gratonos  
    OP
       2019-01-23 10:28:09 +08:00
    gratonos
        4
    gratonos  
    OP
       2019-01-23 10:28:42 +08:00
    简单测试,仅供参考

    硬件:小米 air13
    系统:Win10 上 VirtualBox 虚拟的 Linuxmint18
    Go:go1.11.4
    单条日志:消息负载 120 字节,上下文一对键值,无 mark,无 prefix,无染色,总长度 234 (算上换行)
    写入 /dev/null 性能( go run bench.go 2>/dev/null ):每秒 23-24 万条日志
    写入文件性能( go run bench.go 2> log.txt ):每秒 16-17 万条日志

    不获取运行时(文件、行号等),手动改了实现代码,新版本中会加入 Flag 控制:
    写入 /dev/null 性能:每秒 37-38 万条日志
    写入文件性能:每秒 24-25 万条日志

    参考测试代码:
    package main

    import (
    "mt"
    "time"

    "github.com/gxlog/gxlog"
    )

    func main() {
    msg := "012345678901234567890123456789012345678901234567890123456789" +
    "012345678901234567890123456789012345678901234567890123456789"
    log := gxlog.Logger().WithContext("k1", "v1")

    now := time.Now()
    for i := 0; i < 200000; i++ {
    log.Trace(msg)
    }
    fmt.Println("costs:", time.Since(now))
    }
    gratonos
        5
    gratonos  
    OP
       2019-01-23 16:19:30 +08:00
    补充一下标准库 log 的性能作为对比

    环境:同上
    Flags:LstdFlags | Llongfile | Lmicroseconds
    单条日志:消息负载 146 字节,总长度 234 (算上换行)
    调用:log.Println
    备注:gxlog 为了支持异步,每条日志都需要分配一个 buf,标准库 log 不支持异步,buf 为 log 对象的一个字段,无需重复分配。
    写入 /dev/null 性能:每秒 36-37 万条日志
    写入文件性能:每秒 24-25 万条日志
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1307 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 17:11 PVG 01:11 LAX 09:11 JFK 12:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86