mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-18 06:29:42 +02:00
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.
This commit is contained in:
committed by
github-actions[bot]
parent
235af71343
commit
bd1ff9731d
@@ -16,9 +16,11 @@ type (
|
||||
CommonFormatter struct {
|
||||
cfg *Fields
|
||||
}
|
||||
CombinedFormatter struct{ CommonFormatter }
|
||||
JSONFormatter struct{ CommonFormatter }
|
||||
ACLLogFormatter struct{}
|
||||
CombinedFormatter struct{ CommonFormatter }
|
||||
JSONFormatter struct{ cfg *Fields }
|
||||
ConsoleFormatter struct{ cfg *Fields }
|
||||
ACLLogFormatter struct{}
|
||||
ConsoleACLFormatter struct{}
|
||||
)
|
||||
|
||||
const LogTimeFormat = "02/Jan/2006:15:04:05 -0700"
|
||||
@@ -30,24 +32,26 @@ func scheme(req *http.Request) string {
|
||||
return "http"
|
||||
}
|
||||
|
||||
func appendRequestURI(line []byte, req *http.Request, query iter.Seq2[string, []string]) []byte {
|
||||
func appendRequestURI(line *bytes.Buffer, req *http.Request, query iter.Seq2[string, []string]) {
|
||||
uri := req.URL.EscapedPath()
|
||||
line = append(line, uri...)
|
||||
line.WriteString(uri)
|
||||
isFirst := true
|
||||
for k, v := range query {
|
||||
if isFirst {
|
||||
line = append(line, '?')
|
||||
line.WriteByte('?')
|
||||
isFirst = false
|
||||
} else {
|
||||
line = append(line, '&')
|
||||
line.WriteByte('&')
|
||||
}
|
||||
line = append(line, k...)
|
||||
line = append(line, '=')
|
||||
for _, v := range v {
|
||||
line = append(line, v...)
|
||||
for i, val := range v {
|
||||
if i > 0 {
|
||||
line.WriteByte('&')
|
||||
}
|
||||
line.WriteString(k)
|
||||
line.WriteByte('=')
|
||||
line.WriteString(val)
|
||||
}
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
func clientIP(req *http.Request) string {
|
||||
@@ -58,50 +62,51 @@ func clientIP(req *http.Request) string {
|
||||
return req.RemoteAddr
|
||||
}
|
||||
|
||||
func (f *CommonFormatter) AppendRequestLog(line []byte, req *http.Request, res *http.Response) []byte {
|
||||
func (f CommonFormatter) AppendRequestLog(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
query := f.cfg.Query.IterQuery(req.URL.Query())
|
||||
|
||||
line = append(line, req.Host...)
|
||||
line = append(line, ' ')
|
||||
line.WriteString(req.Host)
|
||||
line.WriteByte(' ')
|
||||
|
||||
line = append(line, clientIP(req)...)
|
||||
line = append(line, " - - ["...)
|
||||
line.WriteString(clientIP(req))
|
||||
line.WriteString(" - - [")
|
||||
|
||||
line = mockable.TimeNow().AppendFormat(line, LogTimeFormat)
|
||||
line = append(line, `] "`...)
|
||||
line.WriteString(mockable.TimeNow().Format(LogTimeFormat))
|
||||
line.WriteString("] \"")
|
||||
|
||||
line = append(line, req.Method...)
|
||||
line = append(line, ' ')
|
||||
line = appendRequestURI(line, req, query)
|
||||
line = append(line, ' ')
|
||||
line = append(line, req.Proto...)
|
||||
line = append(line, '"')
|
||||
line = append(line, ' ')
|
||||
line.WriteString(req.Method)
|
||||
line.WriteByte(' ')
|
||||
appendRequestURI(line, req, query)
|
||||
line.WriteByte(' ')
|
||||
line.WriteString(req.Proto)
|
||||
line.WriteByte('"')
|
||||
line.WriteByte(' ')
|
||||
|
||||
line = strconv.AppendInt(line, int64(res.StatusCode), 10)
|
||||
line = append(line, ' ')
|
||||
line = strconv.AppendInt(line, res.ContentLength, 10)
|
||||
return line
|
||||
line.WriteString(strconv.FormatInt(int64(res.StatusCode), 10))
|
||||
line.WriteByte(' ')
|
||||
line.WriteString(strconv.FormatInt(res.ContentLength, 10))
|
||||
}
|
||||
|
||||
func (f *CombinedFormatter) AppendRequestLog(line []byte, req *http.Request, res *http.Response) []byte {
|
||||
line = f.CommonFormatter.AppendRequestLog(line, req, res)
|
||||
line = append(line, " \""...)
|
||||
line = append(line, req.Referer()...)
|
||||
line = append(line, "\" \""...)
|
||||
line = append(line, req.UserAgent()...)
|
||||
line = append(line, '"')
|
||||
return line
|
||||
func (f CombinedFormatter) AppendRequestLog(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
f.CommonFormatter.AppendRequestLog(line, req, res)
|
||||
line.WriteString(" \"")
|
||||
line.WriteString(req.Referer())
|
||||
line.WriteString("\" \"")
|
||||
line.WriteString(req.UserAgent())
|
||||
line.WriteByte('"')
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) AppendRequestLog(line []byte, req *http.Request, res *http.Response) []byte {
|
||||
func (f JSONFormatter) AppendRequestLog(line *bytes.Buffer, req *http.Request, res *http.Response) {
|
||||
logger := zerolog.New(line)
|
||||
f.LogRequestZeroLog(&logger, req, res)
|
||||
}
|
||||
|
||||
func (f JSONFormatter) LogRequestZeroLog(logger *zerolog.Logger, req *http.Request, res *http.Response) {
|
||||
query := f.cfg.Query.ZerologQuery(req.URL.Query())
|
||||
headers := f.cfg.Headers.ZerologHeaders(req.Header)
|
||||
cookies := f.cfg.Cookies.ZerologCookies(req.Cookies())
|
||||
contentType := res.Header.Get("Content-Type")
|
||||
|
||||
writer := bytes.NewBuffer(line)
|
||||
logger := zerolog.New(writer)
|
||||
event := logger.Info().
|
||||
Str("time", mockable.TimeNow().Format(LogTimeFormat)).
|
||||
Str("ip", clientIP(req)).
|
||||
@@ -119,22 +124,33 @@ func (f *JSONFormatter) AppendRequestLog(line []byte, req *http.Request, res *ht
|
||||
Object("headers", headers).
|
||||
Object("cookies", cookies)
|
||||
|
||||
if res.StatusCode >= 400 {
|
||||
if res.Status != "" {
|
||||
event.Str("error", res.Status)
|
||||
} else {
|
||||
event.Str("error", http.StatusText(res.StatusCode))
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: zerolog will append a newline to the buffer
|
||||
event.Send()
|
||||
return writer.Bytes()
|
||||
}
|
||||
|
||||
func (f ACLLogFormatter) AppendACLLog(line []byte, info *maxmind.IPInfo, blocked bool) []byte {
|
||||
writer := bytes.NewBuffer(line)
|
||||
logger := zerolog.New(writer)
|
||||
func (f ConsoleFormatter) LogRequestZeroLog(logger *zerolog.Logger, req *http.Request, res *http.Response) {
|
||||
contentType := res.Header.Get("Content-Type")
|
||||
|
||||
var reqURI bytes.Buffer
|
||||
appendRequestURI(&reqURI, req, f.cfg.Query.IterQuery(req.URL.Query()))
|
||||
|
||||
event := logger.Info().
|
||||
Bytes("uri", reqURI.Bytes()).
|
||||
Str("protocol", req.Proto).
|
||||
Str("type", contentType).
|
||||
Int64("size", res.ContentLength).
|
||||
Str("useragent", req.UserAgent())
|
||||
|
||||
// NOTE: zerolog will append a newline to the buffer
|
||||
event.Msgf("[%d] %s %s://%s from %s", res.StatusCode, req.Method, scheme(req), req.Host, clientIP(req))
|
||||
}
|
||||
|
||||
func (f ACLLogFormatter) AppendACLLog(line *bytes.Buffer, info *maxmind.IPInfo, blocked bool) {
|
||||
logger := zerolog.New(line)
|
||||
f.LogACLZeroLog(&logger, info, blocked)
|
||||
}
|
||||
|
||||
func (f ACLLogFormatter) LogACLZeroLog(logger *zerolog.Logger, info *maxmind.IPInfo, blocked bool) {
|
||||
event := logger.Info().
|
||||
Str("time", mockable.TimeNow().Format(LogTimeFormat)).
|
||||
Str("ip", info.Str)
|
||||
@@ -144,10 +160,32 @@ func (f ACLLogFormatter) AppendACLLog(line []byte, info *maxmind.IPInfo, blocked
|
||||
event.Str("action", "allow")
|
||||
}
|
||||
if info.City != nil {
|
||||
event.Str("iso_code", info.City.Country.IsoCode)
|
||||
event.Str("time_zone", info.City.Location.TimeZone)
|
||||
if isoCode := info.City.Country.IsoCode; isoCode != "" {
|
||||
event.Str("iso_code", isoCode)
|
||||
}
|
||||
if timeZone := info.City.Location.TimeZone; timeZone != "" {
|
||||
event.Str("time_zone", timeZone)
|
||||
}
|
||||
}
|
||||
// NOTE: zerolog will append a newline to the buffer
|
||||
event.Send()
|
||||
return writer.Bytes()
|
||||
}
|
||||
|
||||
func (f ConsoleACLFormatter) LogACLZeroLog(logger *zerolog.Logger, info *maxmind.IPInfo, blocked bool) {
|
||||
event := logger.Info()
|
||||
if info.City != nil {
|
||||
if isoCode := info.City.Country.IsoCode; isoCode != "" {
|
||||
event.Str("iso_code", isoCode)
|
||||
}
|
||||
if timeZone := info.City.Location.TimeZone; timeZone != "" {
|
||||
event.Str("time_zone", timeZone)
|
||||
}
|
||||
}
|
||||
action := "accepted"
|
||||
if blocked {
|
||||
action = "denied"
|
||||
}
|
||||
|
||||
// NOTE: zerolog will append a newline to the buffer
|
||||
event.Msgf("request %s from %s", action, info.Str)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user