fix(log): write each log category to its own file (#2206)

Previously, `makeLogHandler()` hardcoded "standard" as the logfile name
passed to `getLogWriter()`, causing all log categories (`database`,
`http`, `events`, `mail`) to write to `standard.log` instead of their
own files.

Add a logfile parameter to `makeLogHandler()` so each caller specifies
its category name, producing `database.log`, `http.log`, `echo.log`,
`events.log`, and `mail.log` as expected.

Fixes https://github.com/go-vikunja/vikunja/issues/2177
This commit is contained in:
kolaente
2026-02-08 16:22:58 +01:00
committed by GitHub
parent b6974ffcfd
commit 0e05d1cc9d
6 changed files with 35 additions and 8 deletions

View File

@@ -22,6 +22,6 @@ import (
// NewEchoLogger creates and initializes a new slog logger for Echo v5
func NewEchoLogger(configLogEnabled bool, configLogEcho string, configLogFormat string) *slog.Logger {
handler := makeLogHandler(configLogEnabled, configLogEcho, "DEBUG", configLogFormat)
handler := makeLogHandler(configLogEnabled, configLogEcho, "http", "DEBUG", configLogFormat)
return slog.New(handler).With("component", "http")
}

View File

@@ -37,7 +37,7 @@ func InitLogger() {
logInstance = slog.New(handler)
}
func makeLogHandler(enabled bool, output string, level string, format string) slog.Handler {
func makeLogHandler(enabled bool, output string, logfile string, level string, format string) slog.Handler {
var slogLevel slog.Level
switch strings.ToUpper(level) {
case "CRITICAL", "ERROR":
@@ -62,7 +62,7 @@ func makeLogHandler(enabled bool, output string, level string, format string) sl
writer := io.Discard
if enabled && output != "off" {
writer = getLogWriter(output, "standard")
writer = getLogWriter(output, logfile)
}
return createHandler(writer, slogLevel, format)
@@ -89,7 +89,7 @@ func createHandler(writer io.Writer, level slog.Level, format string) slog.Handl
// NewHTTPLogger creates and initializes a new HTTP logger
func NewHTTPLogger(enabled bool, output string, format string) *slog.Logger {
handler := makeLogHandler(enabled, output, "DEBUG", format)
handler := makeLogHandler(enabled, output, "http", "DEBUG", format)
return slog.New(handler).With("component", "http")
}
@@ -97,7 +97,7 @@ func NewHTTPLogger(enabled bool, output string, format string) *slog.Logger {
// ConfigureStandardLogger configures the global log handler
func ConfigureStandardLogger(enabled bool, output string, path string, level string, format string) {
logPath = path
handler := makeLogHandler(enabled, output, level, format)
handler := makeLogHandler(enabled, output, "standard", level, format)
logInstance = slog.New(handler)
}

View File

@@ -40,6 +40,33 @@ func TestConfigureStandardLoggerWithPath(t *testing.T) {
assert.True(t, os.IsNotExist(err), "Log file should NOT be created in current directory")
}
func TestMakeLogHandlerCreatesCorrectLogFile(t *testing.T) {
tempDir := t.TempDir()
logPath = tempDir
tests := []struct {
name string
logfile string
expected string
}{
{"standard", "standard", "standard.log"},
{"database", "database", "database.log"},
{"http", "http", "http.log"},
{"events", "events", "events.log"},
{"mail", "mail", "mail.log"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_ = makeLogHandler(true, "file", tt.logfile, "INFO", "text")
expectedPath := filepath.Join(tempDir, tt.expected)
_, err := os.Stat(expectedPath)
require.NoError(t, err, "Log file %s should be created", tt.expected)
})
}
}
func TestConfigureStandardLoggerSetsPathBeforeHandler(t *testing.T) {
tempDir := t.TempDir()

View File

@@ -29,7 +29,7 @@ type MailLogger struct {
// NewMailLogger creates and initializes a new mail logger
func NewMailLogger(configLogEnabled bool, configLogMail string, configLogMailLevel string, configLogFormat string) maillog.Logger {
handler := makeLogHandler(configLogEnabled, configLogMail, configLogMailLevel, configLogFormat)
handler := makeLogHandler(configLogEnabled, configLogMail, "mail", configLogMailLevel, configLogFormat)
mailLogger := &MailLogger{
logger: slog.New(handler).With("component", "mail"),

View File

@@ -29,7 +29,7 @@ type WatermillLogger struct {
// NewWatermillLogger creates and initializes a new watermill logger
func NewWatermillLogger(configLogEnabled bool, configLogEvents string, configLogEventsLevel string, configLogFormat string) *WatermillLogger {
handler := makeLogHandler(configLogEnabled, configLogEvents, configLogEventsLevel, configLogFormat)
handler := makeLogHandler(configLogEnabled, configLogEvents, "events", configLogEventsLevel, configLogFormat)
watermillLogger := &WatermillLogger{
logger: slog.New(handler).With("component", "events"),

View File

@@ -31,7 +31,7 @@ type XormLogger struct {
// NewXormLogger creates and initializes a new xorm logger
func NewXormLogger(configLogEnabled bool, configLogDatabase string, configLogDatabaseLevel string, configLogFormat string) *XormLogger {
handler := makeLogHandler(configLogEnabled, configLogDatabase, configLogDatabaseLevel, configLogFormat)
handler := makeLogHandler(configLogEnabled, configLogDatabase, "database", configLogDatabaseLevel, configLogFormat)
xormLogger := &XormLogger{
logger: slog.New(handler).With("component", "database"),