Files
godoxy-yusing/internal/logging/accesslog/multi_access_logger.go
yusing bd1ff9731d refactor(accesslog): restructure access logging; enhance console output format
Major refactoring of the access logging infrastructure to improve code organization and add proper console/stdout logging support.

- Renamed `Writer` interface to `File` and consolidated with `SupportRotate`
- Renamed `Log(req, res)` to `LogRequest(req, res)` for clarity
- Added new `ConsoleLogger` with zerolog console writer for formatted stdout output
- Moved type definitions to new `types.go` file
- Changed buffer handling from `[]byte` returns to `*bytes.Buffer` parameters
- Renamed internal files for clarity (`access_logger.go` → `file_access_logger.go`)
- Fixed fileserver access logging timing: moved logging after handler execution with defer
- Correct response handling in Fileserver
- Remove deprecated field `buffer_size`
- Simplify and removed unnecessary code

All callers have been updated to use the new APIs.
2026-01-21 14:32:28 +00:00

71 lines
1.8 KiB
Go

package accesslog
import (
"net/http"
maxmind "github.com/yusing/godoxy/internal/maxmind/types"
"github.com/yusing/goutils/task"
)
type MultiAccessLogger struct {
accessLoggers []AccessLogger
}
// NewMultiAccessLogger creates a new AccessLogger that writes to multiple writers.
//
// If there is only one writer, it will return a single AccessLogger.
// Otherwise, it will return a MultiAccessLogger that writes to all the writers.
func NewMultiAccessLogger(parent task.Parent, cfg AnyConfig, writers []File) AccessLogger {
if len(writers) == 1 {
if writers[0] == stdout {
return NewConsoleLogger(cfg.ToConfig())
}
return NewFileAccessLogger(parent, writers[0], cfg)
}
accessLoggers := make([]AccessLogger, len(writers))
for i, writer := range writers {
if writer == stdout {
accessLoggers[i] = NewConsoleLogger(cfg.ToConfig())
} else {
accessLoggers[i] = NewFileAccessLogger(parent, writer, cfg)
}
}
return &MultiAccessLogger{accessLoggers}
}
func (m *MultiAccessLogger) Config() *Config {
return m.accessLoggers[0].Config()
}
func (m *MultiAccessLogger) LogRequest(req *http.Request, res *http.Response) {
for _, accessLogger := range m.accessLoggers {
accessLogger.LogRequest(req, res)
}
}
func (m *MultiAccessLogger) LogError(req *http.Request, err error) {
for _, accessLogger := range m.accessLoggers {
accessLogger.LogError(req, err)
}
}
func (m *MultiAccessLogger) LogACL(info *maxmind.IPInfo, blocked bool) {
for _, accessLogger := range m.accessLoggers {
accessLogger.LogACL(info, blocked)
}
}
func (m *MultiAccessLogger) Flush() {
for _, accessLogger := range m.accessLoggers {
accessLogger.Flush()
}
}
func (m *MultiAccessLogger) Close() error {
for _, accessLogger := range m.accessLoggers {
accessLogger.Close()
}
return nil
}