All Posts programming Should I use fmt.Println() or log.Println() in my CLI app in Go ?

Should I use fmt.Println() or log.Println() in my CLI app in Go ?

Β· 669 words Β· 4 minute read

Choosing between fmt.Println() and log.Println() in your CLI application depends on your specific needs regarding output formatting, verbosity, and where the output goes (stdout vs stderr).

Choosing between fmt versus log package:

fmt package πŸ”—

  • Purpose: Primarily for general-purpose formatted I/O (input/output). It’s used for printing strings, variables, and other data to standard output (stdout) or other io.Writer implementations.
  • Concurrency: fmt functions are not inherently safe for concurrent writes from multiple goroutines. Concurrent writes can lead to interleaved or unexpected output.
  • Features: Provides functions like Printf, Println, Sprintf, Fprint for various formatting and output scenarios. It excels at flexible string formatting with format specifiers.
  • Use Cases: Displaying program results to the user, generating simple reports, or for quick debugging output during development.

log package πŸ”—

  • Purpose: Specifically designed for logging program events and information. It provides a more structured and robust way to manage application logs.
  • Concurrency: The log package is designed to be concurrently safe, ensuring that log messages from multiple goroutines are written atomically and without interleaving.
  • Features:
    • Automatically adds timestamps and other context (like file and line number if configured).
    • Supports different log levels (though the built-in log package is simpler; log/slog offers more structured logging).
    • Can be configured to write to different destinations (e.g., files, network, standard error) using log.SetOutput.
    • Includes functions for critical events like log.Fatal (prints and exits) and log.Panic (prints and panics).
  • Use Cases: Recording application events, errors, warnings, and debugging information, especially in production environments where structured and reliable logging is crucial for monitoring and troubleshooting.

Key differences πŸ”—

featurefmtlog
purposegeneral-purpose formatted IOapplication logging
concurrencynot inherently concurrent-safeconcurrent-safe
metadatano automatic metadata (timestamps, .. etc.)can automatically add timestamps and other contect.
outputdefault to stdoutdefaults to stderr , configurable to any io.Writer
error handlingbasic printingFatal and Panic functions for critical events

Conclusion πŸ”—

Use fmt for displaying direct program output or for simple, non-critical debugging messages during development. Use log for all application logging, especially in production, where concurrency safety, structured information, and flexible output destinations are important. For more advanced structured logging, consider the log/slog package introduced in Go 1.21.

fmt.Println() vs fmt.Println() πŸ”—

  • fmt.Println() is part of the standard library and is suitable for general-purpose output. It prints to stdout by default, which is typically where you’d want your CLI application’s output to go. It’s straightforward to use and doesn’t require any setup beyond importing the fmt package. However, it lacks the structured logging capabilities that log.Println() offers.
  • log.Println(), on the other hand, is specifically designed for logging purposes. It prefixes each output with a timestamp and the name of the package, providing structured logging that can be very helpful for debugging and monitoring applications. Like fmt.Println(), it prints to stdout by default, but you can configure it to print to stderr or another destination if needed. Using log.Println() makes it easier to control the verbosity of your application through different log levels (e.g., debug, info, warn, error).

If your CLI application requires simple output for user interaction or debugging purposes, fmt.Println() is sufficient. However, if you’re developing an application where logging is crucial for understanding the flow of execution, especially in production environments, log.Println() is the better choice due to its structured logging capabilities and flexibility.

Here’s a quick comparison:

  • Use fmt.Println() for:

    • Simple output to stdout.
    • No need for structured logging or controlling verbosity.
  • Use log.Println() for:

    • Structured logging with timestamps and package names.
    • Controlling output verbosity through log levels.
    • Printing to destinations other than stdout if configured.

So, use fmt.Println() as the go to way of printing text on terminal. And use log.Println(), if your application needs the additional features provided by log.Println().

I hope you enjoyed reading this post as much as I enjoyed writing it. If you know a person who can benefit from this information, send them a link of this post. If you want to get notified about new posts, follow me on YouTube , Twitter (x) , LinkedIn , and GitHub .