Add the canonical .golangci.yml (v2 schema, all linters enabled with a
small documented disable list) and pin the Dockerfile lint stage to
golangci/golangci-lint:v2.12.2 by tag and digest, replacing the old
v1.64.8 digest-only pin.
Fix all findings surfaced by the v1 to v2 jump without changing any
exported signatures or behavior:
- add package and exported-symbol doc comments (revive)
- rename unused handler parameters to underscore (revive)
- check or explicitly discard error returns (errcheck, errchkjson)
- wrap errors with %w instead of %v (err113)
- use http.NewRequestWithContext instead of http.Post (noctx)
- replace fmt.Println with fmt.Fprintln(os.Stdout, ...) (forbidigo)
- name magic numbers as constants (mnd)
- add explicit slog.LevelDebug case (exhaustive)
- interface{} to any (modernize)
- move tests to the simplelog_test package (testpackage) and add
t.Parallel() (paralleltest)
- move NewWebhookHandler above its methods (funcorder)
- whitespace, line-length, and blank-line fixes (wsl_v5, whitespace,
nlreturn, lll, embeddedstructfieldcheck)
- nolint with justification for the intentional init/global design
(gochecknoinits, gochecknoglobals) and interface-returning
constructor (ireturn)
89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
package simplelog
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"runtime"
|
|
"time"
|
|
|
|
"github.com/fatih/color"
|
|
)
|
|
|
|
// callerSkipFrames is the number of stack frames between runtime.Caller
|
|
// and the slog call site that produced the record.
|
|
const callerSkipFrames = 4
|
|
|
|
// ConsoleHandler writes human-readable, colored log lines to stdout.
|
|
type ConsoleHandler struct{}
|
|
|
|
// NewConsoleHandler returns a new ConsoleHandler.
|
|
func NewConsoleHandler() *ConsoleHandler {
|
|
return &ConsoleHandler{}
|
|
}
|
|
|
|
// Handle writes the record to stdout as a colored, timestamped line
|
|
// including the caller file and line.
|
|
func (c *ConsoleHandler) Handle(
|
|
_ context.Context,
|
|
record slog.Record,
|
|
) error {
|
|
timestamp := time.Now().UTC().Format("2006-01-02T15:04:05.000Z07:00")
|
|
|
|
var colorFunc func(format string, a ...any) string
|
|
|
|
switch record.Level {
|
|
case slog.LevelDebug:
|
|
colorFunc = color.New(color.FgWhite).SprintfFunc()
|
|
case slog.LevelInfo:
|
|
colorFunc = color.New(color.FgBlue).SprintfFunc()
|
|
case slog.LevelWarn:
|
|
colorFunc = color.New(color.FgYellow).SprintfFunc()
|
|
case slog.LevelError:
|
|
colorFunc = color.New(color.FgRed).SprintfFunc()
|
|
default:
|
|
colorFunc = color.New(color.FgWhite).SprintfFunc()
|
|
}
|
|
|
|
// Get the caller information
|
|
_, file, line, ok := runtime.Caller(callerSkipFrames)
|
|
if !ok {
|
|
file = "???"
|
|
line = 0
|
|
}
|
|
|
|
_, _ = fmt.Fprintln(
|
|
os.Stdout,
|
|
colorFunc(
|
|
"%s [%s] %s:%d: %s",
|
|
timestamp,
|
|
record.Level,
|
|
file,
|
|
line,
|
|
record.Message,
|
|
),
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Enabled reports whether the handler processes records at the given
|
|
// level; it always returns true.
|
|
func (c *ConsoleHandler) Enabled(
|
|
_ context.Context,
|
|
_ slog.Level,
|
|
) bool {
|
|
return true
|
|
}
|
|
|
|
// WithAttrs returns the handler unchanged; attributes are not rendered.
|
|
func (c *ConsoleHandler) WithAttrs(_ []slog.Attr) slog.Handler {
|
|
return c
|
|
}
|
|
|
|
// WithGroup returns the handler unchanged; groups are not rendered.
|
|
func (c *ConsoleHandler) WithGroup(_ string) slog.Handler {
|
|
return c
|
|
}
|