Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 戈朗'的间接费用;s记录器(如果设置为丢弃)_Go_Logging_Overhead - Fatal编程技术网

Go 戈朗'的间接费用;s记录器(如果设置为丢弃)

Go 戈朗'的间接费用;s记录器(如果设置为丢弃),go,logging,overhead,Go,Logging,Overhead,我有一个HTTP处理程序,它有40个记录器,设置为os.Stdout 这对我来说很好,因为我是目前唯一的测试者。 但是,当它投入生产时,恐怕会有太多的开销 当前记录器设置为os.Stdout和os.Stderr。 但一旦进入生产环境,os.Stdout将设置为ioutil.discard 问题1。如果仍将记录器设置为丢弃,会影响性能吗 问题2。对于最佳实践,是否最好从HTTP处理程序中完全删除记录器 ----更新--- package main import ( "time"

我有一个HTTP处理程序,它有40个记录器,设置为os.Stdout

这对我来说很好,因为我是目前唯一的测试者。 但是,当它投入生产时,恐怕会有太多的开销

当前记录器设置为os.Stdoutos.Stderr。 但一旦进入生产环境,os.Stdout将设置为ioutil.discard

问题1。如果仍将记录器设置为丢弃,会影响性能吗

问题2。对于最佳实践,是否最好从HTTP处理程序中完全删除记录器

----更新---

package main

import (
    "time"
    "fmt"
    "log"
    "io/ioutil"
    "io"
)

func testPrintf(w io.Writer, note string, cnt int) {
    l := log.New(w, "", 0)
    t1 := time.Now()
    for i:=0; i<cnt; i++ {
        l.Printf("%s - %d", "test", i)
    }
    t2 := time.Now()
    fmt.Printf("%-15s  %-15s, %v\n","Printf ", note, t2.Sub(t1))
}

func testPrintln(w io.Writer, note string, cnt int) {
    l := log.New(w, "", 0)
    t1 := time.Now()
    for i:=0; i<cnt; i++ {
        l.Println("test" + string(i))
    }
    t2 := time.Now()
    fmt.Printf("%-15s  %-15s, %v\n","Println", note, t2.Sub(t1))
}

func testDoNothing(w io.Writer, note string, cnt int) {
    //l := log.New(w, "", 0)
    t1 := time.Now()
    for i:=0; i<cnt; i++ {
        _ = "test" + string(i) // evaluated but didn't do any.
    }
    t2 := time.Now()
    fmt.Printf("%-15s  %-15s, %v\n", "DoNothing", note, t2.Sub(t1))
}

func main() {
    cnt := 10000000 // ten million
    testPrintf(ioutil.Discard, "discard.Attempt.1", cnt)
    testPrintln(ioutil.Discard, "discard.Attempt.1", cnt)
    testDoNothing(ioutil.Discard, "discard.Attempt.1", cnt)
    fmt.Println("\n")
    testPrintf(ioutil.Discard, "discard.Attempt.2", cnt)
    testPrintln(ioutil.Discard, "discard.Attempt.2", cnt)
    testDoNothing(ioutil.Discard, "discard.Attempt.2", cnt)
    fmt.Println("\n")
    testPrintf(ioutil.Discard, "discard.Attempt.3", cnt)
    testPrintln(ioutil.Discard, "discard.Attempt.3", cnt)
    testDoNothing(ioutil.Discard, "discard.Attempt.3", cnt)
}
Printf           discard.Attempt.1, 2.663697209s
Println          discard.Attempt.1, 2.4289759s
DoNothing        discard.Attempt.1, 190.480694ms

Printf           discard.Attempt.2, 2.493506245s
Println          discard.Attempt.2, 2.426081786s
DoNothing        discard.Attempt.2, 182.899574ms

Printf           discard.Attempt.3, 2.480853275s
Println          discard.Attempt.3, 2.481552836s
DoNothing        discard.Attempt.3, 180.916608ms
  • 我每次都跑了1000万次
  • 10米日志到io的时间为2~3秒。丢弃速度比我想象的要快。。我想我不必担心速度
  • 我不想使用的os.Stdout;(我最初关心的是用ioutil.Discard保存代码,而不是删除代码),但是由于os.Stdout没有缓冲,所以速度很慢
  • 顺便说一句,printf()比我想象的要快得多。几乎与println()相同
  • 我没有每天编写Go代码,所以这个测试可能不准确。如果你在测试中看到误导性的信息,请在这里留下评论,让其他人知道。谢谢。

    虽然我的直觉告诉我,将日志丢弃到
    会对代码产生最小的影响,但我建议设置一个基准测试来测试日志记录器的性能影响

    幸运的是,Go通过在单元测试中编写一个
    func BenchmarkXxxxx(*testing.B)
    函数并运行
    Go test-bench
    使这变得非常容易。可以找到更多信息。对于基准测试,我建议编写两个测试,一个使用
    os.Stdout
    ,另一个使用
    ioutil.Discard
    ——确保两个测试的输入相同

    显示“引擎盖下”将发生什么的相关代码:

    //ioutil.go
    类型devNull int
    func(devNull)写入(p[]字节)(int,错误){
    返回len(p),无
    }
    func(devNull)WriteString(s字符串)(int,error){
    返回len(s),无
    }
    
    日志记录最佳实践 日志记录的一种方法是常见的“基于级别的日志记录”,您可以选择希望记录的消息的严重性(
    DEBUG
    /
    INFO
    /
    WARN
    /
    ERROR
    等),然后选择在部署应用程序时显示的级别(例如,在开发过程中进行
    DEBUG
    及以上操作,但在生产过程中进行
    WARN
    及以上操作)

    正如您所注意到的,Go在标准库中只提供了
    Print
    Error
    级别的语句,因此您需要使用类似的语句(这些语句也有助于以更易于机器阅读/搜索的JSON格式构建日志)戴夫·切尼证明了这一决定背后的理由


    在您的情况下,40个日志语句听起来似乎很多,但这可能取决于有多少是简单的
    Print
    日志;处理程序的大小和复杂性等。
    Print
    日志记录作为开发中的临时措施非常有帮助,如果您没有将错误呈现给客户端。

    对于第一季度,您可以编写一个基准测试。然后您可以看到记录器的速度有多慢。对于第二季度,最好手动选择要记录的情况/错误,并且只记录这些情况/错误(如果有)如果你想知道性能影响,你需要在你的代码中测量它。评估日志参数支配你时间的可能性非常小。你可以在50纳秒/日志项下进行日志记录。例如,谢谢;我会简化并尝试;我会在这里更新结果,以防以后有人遇到同样的问题。。