Should I use fmt.Println() or log.Println() in my CLI app in Go ?
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.Writerimplementations. - Concurrency:
fmtfunctions 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,Fprintfor 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
logpackage 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/slogoffers 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) andlog.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 π
| feature | fmt | log |
|---|---|---|
| purpose | general-purpose formatted IO | application logging |
| concurrency | not inherently concurrent-safe | concurrent-safe |
| metadata | no automatic metadata (timestamps, .. etc.) | can automatically add timestamps and other contect. |
| output | default to stdout | defaults to stderr , configurable to any io.Writer |
| error handling | basic printing | Fatal 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 thatlog.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. Likefmt.Println(), it prints to stdout by default, but you can configure it to print to stderr or another destination if needed. Usinglog.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 .