首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

Golang 有没有什么方法能解决高并发时, log 的输出问题?

  •  
  •   zwpaper · 2017-06-16 21:35:15 +08:00 · 1319 次点击
    这是一个创建于 709 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在写程序,自己调试的时候没什么问题,真正用的时候发现日志特别乱,才发现并发的时候,日志都打一起去了,虽然也是行输出的,但是就不好找运行的流程了。

    所以在想,能不能有什么办法,在并发的时候,能区分一下不同 goroutine 的日志

    第一个想到打 goroutine ID,但是这个被 Google 否决了,并不能拿到这个 ID。 尴尬点的方法,自己生成一个 ID,也是一种方案,但是太不优雅了

    找日志库,好像也没人讨论出这方面比较好的库

    不知道在座各位有没有什么好一点的解决方案?

    19 回复  |  直到 2017-06-17 11:47:29 +08:00
        1
    wweir   2017-06-16 22:02:21 +08:00 via Android
    针对调用链(栈)区分上下文,把上下文作为 tag 打到日志里。

    context 包里加上全局唯一 ID 可以一定程度上解决分布式调用链追踪问题,不过这方法对你的问题而言,有点过重了
        2
    est   2017-06-16 22:17:24 +08:00
    再开一个 goroutine 专门把数组转换成日志并且定时 flush。
        3
    cxbig   2017-06-16 22:28:43 +08:00   ♥ 1
    现在比较流行 ELK 日志管理 https://www.elastic.co/
    找现成试用 有 https://logz.io/
        4
    zwpaper   2017-06-16 23:17:21 +08:00
    @wweir #1 针对调用链这个不太理解,现在就是在并发的时候,各个 goroutine 都有自己的调用链,打到一起就乱了😳

    确实是想找一个能稍微简单一点的方案
        5
    zwpaper   2017-06-16 23:18:30 +08:00
    @cxbig #3 ELK 就更重了,而且 ELK 首先也得在打印的时候能区分吧?
        6
    zwpaper   2017-06-16 23:19:10 +08:00
    @est #2 这个方案写着写着,应该就是一个 log 库了吧。。。
        7
    devops   2017-06-16 23:37:01 +08:00
    蛤蛤,这个问题我搞过,overhead 最小的办法是修改 runtime 库,加上这个函数。

    func GoID() int64 {
    return getg().goid
    }
        8
    zwpaper   2017-06-16 23:42:50 +08:00
    @devops #7 对了,这个也查到过,但是改人官方库,总感觉有点太 tricky 了。。。
        9
    cxbig   2017-06-16 23:43:51 +08:00
    @zwpaper ELK 可以方便的分析和归类日志
    至于区分的问题,每个进程生成一个随机 key 怎么就不优雅呢?
        10
    mingyun   2017-06-16 23:45:01 +08:00
    @cxbig nice
        11
    zwpaper   2017-06-17 00:05:07 +08:00
    @cxbig #9 目前看来就这个方法最简单了
        12
    zwpaper   2017-06-17 00:05:42 +08:00
    @cxbig #9 还想看看大家有没有一些不一样的思路
        13
    cxbig   2017-06-17 00:13:15 +08:00
    @zwpaper 你还可以直接用 stream 发出去,不写 FS。
    https://github.com/omc/dendrite

    并发量大的话可以用 Kafka 之类的中间件可以进一步稳定性能。
        14
    herozem   2017-06-17 01:40:15 +08:00 via iPhone
    在 nginx 上加一个 requestID ?然后 elk 再归一下类
        15
    wweir   2017-06-17 07:03:41 +08:00 via Android   ♥ 1
    @zwpaper 最简单轻量的两种做法,
    通常是在函数的参数中(或者方法的结构体中),加个 context 保存 tag,打日志的时候带上这个 tag。
    另一个更轻量省事,引入一个第三方 errors 包,报错一层一层手动加调用栈。遇到 goruntine 加上其 id 或者方便识别的随机字符串

    PS:扯 elk 大数据之流纯属扯淡,日志乱到人都分辨,工具更是没法分辨
        16
    callofmx   2017-06-17 10:13:27 +08:00   ♥ 2
    context 不就是干这个的么
        17
    mengzhuo   2017-06-17 10:37:57 +08:00 via iPhone   ♥ 1
    思路问题
    1. 加上日志等级
    2. 不要输出没必要的调试日志
    3. UT 保证程序的正确性,而不是肉眼看日志
        18
    zwpaper   2017-06-17 10:41:57 +08:00 via iPhone
    @mengzhuo
    1. 等级有,但是并不能解决并发日志问题
    2. 同一
    3. 单测做的再好,也无法避免有时候出错需要查日志吧?
        19
    reus   2017-06-17 11:47:29 +08:00
    一般只有 panic 日志,也就是,如果打出日志来,就说明需要我要干预
    不需要关心的都直接入库
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   852 人在线   最高记录 5043   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 23ms · UTC 18:56 · PVG 02:56 · LAX 11:56 · JFK 14:56
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1