douzong5057 2016-07-29 19:45
浏览 248
已采纳

如何在golang处理并发日志?

I've searched for it and only found here and here, but it not solves my problem.

How can I, using a standard way, identify the log separating the concurrent logs like JAVA does with thread ID? Because if I have a concurrent method then the logs will be printed mixed at the output, so I think that the LOGGER needs to have a way of identifying each request "thread"

Ex:

package main

import "log"

func main() {

    /* simulating 10000 users requests  */
    i := 1;
    for ;i < 10000; i++ {
        go getHello(i)
    }

}

func getHello(d int){
    log.Printf("m=getHello, i=%d,begin", d)
    log.Println("m=getHello, processing the hello message")
    log.Printf("m=getHello, i=%d, end", d)
}

output

2016/07/29 15:59:46 m=getHello, i=1017,begin
2016/07/29 15:59:46 m=getHello, processing the hello message
2016/07/29 15:59:46 m=getHello, i=1017, end
2016/07/29 15:59:46 m=getHello, processing the hello message
2016/07/29 15:59:46 m=getHello, i=1038, end
2016/07/29 15:59:46 m=getHello, i=311,begin
2016/07/29 15:59:46 m=getHello, processing the hello message
2016/07/29 15:59:46 m=getHello, i=311, end
2016/07/29 15:59:46 m=getHello, i=1023,begin
2016/07/29 15:59:46 m=getHello, processing the hello message
2016/07/29 15:59:46 m=getHello, i=1023, end
2016/07/29 15:59:46 m=getHello, i=991,begin
2016/07/29 15:59:46 m=getHello, processing the hello message
2016/07/29 15:59:46 m=getHello, i=991, end

As you can see if I have not a int flag is impossible to know what of the requests have logged. In java,c,c#,delphy for example I simple logs the thread id and everything is ok.

Can you help me to do something like that in Golang? Thanks.

Obs: If my question is not good please tell me why on comments

  • 写回答

3条回答 默认 最新

  • duanchai0028 2016-07-30 09:59
    关注

    There's no goroutine ID available from the runtime. Goroutines are used more liberally than threads in other languages, so the idea of which goroutine is handling a particular request or item may be less well-defined in a larger program.

    So somehow you need to pass through an ID yourself for logging. You could just pass through an int yourself, but the context module is handy for this: apart from allowing user-defined values, it can handle item cancellation and deadlines which are also likely to be useful to you.

    Here's a rough example of how it might be used. I've added a simple logging object that can be used as a context-aware logger. It logs the ID the context was created with. Probably this logger would go in its own package in a real program and support more of the log package's functions rather than just Printf and Println.

    package main
    
    import (
        "fmt"
        "log"
        "sync"
        "context"
    )
    
    type logger int
    const loggerID = "logger_id"
    
    func (l logger) Printf(s string, args ...interface{}) {
        log.Printf("[id=%d] %s", l, fmt.Sprintf(s, args...))
    }
    
    func (l logger) Println(s string) {
        log.Printf("[id=%d] %s
    ", l, s)
    }
    
    func ctxWithLoggerID(ctx context.Context, id int) context.Context {
        return context.WithValue(ctx, loggerID, id)
    }
    
    func getLogger(ctx context.Context) logger {
        return logger(ctx.Value(loggerID).(int))
    }
    
    func main() {
        ctx := context.Background()
        var wg sync.WaitGroup
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go hello(ctxWithLoggerID(ctx, i), &wg)
        }
        wg.Wait()
    }
    
    func hello(ctx context.Context, wg *sync.WaitGroup) {
        defer wg.Done()
        log := getLogger(ctx)
        log.Printf("hello begin")
        log.Println("hello, processing the hello message")
        log.Printf("hello, end")
    }
    

    It's incidental to your question, but I added a sync.WaitGroup to your program so that main will wait until all of the workers are finished before exiting. That allows the code to be tested with a smaller number of workers (10 rather than the original 10000).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 数学的三元一次方程求解
  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题