mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-21 08:21:51 +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
165
internal/logging/accesslog/file_access_logger_test.go
Normal file
165
internal/logging/accesslog/file_access_logger_test.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package accesslog_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/yusing/godoxy/internal/logging/accesslog"
|
||||
"github.com/yusing/goutils/mockable"
|
||||
"github.com/yusing/goutils/task"
|
||||
expect "github.com/yusing/goutils/testing"
|
||||
)
|
||||
|
||||
const (
|
||||
remote = "192.168.1.1"
|
||||
host = "example.com"
|
||||
uri = "/?bar=baz&foo=bar"
|
||||
uriRedacted = "/?bar=" + RedactedValue + "&foo=" + RedactedValue
|
||||
referer = "https://www.google.com/"
|
||||
proto = "HTTP/1.1"
|
||||
ua = "Go-http-client/1.1"
|
||||
status = http.StatusNotFound
|
||||
contentLength = 100
|
||||
method = http.MethodGet
|
||||
)
|
||||
|
||||
var (
|
||||
testTask = task.RootTask("test", false)
|
||||
testURL = expect.Must(url.Parse("http://" + host + uri))
|
||||
req = &http.Request{
|
||||
RemoteAddr: remote,
|
||||
Method: method,
|
||||
Proto: proto,
|
||||
Host: testURL.Host,
|
||||
URL: testURL,
|
||||
Header: http.Header{
|
||||
"User-Agent": []string{ua},
|
||||
"Referer": []string{referer},
|
||||
"Cookie": []string{
|
||||
"foo=bar",
|
||||
"bar=baz",
|
||||
},
|
||||
},
|
||||
}
|
||||
resp = &http.Response{
|
||||
StatusCode: status,
|
||||
ContentLength: contentLength,
|
||||
Header: http.Header{"Content-Type": []string{"text/plain"}},
|
||||
}
|
||||
)
|
||||
|
||||
func fmtLog(cfg *RequestLoggerConfig) (ts string, line string) {
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
|
||||
t := time.Now()
|
||||
logger := NewMockAccessLogger(testTask, cfg)
|
||||
mockable.MockTimeNow(t)
|
||||
logger.(RequestFormatter).AppendRequestLog(buf, req, resp)
|
||||
return t.Format(LogTimeFormat), buf.String()
|
||||
}
|
||||
|
||||
func TestAccessLoggerCommon(t *testing.T) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
config.Format = FormatCommon
|
||||
ts, log := fmtLog(config)
|
||||
expect.Equal(t, log,
|
||||
fmt.Sprintf("%s %s - - [%s] \"%s %s %s\" %d %d",
|
||||
host, remote, ts, method, uri, proto, status, contentLength,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func TestAccessLoggerCombined(t *testing.T) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
config.Format = FormatCombined
|
||||
ts, log := fmtLog(config)
|
||||
expect.Equal(t, log,
|
||||
fmt.Sprintf("%s %s - - [%s] \"%s %s %s\" %d %d \"%s\" \"%s\"",
|
||||
host, remote, ts, method, uri, proto, status, contentLength, referer, ua,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func TestAccessLoggerRedactQuery(t *testing.T) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
config.Format = FormatCommon
|
||||
config.Fields.Query.Default = FieldModeRedact
|
||||
ts, log := fmtLog(config)
|
||||
expect.Equal(t, log,
|
||||
fmt.Sprintf("%s %s - - [%s] \"%s %s %s\" %d %d",
|
||||
host, remote, ts, method, uriRedacted, proto, status, contentLength,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
type JSONLogEntry struct {
|
||||
Time string `json:"time"`
|
||||
IP string `json:"ip"`
|
||||
Method string `json:"method"`
|
||||
Scheme string `json:"scheme"`
|
||||
Host string `json:"host"`
|
||||
Path string `json:"path"`
|
||||
Protocol string `json:"protocol"`
|
||||
Status int `json:"status"`
|
||||
Error string `json:"error,omitempty"`
|
||||
ContentType string `json:"type"`
|
||||
Size int64 `json:"size"`
|
||||
Referer string `json:"referer"`
|
||||
UserAgent string `json:"useragent"`
|
||||
Query map[string][]string `json:"query,omitempty"`
|
||||
Headers map[string][]string `json:"headers,omitempty"`
|
||||
Cookies map[string]string `json:"cookies,omitempty"`
|
||||
}
|
||||
|
||||
func getJSONEntry(t *testing.T, config *RequestLoggerConfig) JSONLogEntry {
|
||||
t.Helper()
|
||||
config.Format = FormatJSON
|
||||
var entry JSONLogEntry
|
||||
_, log := fmtLog(config)
|
||||
err := json.Unmarshal([]byte(log), &entry)
|
||||
expect.NoError(t, err)
|
||||
return entry
|
||||
}
|
||||
|
||||
func TestAccessLoggerJSON(t *testing.T) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
entry := getJSONEntry(t, config)
|
||||
expect.Equal(t, entry.IP, remote)
|
||||
expect.Equal(t, entry.Method, method)
|
||||
expect.Equal(t, entry.Scheme, "http")
|
||||
expect.Equal(t, entry.Host, testURL.Host)
|
||||
expect.Equal(t, entry.Path, testURL.Path)
|
||||
expect.Equal(t, entry.Protocol, proto)
|
||||
expect.Equal(t, entry.Status, status)
|
||||
expect.Equal(t, entry.ContentType, "text/plain")
|
||||
expect.Equal(t, entry.Size, contentLength)
|
||||
expect.Equal(t, entry.Referer, referer)
|
||||
expect.Equal(t, entry.UserAgent, ua)
|
||||
expect.Equal(t, len(entry.Headers), 0)
|
||||
expect.Equal(t, len(entry.Cookies), 0)
|
||||
}
|
||||
|
||||
func BenchmarkAccessLoggerJSON(b *testing.B) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
config.Format = FormatJSON
|
||||
logger := NewMockAccessLogger(testTask, config)
|
||||
b.ResetTimer()
|
||||
for b.Loop() {
|
||||
logger.LogRequest(req, resp)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAccessLoggerCombined(b *testing.B) {
|
||||
config := DefaultRequestLoggerConfig()
|
||||
config.Format = FormatCombined
|
||||
logger := NewMockAccessLogger(testTask, config)
|
||||
b.ResetTimer()
|
||||
for b.Loop() {
|
||||
logger.LogRequest(req, resp)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user