Logging can be a life-saver when it comes to discovering bugs or faults in your Go (Golang) code. The three most popular ways to log errors in Golang are:
- Output the errors to the console
- Log the errors to a file
- Use a logging framework
This article will walk you through how to log errors using each method, when and why you’d want to use each, along with examples.
Basic Logging in Golang
Golang comes with an in-built standard log
package which provides basic error logging features. Though it doesn't provide any log levels like debug
, warning
, or error
, it still has many features to get started with basic logging.
Let’s look at an example to understand it better.
package main
import "log"
func main() {
log.Println("We are logging in Golang!")
}
When the above code is executed, the log
package prints the output to the standard error (stderr)
stream and automatically appends a timestamp to each log message.
2022/09/30 02:44:31 We are logging in Golang!
Logging to a File in Golang
Despite the fact that the log
package's default output is to the stderr
stream, it may be adjusted to write to any local file or to any other location that accepts the io.Writer
interface. You must either create a new file or open an existing one and set it up as the log's output path in order to save log messages in a file.
Example
package main
import (
"log"
"os"
)
func main() {
file, err := os.OpenFile("myLOG.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
log.Fatal(err)
}
log.SetOutput(file)
log.Println("We are logging in Golang!")
}
In the above code, we have created the file myLOG.txt
or opened it if it is already existing in the append and write-only mode. When the above code is executed, the following output is written to the myLOG.txt
file:
2022/09/30 03:02:51 We are logging in Golang!
Writing Custom Logs in Golang
The log.New()
method may be used to create custom loggers. Three arguments must be sent to a custom logger when using the log.New()
function:
out
- It specifies the place where the log data has to be written, for instance, a file path. It could be any interface that implements the io.Writer interface.prefix
- a string or text which has to be appended at the beginning of each log line.flag
- These are sets of constants which allow us to define logging properties.
Example: Writing Custom Logs
package main
import (
"log"
"os"
)
var (
WarningLog *log.Logger
InfoLog *log.Logger
ErrorLog *log.Logger
)
func init() {
file, err := os.OpenFile("myLOG.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
log.Fatal(err)
}
InfoLog = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
WarningLog = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
ErrorLog = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}
func main() {
InfoLog.Println("Opening the application...")
InfoLog.Println("Something has occurred...")
WarningLog.Println("WARNING!!!..")
ErrorLog.Println("Some error has occurred...")
}
With the help of the destination
file path
, prefix string
, and flags
provided in the code above, three logs have been generated. These loggers use the println()
method in the main function to write log entries to the file.
When the above code is executed we get the following output written into myLOG.txt
file.
INFO: 2022/09/30 03:20:51 main.go:26: Opening the application...
INFO: 2022/09/30 03:20:51 main.go:27: Something has occurred...
WARNING: 2022/09/30 03:20:51 main.go:28: WARNING!!!..
ERROR: 2022/09/30 03:20:51 main.go:29: Some error has occurred…
Logging Frameworks
When used for local development, the log
package is fantastic. However, logging frameworks are preferable when working on a larger scale. Two logging frameworks you should know about are Logrus and Rollbar.
Logrus
Logrus is completely API compatible with the log
package, supports color-coded formatting of your logs, and works well for structured JSON logging. It can be installed on your system using the command below.
go get "github.com/Sirupsen/logrus"
Example: Logrus
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(
log.Fields{
"field1": "foo",
"field2": "bar",
},
).Info("Log message here!!!")
}
When the above code is executed we get the following output:
{"field1":"bar","field2":"foo","level":"info","msg":"Log message here!!!","time":"2022-09-30T15:55:24+01:00"}
Rollbar
Rollbar is a real-time error reporting service for Go and other languages. It makes it easy to identify the root cause of bugs through stack traces, local variables, telemetry, suspect deploys, and other metadata. Errors are sent to Rollbar asynchronously in a background goroutine and in return you get instant and accurate alerts — grouped using machine learning to reduce noise.
Example: Rollbar
package main
import (
"github.com/rollbar/rollbar-go"
"time"
)
func main() {
rollbar.SetToken("MY_TOKEN")
rollbar.SetEnvironment("production") // defaults to "development"
rollbar.SetCodeVersion("v2") // optional Git hash/branch/tag (required for GitHub integration)
rollbar.SetServerHost("web.1") // optional override; defaults to hostname
rollbar.SetServerRoot("github.com/heroku/myproject") // path of project (required for GitHub integration and non-project stacktrace collapsing) - where repo is set up for the project, the server.root has to be "/"
rollbar.Info("Message body goes here")
rollbar.WrapAndWait(doSomething)
}
func doSomething() {
var timer *time.Timer = nil
timer.Reset(10) // this will panic
}
Errors are displayed on a real-time feed.
For each error, you can drill down to get request parameters, local variables, affected users and IP addresses, browsers and OSes, deployed code versions, and more.
The Rollbar Query Language (RQL) allows you to monitor, perform data analysis and build custom reports on your error data, using a familiar SQL-like language.
Conclusion
Error logging can be very helpful in analyzing the health of your application. The built-in Go logging package should only be used when working with small applications. Logging frameworks like Rollbar should be used for logging in large-scale applications.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Go errors easier than ever. Try it today!