Golang Logging: A Step-by-step Guide

To create a log in Golang, you can use the built-in “log” library. The package log in Go implements the simple logging package that defines a type, Logger, with methods for formatting output.

You can use these rough-and-ready logs for local development in which you need to get fast feedback from your code may be more important than generating rich, structured logs.

To generate rich and structured logs, third-party packages will be more helpful.

Example

For example, you can define the division function that returns the error to the caller rather than exiting the program when you attempt to divide by zero.

package main

import (
  "errors"
  "fmt"
  "log"
)

func division(x float32, y float32) (float32, error) {
  if y == 0 {
    return 0, errors.New("can't divide by zero")
  }

  return x / y, nil
}

func main() {

  var x float32 = 11
  var y float32

  res, err := division(x, y)

  if err != nil {
    log.Print(err)
  }

  fmt.Println(res)
}

Output

2019/11/28 18:50:19 can't divide by zero 
0 

In the above program, we have imported three packages.

  1. errors
  2. fmt
  3. log

Then we have defined a function division(), which accepts two parameters. 

We are checking the dividing by 0 error; if it occurs, we log that error in the console.

If we meet the divide by 0 conditions, one error will be generated, and then we log that error in the console and print the return value.

In the above program, we got the divide by 0 conditions; that is why we got the output log.

The logger writes to standard error and prints the date and time of each logged message, which is helpful in general case scenarios.

How to store the logged messages in files in Go

In Go, you can store logged messages in files by configuring the logger from the log package to write to a file.

Example

package main

import (
  "errors"
  "fmt"
  "log"
  "os"
)

func division(x float32, y float32) (float32, error) {
  if y == 0 {
    return 0, errors.New("can't divide by zero")
  }

  return x / y, nil
}

func main() {
  var x float32 = 11
  var y float32

  res, exception := division(x, y)
  file, err := os.OpenFile("info.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)

  if err != nil {
    log.Fatal(err)
  }

  defer file.Close()

  log.SetOutput(file)
  log.Print(exception)
  fmt.Println(res)
}

Output

0 

Also, you will find the info.log created in your directory. Open the file, and you will see something like the following printed.

2019/11/28 19:29:33 can't divide by zero 

The os interface in Go is intended to be uniform across all operating systems. Therefore, features not generally available appear in the system-specific package syscall.

If the open fails on file, the error string will be self-explanatory.

What we are doing in the above code is creating one log file and printing our log message inside that file.

After printing the log message, we close the file, and that is it.

GitHub package logrus for formatted logs

The logrus is a package designed for structured logging that is well-suited for logging in JSON. The JSON format allows machines to parse your Golang logs quickly.

To use the package, first, you need to install it. Type the following command.
go get github.com/Sirupsen/logrus

Example

package main

import (
  log "github.com/sirupsen/logrus"
)

func main() {
  log.WithFields(log.Fields{
    "Best Song": "Sunflower",
  }).Info("One of the best song")
}

Output

Golang Log Example

Note that it’s utterly API-compatible with the stdlib logger so that you can replace your log imports everywhere with log github.com/sirupsen/logrus, and you’ll now have the flexibility of Logrus. You can customize it all you want.

That’s it.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.