In this article, we will cover Golang logging, highlighting how you can collect and measure logs (manually, and using Middleware) and cover some Golang logging best practices.

As a developer that codes with Golang to benefit from its speed, flexibility, and CSP-style concurrency, you would still not fully leverage Go’s capabilities without Golang logging

Logging helps you understand your software’s condition. Furthermore, logging allows you to track the step-by-step execution of your application, thereby easing debugging.

Asides from error tracking, logging also helps you record notable events in your application for future decision-making, especially during deployment and upgrading. 

This article discusses Golang Logging, highlighting how you can collect and measure logs vis-a-vis the Golang logging best practices.

What is Golang logging?

Golang logging is the process of recording information about the execution of an application. Golang is built with a logging package called `log,` which developers can use to record critical events and messages during the execution of their Golang applications.

The ‘log’ provides a simple interface to create and manage logs and specify the importance of each log message and the destination of the log output. Although the log outputs to the standard error (STDERR) by default, you can customize the destination of your logs. Logging is integral to Golang application performance monitoring.

How does Golang logging work?

Logging in Golang uses Golang’s in-built library package or a third-party logging tool. Both provide basic logging facilities that you can use to print messages based on different severity levels to the console or a file.

Logs content CTA

Start logging your Golang application under a minute.

There are five printing functions—Print(), Printf(), PrintIn(), Fatal(), and Fatalf(), and four severity levels—INFO, WARN, ERROR, and FATAL.

The `Print` functions write log messages with a severity of `INFO,` while the `Fatal` functions write messages with a severity of `FATAL.` Accordingly, a developer can execute the “Printf” or the “Fatalf” functions to format log messages with variables and other data. The “PrintIn” function logs a message followed by a newline character to the console or standard output. 

In addition, the log package also provides several other features that enable the customization of logging exercises. With these features, you can configure the prefix to be displayed with each log message, the output location, and the formatting of the log message. For example, you can add timestamps to each log entry and customize the output to meet their needs.

To use the logging package, you must first create a logged object with the function:

log.New(). 

This function produces the output destination of the log messages and the prefix that will be added.

For example, to create a logger that writes to standard output (STDOUT) with the prefix INFO, you can run this function:


logger := log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime)

You can then use the logger to write log messages using the Print, Printf, and Println functions. Consider this PrintIn log message:


logger.Println("This is an info message.")

It will produce this output:


INFO:2023/02/17 14:30:15 This is an info message.

Golang’s log package provides many other features. Check the Golang documentation for more information.

How to Collect Golang Logs

Whether you are using the log package or a third-party package, here is a step-by-step process to collect logs in Golang using the standard “log” package:

Step 1: Import the log package:


import "log"

Step 2: Create an output destination for your logs: 


logfile, err  := os.Create("app.log")

if err != nil { log.Fatal(err) }
defer logfile.Close() log. SetOutput(logfile)

This creates a new file called app.log and sets it as the output destination for logs. The “defer” statement ensures that the file is closed after the logs are written.

Step 3: Write logs:


log.Println("Starting the application...")

This code writes a log message to the file specified in step 2. The “Println” function adds a new line character at the end of the message.

Step 4: Use different levels of severity:


log.Println("Info message")
log.Println("Debug message: %s", debugInfo)
log.Println("Fatal error message")

The log package provides different severity levels for logs, such as Debug, Info, Warning, and Error. 

Step 5: Format logs:


log.Println("Request from %s for %s", req.RemoteAddr, req.URL.Path)

The “Printf” function allows you to format logs with variables, similar to the standard.fmt.Printf function.

Step 6: Set log flags:


log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Llongfile)

This sets the log flags to include the date, time, microseconds, and the full file path. You can also customize the flags. 

Step 7: Handle panics:


deferfunc() {
if := recover(); err != nil {
     log.Println("Panic:", err)
}
}()

If a panic occurs in the application, the `defer` function writes a log with the error message. 

By implementing the steps above, you should be able to collect logs in your Golang application using the standard “log” package.

If a panic occurs in the application, the `defer` function writes a log with the error message. 

By implementing the steps above, you should be able to collect logs in your Golang application using the standard “log” package.

How to measure Golang logs

Measuring Golang logs analyzes the log collection output to gain insights into its performance and behavior. After collecting your Golang logs, you can use the data to identify errors, optimize performance, and track usage metrics.

How to measure Golang logs

Follow these steps to measure your logs: 

1. Determine the type of logs you need to measure

The first step is to decide what information you intend to capture in your logs. You can capture performance metrics like request and response times, error rates, and memory usage. The information can also be more application-specific, like user actions or API calls.

2. Decide on a logging package

While you can use the built-in log package, third-party logging packages offer more comprehensive options and opportunities for customization.

3. Set up logging levels

This allows you to restrict the information to specific resources. Depending on your needs, you can use these levels to generate more or less detailed logs.

4. Add custom metrics

If you need to capture more specific performance metrics, you can add custom metrics to your logs using a package like Golang’s built-in expvar package or a third-party package like Middleware.

5. Choose a log analysis tool

Analysis tools help you aggregate, search, and analyze your logs. Many log analysis tools are available, such as Middleware, Splunk, Loggly, and many other tools that you can use to aggregate and analyze logs, generate reports and dashboards, and visualize metrics.

6. Set up log shipping

This enables you to send your logs to your chosen analysis tool. It involves configuring your logging package to write logs to a file or stream and then sending that file or stream to your log analysis tool.

7. Analyze your logs

After capturing your logs and sending them to your analysis tool, look for patterns and trends in the data, and use that information to optimize your application.

8. Set up alerts

You can also set up alerts based on specific events or metrics in your logs. For example, you might set up an alert to notify you if the error rate in your logs exceeds a certain threshold.

Golang logging best practices

Well-executed logging makes identifying and resolving issues easier, improving performance, and gaining insights into your application. Follow these best practices for well-executed Golang logging:

1. Use a logging framework

While Golang provides a built-in “log” package, the package has limited functionality. Consider using a third-party logging framework that is more feature-rich for more control over log output.

2. Use structured logging

Structured logging is a technique where log messages are formatted into machine-readable formats such as JSON. This makes it easier to search and analyze logs and extract valuable information. It is beneficial when dealing with large volumes of logs.

3. Log at the right level

Use the appropriate log level based on the severity of the event being logged. Streamlining your log to the appropriate level prevents overloading logs with too much or too little information.

4. Use contextual information

Contextual information makes logs more traceable, informative, and valuable. They are helpful during troubleshooting issues and debugging problems. This information includes timestamps, request IDs, user IDs, and other relevant data.

5. Limit log output

Avoid logging sensitive information and limit the amount of data output to reduce the risk of information leakage or performance degradation. Security teams often stumble upon sensitive information in log files when carrying out recovery tasks. Malicious insiders can readily exploit this information.

6. Store logs centrally

Collect logs from all your application instances in a centralized location to make searching and analyzing log data easier. A log management platform like Middleware is your best bet to ensure this. 

7. Regularly review logs

Regular review of logs enables you to identify patterns, spot errors, optimize application performance, and prevent security risks.

Conclusion

Golang logging involves the collection and measurement of logs and aids the optimization of Golang applications. With its flexibility and high performance, Golang programming provides developers with an efficient logging package to facilitate logging activities.

Start logging in for free with Middleware

This enables them to capture critical information in real-time and monitor the behavior of their application. Since third-party logging solutions are more robust, customizable, and provide more extensive visibility into your Golang logs, they are your best bet for effective Golang logging.

However, not all third-party logging solutions provide requisite control over your logs or ratify the tooling-based best practices highlighted above. While some do not provide intelligent feedback on your logs, others do not provide a central location to store your logs. 

Middleware satisfies all these conditions—log filtering and analysis, dashboard customization, seamless integration with existing infrastructure, and many other features that dignify it as your safest option for well-executed Golang logging. Start logging in for free today!