How to disable a log.Logger

LoggingGoFlags

Logging Problem Overview


I have some heavily instrumented code that makes use of the log package. Now it's come time to turn off the logging, and I can't determine how to turn off the standard logger.

Have I missed something? Should I be checking a flag before making log calls, or commenting them out in production?

Logging Solutions


Solution 1 - Logging

No reason to create your own type for a common io.Writer when one exists in the io/ioutil package.

import (
    "log"
    "io/ioutil"
)

func init() {
    log.SetOutput(ioutil.Discard)
}

Solution 2 - Logging

For completely disabling logs, it's actually better to call log.SetFlags(0)[Joril][1] and set the output to a no-op io.Writer (i.e., log.SetOutput(ioutil.Discard))

But even after this, the operations will idle around [500-600 ns/op][2a]1

This can still be cut short (to around 100 ns/op) by using a custom Logger implementation, and implementing all the functions to be no-op -- as demonstrated [here][2b] (only overriding Println for bervity).

The alternative to all these is to use a custom logging framework with levels and set it to complete OFF.

Note though, one of the commonly used library for logging ([logrus][3]) has [performance implications][4] -- the same can be found in the [benchmarks][6] where it perform with 3K+ ns/op, regardless.

Biased opinion: from the benchmarks, the library [go-logging][5] performs in par with the custom Logger implementation when setting the Level to -1, regardless of the backend and formatting

(the benchmark source can be found [here][6])

the output of the benchmark is as follows:

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

#1: YMMV, tested on i7-4500U CPU @ 1.80GHz [1]:https://stackoverflow.com/questions/10571182/go-disable-a-log-logger#comment43485550_10688098 [2a]:https://gist.github.com/Avinash-Bhat/48c4f06b0cc840d9fd6c#file-log_test-go "YMMV, tested on i7-4500U CPU @ 1.80GHz" [2b]:https://gist.github.com/Avinash-Bhat/48c4f06b0cc840d9fd6c#file-log_test-go "benchmark for package log" [3]:https://github.com/Sirupsen/logrus [4]:https://github.com/Sirupsen/logrus/issues/125 "Issue #125" [5]:https://github.com/op/go-logging [6]:https://gist.github.com/Avinash-Bhat/48c4f06b0cc840d9fd6c "Gist"

Solution 3 - Logging

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

// ...

log.SetOutput(new(NullWriter))

Solution 4 - Logging

This approach allows you to turn logging on and off at runtime:

type LogWriter struct{
    enabled bool
}

func (l *LogWriter) Enable() {
    l.enabled = true
}

func (l *LogWriter) Disable() {
    l.enabled = false
}

func (l *LogWriter) Write([]byte) (int, error) {
    if l.enabled {
        //...
    }
    return 0, nil
}

And this approach enables or disables logging for the entire runtime:

type LogWriter struct{}

func (l *LogWriter) Write([]byte) (int, error) {
    if some.Constant {
        //...
    }
    return 0, nil
}

Where some.Constant would be either a constant that you set before compiling (producing a "production" binary) or a variable that is set only once when running the program via command-line flags (something like myprogram --enable-logging=true)

With both approaches you can leave your current code almost entirely untouched.

Solution 5 - Logging

Since SetOutput() is only defined for the global logger, a custom writer is still handy for other loggers. A short way of writing one is like this:

type LogWriter struct{ io.Writer }
func (w *LogWriter) Enable()  { w.Writer = os.Stdout }
func (w *LogWriter) Disable() { w.Writer = ioutil.Discard }

Solution 6 - Logging

A note for others coming here looking for this and other logging facilities: have a look at the log4go package as that covers turning off logging, setting log levels, log rotation, redirection to a file etc which might be useful.

See the doc at http://godoc.org/code.google.com/p/log4go

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatt JoinerView Question on Stackoverflow
Solution 1 - LoggingJeff WendlingView Answer on Stackoverflow
Solution 2 - LoggingAvinash RView Answer on Stackoverflow
Solution 3 - LoggingMostafaView Answer on Stackoverflow
Solution 4 - LoggingthwdView Answer on Stackoverflow
Solution 5 - LoggingTJMView Answer on Stackoverflow
Solution 6 - LoggingKenny GrantView Answer on Stackoverflow