ruleguard-logfatal: A ruleguard bundle for better log hygiene
ruleguard-logfatal is a ruleguard bundle that enforces the absence of logging at Fatal or Panic levels in a codebase.
It supports most well-known logging libraries with a Fatal and/or Panic level, including zap, logrus, zerolog, and the standard library's log package. If you're not using one of these libraries, it should still work just fine if your library has an API similar to any of the above; you can look at the custom logger interface in _example/examples.go as an example.
Motivation
Quite simply: it is better to propagate errors so they can be handled rather than crash an application.
Errors should be propagated and handled accordingly, rather than cause an application to crash; using Fatal makes it too easy to be haphazard about failure modes. It is especially important to be considerate of error handling in library; no one wants their application to crash because a dependency decided to call os.Exit(1)! Logging at Panic is slightly better due to recover, but suffers from the same problem: if you don't know it exists in your dependency, you won't know to use recover.
Usage
Installation
Install ruleguard-logfatal like you would any other ruleguard bundle:
- If you're not using
golangci-lint, then get ruleguard first
go get -u github.com/ennyjfrick/ruleguard-logfatal@latest
- Create a
rules.go with the following content somewhere in your project directory:
//go:build ruleguard
// +build ruleguard
package gorules
import (
"github.com/quasilyte/go-ruleguard/dsl"
logfatalrules "github.com/ennyjfrick/ruleguard-logfatal"
)
func init() {
dsl.ImportRules("logfatal", logfatalrules.Bundle)
}
- If you're using
ruleguard as a standalone tool, just point it at your new rules.go file:
$ ruleguard -rules /path/to/rules.go ./...
- Otherwise, if you're using
ruleguard through golangci-lint, add the following to your .golangci.yml:
linters:
enable:
- gocritic
linters-settings:
gocritic:
enabled-checks:
- ruleguard
settings:
ruleguard:
rules: "rules.go"
Customization
As a ruleguard bundle, ruleguard-logfatal uses the parent ruleguard configuration.
Disabling or Enabling Rule Groups
ruleguard-logfatal has the following two rule groups:
noFatal: checks for logging at the Fatal level
noPanic: checks for logging at the Panic level
To enable or disable a group, simply pass the prefix you set in the dsl.ImportRules call plus the group name to the appropriate ruleguard flags. For example, to disable noPanic:
# using ruleguard as a standalone tool
$ ruleguard -rules rules.go -disable logfatal/noPanic . # to disable the check for logging at `Panic`
# alternatively: ruleguard -rules rules.go -enable logfatal/noFatal .
# using ruleguard through golangci-lint
linters:
enable:
- gocritic
linters-settings:
gocritic:
enabled-checks:
- ruleguard
settings:
ruleguard:
rules: "rules.go"
disable: "logfatal/noPanic"
# alternatively
# enable: "logfatal/noError"
Contributing
Feel free to open an issue or create a pull request for any features/bugs/etc.
If you're creating a pull request, please include test cases when applicable.
TODO