Print In Production Code
ID |
go.print_in_production |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Best Practice |
Language |
Go |
Tags |
best-practice, leftover-debug, logging |
Description
Reports fmt.Print / fmt.Printf / fmt.Println and the builtin print / println
calls left in production code. These write directly to standard output/error and bypass the
application’s structured logging pipeline.
Rationale
fmt.Print* and the builtins print / println are diagnostic helpers. Output sent
through them cannot be filtered by log level, lacks the usual metadata (timestamp, severity,
request context), and is often an unbuffered debug leftover. In a deployed service this clutters
the console and may be silently dropped by the container runtime.
// Bad
func load() {
fmt.Println("loaded")
print("debug")
}
// Good
func load(logger *slog.Logger) {
logger.Info("loaded")
}
Exceptions
Member-style calls on a caller-supplied sink (w.Write(…), logger.Info(…)) are never
flagged. Test files (*_test.go) are skipped. The main package — and any package listed in
exemptPackages, such as cmd/… command entry points — are not reported, since writing to
the console there is legitimate.
Remediation
Route output through a logger — the standard-library log/slog, or the application’s existing
logging facade — so messages carry level and context and flow through one pipeline.