Read this in other languages: Russian
logmsglint is a Go static analyzer for validating log messages in log/slog and go.uber.org/zap calls.
It helps keep log messages consistent before code review: lowercase style, English-only messages, no emoji or unexpected special characters, and configurable checks for sensitive data patterns.
The analyzer can be used as a standalone tool or integrated into golangci-lint through the custom module plugin system.
- Why
- What It Checks
- Supported Loggers
- Install
- Usage
- Configuration
- Examples
- Autofix
- CI
- Development
- License
Logs are part of the public interface of a backend service. They are used during debugging, incident response, monitoring, and support.
Without automated checks, log messages often become inconsistent over time:
- some start with uppercase letters, others with lowercase letters
- some use Russian or mixed-language text
- some contain emojis or punctuation that makes logs harder to search
- some accidentally include sensitive values or suspicious key names
logmsglint catches these issues statically, before they reach code review or production.
| Rule | Description | Autofix |
|---|---|---|
| Lowercase start | Log message should start with a lowercase letter | yes |
| English-only message | Log message should use English text | no |
| No special characters / emoji | Disallows unexpected punctuation and emoji | no |
| Sensitive data patterns | Detects configured keywords and regular expressions | no |
Sensitive data checks are configurable, so teams can tune them for their own conventions.
logmsglint checks message arguments in common Go logging calls.
Supported packages:
log/sloggo.uber.org/zap
Example calls:
slog.Info("server started")
slog.Error("request failed", "err", err)
logger.Info("server started")
logger.Error("request failed", zap.Error(err))Clone and build:
git clone https://github.com/timur-developer/logmsglint.git
cd logmsglint
go build -o logmsglint ./cmd/logmsglintRun:
./logmsglint ./...logmsglint can also be embedded into a custom golangci-lint binary.
Build the custom linter binary:
golangci-lint custom -vThen run it:
./custom-gcl run ./...Run the analyzer for the current module:
./logmsglint ./...Run for a specific package:
./logmsglint ./internal/serviceCreate a .golangci.yml configuration and enable logmsglint.
./custom-gcl run -c .golangci.yml ./...Run with fixes enabled:
./custom-gcl run -c .golangci.yml --fix ./...Example .golangci.yml:
version: "2"
linters:
default: none
enable:
- logmsglint
settings:
custom:
logmsglint:
type: module
description: Checks slog/zap log messages.
settings:
enable_fixes: true
allowed_punct: ""
sensitive_keywords:
- "password"
- "secret"
- "secret_token"
sensitive_regexps:
- "(?i)api[_-]?key\\s*="
- "(?i)token\\s*="Configuration ideas:
- use
allowed_punctif your team allows selected punctuation in log messages - add project-specific words to
sensitive_keywords - use
sensitive_regexpsfor patterns such astoken=...,api_key=..., or similar forms - enable
enable_fixesif you want automatic lowercase fixes
Input:
package main
import "log/slog"
func main() {
slog.Info("Starting server")
slog.Info("запуск сервера")
slog.Info("server started 🚀")
slog.Info("token=abc123")
}Output:
main.go:6: log message must start with a lowercase letter
main.go:7: log message must contain only English letters
main.go:8: log message must not contain emoji or disallowed special characters
main.go:9: log message may contain sensitive data
After running with --fix, the first message becomes:
slog.Info("starting server")Autofix is intentionally conservative.
Currently, logmsglint can fix messages that only violate the lowercase-start rule:
slog.Info("Starting server")becomes:
slog.Info("starting server")The analyzer does not automatically rewrite non-English messages, remove emoji, or edit potentially sensitive content because those changes require human judgment.
Example GitHub Actions step for standalone usage:
- name: Run logmsglint
run: go run ./cmd/logmsglint ./...Example step for a custom golangci-lint binary:
- name: Build custom golangci-lint
run: golangci-lint custom -v
- name: Run linters
run: ./custom-gcl run -c .golangci.yml ./...Run tests:
go test ./...Build:
go build ./...Run the analyzer from source:
go run ./cmd/logmsglint ./...MIT. See LICENSE.
