|home| |posts| |projects| |cv| |bookmarks| |github|

Disable Logs in Go Programs

Why?

When deploying your program in production it may be a good idea to disable logging in order to increase the performance of your program.

How?

Initial version

Let's start from this code snippet:

package main

import (
	"log"
	"os"
)

func main() {
	logger := log.New(os.Stderr, "", log.LstdFlags)
	logger.Println("Hello, world!")
}

This code declares a new logger(which is exactly the same as the default logger) and then prints a log message.

If we run this program we get a log message like this one:

2021/01/01 19:28:48 Hello, world!

Version with disable option

Here's the code:

package main

import (
	"flag"
	"log"
	"os"
)

var disableLogs bool

func main() {
	flag.BoolVar(&disableLogs, "disable-logs", false, "disable logs")
	flag.Parse()

	var logger Logger
	if disableLogs {
		logger = &NopLogger{
			log.New(os.Stderr, "", 0),
		}
	} else {
		logger = log.New(os.Stderr, "", log.LstdFlags)
	}

	logger.Println("Hello, world!")
}

type NopLogger struct {
	*log.Logger
}

func (l *NopLogger) Println(v ...interface{}) {}

type Logger interface {
	Println(v ...interface{})
}

Now let's break it down:

Add flag

We want to be able to decide at runtime if logging is enabled or not.

For this we can use a flag which will tell us to disable or enable the logs.

var disableLogs bool
func main() {
    flag.BoolVar(&disableLogs, "disable-logs", false, "disable logs")
    flag.Parse()

    // same code as above
}
Add NopLogger

To disable logs we need to create a wrapper for a custom logger which will do nothing when a log method(in our example Println) is called.

type NopLogger struct {
	*log.Logger
}
func (l *NopLogger) Println(v ...interface{}) {}
Add Logger interface

We also need a interface which will be used to access the selected logger(Nop or real logger).

type Logger interface {
	Println(v ...interface{})
}
Select logger based on flag

Now all we have to do is to select the logger based on the --disable-logs flag.

var logger Logger
if disableLogs {
    logger = &NopLogger{
        log.New(os.Stderr, "", 0),
	}
} else {
	logger = log.New(os.Stderr, "", log.LstdFlags)
}
Finally

Now we can disable the logs by passing at runtime the --disable-logs flag.