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
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.
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
type NullWriter int
func (NullWriter) Write([]byte) (int, error) { return 0, nil }
// ...
log.SetOutput(new(NullWriter))
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)
}
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 }
For completely disabling logs, it's actually better to call log.SetFlags(0)
Joril 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/op1
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 (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) has performance implications -- the same can be found in the benchmarks where it perform with 3K+ ns/op, regardless.
Biased opinion: from the benchmarks, the library go-logging 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)
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