A Go linter that checks log messages for style and security issues.
Compatible with go vet and golangci-lint.
| Rule | Description | Example (bad → good) |
|---|---|---|
| lowercase | Log message must start with a lowercase letter | "Starting server" → "starting server" |
| english | Log message must be in English only | "Запуск сервера" → "starting server" |
| special-chars | No emoji, !, ?, or ... in log messages |
"started!🚀" → "started" |
| sensitive | No sensitive data keywords (password, token, etc.) | "user password: " + pwd → remove or mask |
log(standard library)log/slog(standard library, Go 1.21+)go.uber.org/zap(*zap.Logger,*zap.SugaredLogger)
go install github.com/idakhno/golangster/cmd/golangster@latest# Build
go build -o golangster ./cmd/golangster/
# Run on a package
go vet -vettool=./golangster ./...
# Run with specific rules disabled
go vet -vettool=./golangster -sensitive=false ./...Step 1. Build the plugin (requires CGO):
CGO_ENABLED=1 go build -buildmode=plugin -o golangster.so plugin/plugin.goStep 2. Configure .golangci.yml:
version: "2"
linters:
default: none
enable:
- golangster
linters-settings:
custom:
golangster:
path: ./golangster.so
description: Checks log messages for style and security issues
original-url: github.com/idakhno/golangster
settings:
rules:
lowercase: true
english_only: true
no_special_chars: true
no_sensitive: true
sensitive_keywords:
- password
- token
- secret
- api_keyNote: The plugin and
golangci-lintbinary must be built with the same Go version and dependency versions. Check with:go version -m $(which golangci-lint)
Step 3. Run:
golangci-lint run| Flag | Default | Description |
|---|---|---|
-lowercase |
true |
Check that messages start with lowercase |
-english |
true |
Check that messages are in English only |
-special-chars |
true |
Check for emoji and special characters |
-sensitive |
true |
Check for sensitive data keywords |
Settings are passed via .golangci.yml under linters-settings.custom.golangster.settings:
settings:
rules:
lowercase: true
english_only: true
no_special_chars: true
no_sensitive: true
sensitive_keywords:
- password
- token
- myCustomSecretimport "log/slog"
// BAD — triggers all 4 rules
slog.Info("Starting server!") // uppercase + special char
slog.Error("Ошибка подключения") // non-English
slog.Debug("api_key=" + apiKey) // sensitive data
slog.Warn("loading...") // ellipsis
// GOOD
slog.Info("starting server on port 8080")
slog.Error("connection failed")
slog.Debug("request processed")
slog.Warn("cache miss, fetching from db")# Run all tests
go test -race ./...
# Run only unit tests for rules
go test -v ./pkg/analyzer/rules/...
# Run integration tests (analysistest)
go test -v ./pkg/analyzer/...
# Build binary
go build -o golangster ./cmd/golangster/golangster/
├── cmd/golangster/ # Standalone binary (go vet -vettool)
├── pkg/analyzer/
│ ├── analyzer.go # Main analyzer (analysis.Analyzer)
│ ├── config.go # Configuration
│ ├── detector.go # Log call detection via AST + type checker
│ └── rules/
│ ├── lowercase.go # Rule 1: lowercase start + SuggestedFix
│ ├── english.go # Rule 2: English only
│ ├── special_chars.go # Rule 3: no emoji/special chars
│ └── sensitive.go # Rule 4: no sensitive data
├── plugin/plugin.go # golangci-lint plugin entry point
└── testdata/src/ # analysistest testdata with // want annotations
