Add Renovate log selector in pkg/doctor (checks.go). Use when adding message-based pattern matching, log categorization, new Renovate msg patterns, or Issues dashboard findings from Renovate JSON logs.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Add Renovate log selector in pkg/doctor (checks.go). Use when adding message-based pattern matching, log categorization, new Renovate msg patterns, or Issues dashboard findings from Renovate JSON logs.
Add Renovate log selector
Guide for adding a message-based selector in pkg/doctor. Selectors feed SimpleReport and the mintmaker-custom Kite webhook. They are separate from level-based ERROR/FATAL handling (pipeline-failure).
Before you start
Get a real Renovate log line that should trigger the check either from the user or from analyzing a log file (if provided). When you do not have the whole json log, do not attempt to create a selector.
Confirm the exact msg substring Renovate emits (copy from JSON, do not guess).
Decide severity: report.Error, report.Warning, or report.Info.
How matching works
Registered in init() via registerSelector(substring, checkFunc) in pkg/doctor/checks.go.
On each parsed line, log_reader.go runs strings.Contains(entry.Msg, selector).
The selector string must appear verbatim as a substring of msg (not regex).
Selectors run on all log levels.
Implementation checklist
Copy an existing check in checks.go (prLimitReached, renovateConfigErrors, rawExecError, platformCommitError) and adapt.
1. Check function — func myCheck(line *LogEntry, report *SimpleReport) (use descriptive function name) in checks.go:
Read fields from line.Extras (and line.Msg if needed). Unknown JSON keys land in Extras after parseLogLine. Analyze the real json log and extract a useful fields based on that.
For long err.message strings, use extractUsefulErrorDefault(message) (see rawExecError).
Return early if required structured data is missing (see rawExecError, platformCommitError).
2. Register — In init(), add registerSelector("<exact substring from Renovate msg>", myCheck).
3. Test fixture — Append one minimal JSON line to pkg/doctor/testdata/test_logs.json (or a dedicated file under testdata/ if the line is huge). Requirements:
Valid NDJSON: one JSON object per line.
msg contains the registered selector substring.
Synthetic / anonymized only: no real tokens, cookies, passwords, or internal-only URLs. Use placeholders (example-org, example.com, **redacted**). gitleaks runs on pre-commit.
Mirror structure from neighboring lines in test_logs.json (level, branch, err, etc.).
4. Tests — Add table-driven *_test.go in pkg/doctor when behavior is non-trivial: run ProcessLogFile on a small fixture and assert SimpleReport slices. No live HTTP.
go fmt ./pkg/doctor/...
golangci-lint run ./pkg/doctor
make test
make run-dev LOG_FILE=./pkg/doctor/testdata/test_logs.json
Use go run ./cmd/log-analyzer/main.go --dev with the same env vars as make run-dev when you need custom GIT_HOST / REPOSITORY / BRANCH. With a mock Kite URL, parsing and --dev console output still work; webhook HTTP may fail (expected).
Report formatting
formatSimpleMessage builds strings from title + alternating key/value fields.
Message values are appended on a new line; other fields use | key: value.
Common mistakes
Wrong selector string — Must match Renovate msg, not log text inside err.message only.
Regex in selector — Not supported; use exact substring or handle parsing inside the check function.
Bloated fixtures — Do not paste full production stack traces; trim to fields your check reads.
Skipping docs — Selector list in docs/README.md must stay in sync.
Changing Kite payloads — Selector work stays in pkg/doctor. Webhook schema changes belong in pkg/kite/ and require alignment with the Kite backend.
References
Architecture and selector pattern: docs/README.md (Selector Pattern, Selector List, Local Testing).