Go:禁用log.Logger?

Mat*_*ner 38 logging flags go

我有一些使用该log程序包的密集检测代码.现在是关闭日志记录的时候了,我无法确定如何关闭标准记录器.

我错过了什么吗?我应该在进行日志调用之前检查一个标志,还是在生产中将它们注释掉?

小智 107

当io/ioutil包中存在io.Writer时,没有理由为公共io.Writer创建自己的类型.

import (
    "log"
    "io/ioutil"
)

func init() {
    log.SetOutput(ioutil.Discard)
}
Run Code Online (Sandbox Code Playgroud)

  • 由于这会跳过写入磁盘但仍然执行所有格式化,因此调用`log.SetFlags(0)`应该会稍微缓解一下,我认为 (3认同)
  • @Joril确实通过这个基准确认非零标志确实会导致性能损失(在Go 1.17中):https://gist.github.com/Deleplace/ad33f8c6a96e9938e83e4f9cbcc608e0 (3认同)

Avi*_*h R 30

对于完全禁用日志,实际上最好调用log.SetFlags(0)Joril并将输出设置为no-op io.Writer(即log.SetOutput(ioutil.Discard))

但即使在此之后,操作也会在500-600 ns/op 1左右闲置

这仍然可以剪短(左右为100 ns/OP通过使用自定义)Logger的实现,并实现所有功能进行任何操作-这表现在这里(只覆盖Println了bervity).

所有这些的替代方法是使用具有级别的自定义日志记录框架并将其设置为完成OFF.

但请注意,常用的日志记录库之一(logrus)具有性能影响 - 无论如何,它都可以在3K + ns/op执行的基准测试中找到.

偏见的意见:从基准,图书馆去,记录与定制比肩执行Logger实施时设置Level-1,无论后端和格式

(基准源可以在这里找到)

基准的输出如下:

testing: warning: no tests to run
PASS
BenchmarkGoLogging-4                                             1000000          2068 ns/op
BenchmarkGoLoggingNullBackend-4                                  5000000           308 ns/op
BenchmarkGoLoggingNullBackendWithFancyFormatter-4                3000000           435 ns/op
BenchmarkGoLoggingOffLevel-4                                    20000000           109 ns/op
BenchmarkGoLoggingNullBackendAndOffLevel-4                      20000000           108 ns/op
BenchmarkGoLoggingNullBackendWithFancyFormatterAndOffLevel-4    20000000           109 ns/op
BenchmarkLog15-4                                                  200000          7359 ns/op
BenchmarkLog15WithDiscardHandler-4                               2000000           922 ns/op
BenchmarkLog15WithDiscardHandlerAndOffLevel-4                    2000000           926 ns/op
BenchmarkLog15WithNopLogger-4                                   20000000           108 ns/op
BenchmarkLog15WithNopLoggerDiscardHandlerA-4                    20000000           112 ns/op
BenchmarkLog15WithNopLoggerAndDiscardHandlerAndOffLevel-4       20000000           112 ns/op
BenchmarkLog-4                                                   1000000          1217 ns/op
BenchmarkLogIoDiscardWriter-4                                    2000000           724 ns/op
BenchmarkLogIoDiscardWriterWithoutFlags-4                        3000000           543 ns/op
BenchmarkLogCustomNullWriter-4                                   2000000           731 ns/op
BenchmarkLogCustomNullWriterWithoutFlags-4                       3000000           549 ns/op
BenchmarkNopLogger-4                                            20000000           113 ns/op
BenchmarkNopLoggerWithoutFlags-4                                20000000           112 ns/op
BenchmarkLogrus-4                                                 300000          3832 ns/op
BenchmarkLogrusWithDiscardWriter-4                                500000          3032 ns/op
BenchmarkLogrusWithNullFormatter-4                                500000          3814 ns/op
BenchmarkLogrusWithPanicLevel-4                                   500000          3872 ns/op
BenchmarkLogrusWithDiscardWriterAndPanicLevel-4                   500000          3085 ns/op
BenchmarkLogrusWithDiscardWriterAndNullFormatterAndPanicLevel-4   500000          3064 ns/op
ok      log-benchmarks  51.378s
go test -bench .  62.17s user 3.90s system 126% cpu 52.065 total
Run Code Online (Sandbox Code Playgroud)

#1:YMMV,在i7-4500U CPU @ 1.80GHz上测试


Mos*_*afa 5

type NullWriter int
func (NullWriter) Write([]byte) (int, error) { return 0, nil }

// ...

log.SetOutput(new(NullWriter))
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好方法,因为它完成格式化输出的所有工作,只是为了销毁它.如果你想要你可以关闭的日志记录调用,最好通过避免调用log.Printf来阻止源上的流. (5认同)
  • 一般来说你是对的,但是`log`包[只是忽略](http://code.google.com/p/go/source/browse/src/pkg/log/log.go#153)`int`返回价值,所以我们最好不要浪费时间在生产代码中如此频繁的功能. (2认同)
  • 在Go中使用`log`是否有最佳实践?如果它们用于追踪目的,是否最终删除(或注释掉)大多数日志记录调用? (2认同)