mirror of https://github.com/gofiber/fiber.git
Merge branch 'main' into reduce-defaultCtx
commit
87963876b7
|
@ -298,11 +298,12 @@ func (r *Request) Cookie(key string) string {
|
|||
// Use maps.Collect() to gather them into a map if needed.
|
||||
func (r *Request) Cookies() iter.Seq2[string, string] {
|
||||
return func(yield func(string, string) bool) {
|
||||
r.cookies.VisitAll(func(key, val string) {
|
||||
if !yield(key, val) {
|
||||
for k, v := range *r.cookies {
|
||||
res := yield(k, v)
|
||||
if !res {
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,11 +344,11 @@ func (r *Request) PathParam(key string) string {
|
|||
// Use maps.Collect() to gather them into a map if needed.
|
||||
func (r *Request) PathParams() iter.Seq2[string, string] {
|
||||
return func(yield func(string, string) bool) {
|
||||
r.path.VisitAll(func(key, val string) {
|
||||
if !yield(key, val) {
|
||||
for k, v := range *r.path {
|
||||
if !yield(k, v) {
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//nolint:goconst // Much easier to just ignore memory leaks in tests
|
||||
package client
|
||||
|
||||
import (
|
||||
|
@ -451,6 +452,14 @@ func Test_Request_Cookies(t *testing.T) {
|
|||
require.Equal(t, "bar", cookies["foo"])
|
||||
require.Equal(t, "foo", cookies["bar"])
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
for _, v := range req.Cookies() {
|
||||
if v == "bar" {
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
require.Len(t, cookies, 2)
|
||||
}
|
||||
|
||||
|
@ -564,6 +573,14 @@ func Test_Request_PathParams(t *testing.T) {
|
|||
require.Equal(t, "foo", pathParams["bar"])
|
||||
|
||||
require.Len(t, pathParams, 2)
|
||||
|
||||
require.NotPanics(t, func() {
|
||||
for _, v := range req.PathParams() {
|
||||
if v == "bar" {
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Benchmark_Request_PathParams(b *testing.B) {
|
||||
|
@ -1579,7 +1596,7 @@ func Test_SetValWithStruct(t *testing.T) {
|
|||
|
||||
require.True(t, func() bool {
|
||||
for _, v := range p.PeekMulti("TSlice") {
|
||||
if string(v) == "bar" { //nolint:goconst // test
|
||||
if string(v) == "bar" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ app.Use(logger.New(logger.Config{
|
|||
TimeZone: "Asia/Shanghai",
|
||||
Done: func(c fiber.Ctx, logString []byte) {
|
||||
if c.Response().StatusCode() != fiber.StatusOK {
|
||||
reporter.SendToSlack(logString)
|
||||
reporter.SendToSlack(logString)
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
@ -88,6 +88,23 @@ app.Use(logger.New(logger.Config{
|
|||
app.Use(logger.New(logger.Config{
|
||||
DisableColors: true,
|
||||
}))
|
||||
|
||||
// Use predefined formats
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: logger.FormatCommon,
|
||||
}))
|
||||
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: logger.FormatCombined,
|
||||
}))
|
||||
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: logger.FormatJSON,
|
||||
}))
|
||||
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: logger.FormatECS,
|
||||
}))
|
||||
```
|
||||
|
||||
### Use Logger Middleware with Other Loggers
|
||||
|
@ -136,37 +153,50 @@ Writing to os.File is goroutine-safe, but if you are using a custom Stream that
|
|||
|
||||
### Config
|
||||
|
||||
| Property | Type | Description | Default |
|
||||
|:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------|
|
||||
| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
|
||||
| Skip | `func(fiber.Ctx) bool` | Skip is a function to determine if logging is skipped or written to Stream. | `nil` |
|
||||
| Done | `func(fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Stream, and pass the log string as parameter. | `nil` |
|
||||
| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` |
|
||||
| Format | `string` | Format defines the logging tags. | `[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` |
|
||||
| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` |
|
||||
| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` |
|
||||
| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` |
|
||||
| Stream | `io.Writer` | Stream is a writer where logs are written. | `os.Stdout` |
|
||||
| LoggerFunc | `func(c fiber.Ctx, data *Data, cfg Config) error` | Custom logger function for integration with logging libraries (Zerolog, Zap, Logrus, etc). Defaults to Fiber's default logger if not defined. | `see default_logger.go defaultLoggerInstance` |
|
||||
| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` |
|
||||
| Property | Type | Description | Default |
|
||||
| :------------ | :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
|
||||
| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
|
||||
| Skip | `func(fiber.Ctx) bool` | Skip is a function to determine if logging is skipped or written to Stream. | `nil` |
|
||||
| Done | `func(fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Stream, and pass the log string as parameter. | `nil` |
|
||||
| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` |
|
||||
| `Format` | `string` | Defines the logging tags. See more in [Predefined Formats](#predefined-formats), or create your own using [Tags](#constants). | `[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` (same as `DefaultFormat`) |
|
||||
| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` |
|
||||
| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` |
|
||||
| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` |
|
||||
| Stream | `io.Writer` | Stream is a writer where logs are written. | `os.Stdout` |
|
||||
| LoggerFunc | `func(c fiber.Ctx, data *Data, cfg Config) error` | Custom logger function for integration with logging libraries (Zerolog, Zap, Logrus, etc). Defaults to Fiber's default logger if not defined. | `see default_logger.go defaultLoggerInstance` |
|
||||
| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` |
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Skip nil,
|
||||
Done: nil,
|
||||
Format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n",
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
TimeInterval: 500 * time.Millisecond,
|
||||
Stream: os.Stdout,
|
||||
DisableColors: false,
|
||||
LoggerFunc: defaultLoggerInstance,
|
||||
Next: nil,
|
||||
Skip: nil,
|
||||
Done: nil,
|
||||
Format: DefaultFormat,
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
TimeInterval: 500 * time.Millisecond,
|
||||
Stream: os.Stdout,
|
||||
BeforeHandlerFunc: beforeHandlerFunc,
|
||||
LoggerFunc: defaultLoggerInstance,
|
||||
enableColors: true,
|
||||
}
|
||||
```
|
||||
|
||||
## Predefined Formats
|
||||
|
||||
Logger provides predefined formats that you can use by name or directly by specifying the format string.
|
||||
|
||||
| **Format Constant** | **Format String** | **Description** |
|
||||
|---------------------|--------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|
|
||||
| `DefaultFormat` | `"[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"` | Fiber's default logger format. |
|
||||
| `CommonFormat` | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent}\n"` | Common Log Format (CLF) used in web server logs. |
|
||||
| `CombinedFormat` | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent} "${referer}" "${ua}"\n"` | CLF format plus the `referer` and `user agent` fields. |
|
||||
| `JSONFormat` | `"{time: ${time}, ip: ${ip}, method: ${method}, url: ${url}, status: ${status}, bytesSent: ${bytesSent}}\n"` | JSON format for structured logging. |
|
||||
| `ECSFormat` | `"{\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}\n"` | Elastic Common Schema (ECS) format for structured logging. |
|
||||
|
||||
## Constants
|
||||
|
||||
```go
|
||||
|
|
|
@ -937,6 +937,22 @@ app.Use(logger.New(logger.Config{
|
|||
|
||||
</details>
|
||||
|
||||
#### Predefined Formats
|
||||
|
||||
Logger provides predefined formats that you can use by name or directly by specifying the format string.
|
||||
<details>
|
||||
|
||||
<summary>Example Usage</summary>
|
||||
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: logger.FormatCombined,
|
||||
}))
|
||||
```
|
||||
|
||||
See more in [Logger](./middleware/logger.md#predefined-formats)
|
||||
</details>
|
||||
|
||||
### Filesystem
|
||||
|
||||
We've decided to remove filesystem middleware to clear up the confusion between static and filesystem middleware.
|
||||
|
|
|
@ -1331,56 +1331,65 @@ func Test_CSRF_Cookie_Injection_Exploit(t *testing.T) {
|
|||
}
|
||||
|
||||
// TODO: use this test case and make the unsafe header value bug from https://github.com/gofiber/fiber/issues/2045 reproducible and permanently fixed/tested by this testcase
|
||||
// func Test_CSRF_UnsafeHeaderValue(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// app := fiber.New()
|
||||
func Test_CSRF_UnsafeHeaderValue(t *testing.T) {
|
||||
t.SkipNow()
|
||||
t.Parallel()
|
||||
app := fiber.New()
|
||||
|
||||
// app.Use(New())
|
||||
// app.Get("/", func(c fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusOK)
|
||||
// })
|
||||
// app.Get("/test", func(c fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusOK)
|
||||
// })
|
||||
// app.Post("/", func(c fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusOK)
|
||||
// })
|
||||
app.Use(New())
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
app.Get("/test", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
app.Post("/", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
// resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
// require.NoError(t, err)
|
||||
// require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
// var token string
|
||||
// for _, c := range resp.Cookies() {
|
||||
// if c.Name != ConfigDefault.CookieName {
|
||||
// continue
|
||||
// }
|
||||
// token = c.Value
|
||||
// break
|
||||
// }
|
||||
var token string
|
||||
for _, c := range resp.Cookies() {
|
||||
if c.Name != ConfigDefault.CookieName {
|
||||
continue
|
||||
}
|
||||
token = c.Value
|
||||
break
|
||||
}
|
||||
|
||||
// fmt.Println("token", token)
|
||||
t.Log("token", token)
|
||||
|
||||
// getReq := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||
// getReq.Header.Set(HeaderName, token)
|
||||
// resp, err = app.Test(getReq)
|
||||
getReq := httptest.NewRequest(fiber.MethodGet, "/", nil)
|
||||
getReq.Header.Set(HeaderName, token)
|
||||
resp, err = app.Test(getReq)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
// getReq = httptest.NewRequest(fiber.MethodGet, "/test", nil)
|
||||
// getReq.Header.Set("X-Requested-With", "XMLHttpRequest")
|
||||
// getReq.Header.Set(fiber.HeaderCacheControl, "no")
|
||||
// getReq.Header.Set(HeaderName, token)
|
||||
getReq = httptest.NewRequest(fiber.MethodGet, "/test", nil)
|
||||
getReq.Header.Set("X-Requested-With", "XMLHttpRequest")
|
||||
getReq.Header.Set(fiber.HeaderCacheControl, "no")
|
||||
getReq.Header.Set(HeaderName, token)
|
||||
|
||||
// resp, err = app.Test(getReq)
|
||||
resp, err = app.Test(getReq)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
// getReq.Header.Set(fiber.HeaderAccept, "*/*")
|
||||
// getReq.Header.Del(HeaderName)
|
||||
// resp, err = app.Test(getReq)
|
||||
getReq.Header.Set(fiber.HeaderAccept, "*/*")
|
||||
getReq.Header.Del(HeaderName)
|
||||
resp, err = app.Test(getReq)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
|
||||
// postReq := httptest.NewRequest(fiber.MethodPost, "/", nil)
|
||||
// postReq.Header.Set("X-Requested-With", "XMLHttpRequest")
|
||||
// postReq.Header.Set(HeaderName, token)
|
||||
// resp, err = app.Test(postReq)
|
||||
// }
|
||||
postReq := httptest.NewRequest(fiber.MethodPost, "/", nil)
|
||||
postReq.Header.Set("X-Requested-With", "XMLHttpRequest")
|
||||
postReq.Header.Set(HeaderName, token)
|
||||
resp, err = app.Test(postReq)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusOK, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Middleware_CSRF_Check -benchmem -count=4
|
||||
func Benchmark_Middleware_CSRF_Check(b *testing.B) {
|
||||
|
|
|
@ -50,9 +50,23 @@ type Config struct {
|
|||
|
||||
timeZoneLocation *time.Location
|
||||
|
||||
// Format defines the logging tags
|
||||
// Format defines the logging format for the middleware.
|
||||
//
|
||||
// Optional. Default: [${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}
|
||||
// You can customize the log output by defining a format string with placeholders
|
||||
// such as: ${time}, ${ip}, ${status}, ${method}, ${path}, ${latency}, ${error}, etc.
|
||||
// The full list of available placeholders can be found in 'tags.go' or at
|
||||
// 'https://docs.gofiber.io/api/middleware/logger/#constants'.
|
||||
//
|
||||
// Fiber provides predefined logging formats that can be used directly:
|
||||
//
|
||||
// - DefaultFormat → Uses the default log format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}"
|
||||
// - CommonFormat → Uses the Apache Common Log Format (CLF): "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent}\n"
|
||||
// - CombinedFormat → Uses the Apache Combined Log Format: "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent} \"${referer}\" \"${ua}\"\n"
|
||||
// - JSONFormat → Uses the JSON log format: "{\"time\":\"${time}\",\"ip\":\"${ip}\",\"method\":\"${method}\",\"url\":\"${url}\",\"status\":${status},\"bytesSent\":${bytesSent}}\n"
|
||||
// - ECSFormat → Uses the Elastic Common Schema (ECS) log format: {\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}"
|
||||
// If both `Format` and `CustomFormat` are provided, the `CustomFormat` will be used, and the `Format` field will be ignored.
|
||||
// If no format is specified, the default format is used:
|
||||
// "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}"
|
||||
Format string
|
||||
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
|
@ -105,7 +119,7 @@ var ConfigDefault = Config{
|
|||
Next: nil,
|
||||
Skip: nil,
|
||||
Done: nil,
|
||||
Format: defaultFormat,
|
||||
Format: DefaultFormat,
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
TimeInterval: 500 * time.Millisecond,
|
||||
|
@ -115,9 +129,6 @@ var ConfigDefault = Config{
|
|||
enableColors: true,
|
||||
}
|
||||
|
||||
// default logging format for Fiber's default logger
|
||||
var defaultFormat = "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"
|
||||
|
||||
// Helper function to set default values
|
||||
func configDefault(config ...Config) Config {
|
||||
// Return default config if nothing provided
|
||||
|
|
|
@ -28,7 +28,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error {
|
|||
buf := bytebufferpool.Get()
|
||||
|
||||
// Default output when no custom Format or io.Writer is given
|
||||
if cfg.Format == defaultFormat {
|
||||
if cfg.Format == DefaultFormat {
|
||||
// Format error if exist
|
||||
formatErr := ""
|
||||
if cfg.enableColors {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package logger
|
||||
|
||||
const (
|
||||
// Fiber's default logger
|
||||
DefaultFormat = "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"
|
||||
// Apache Common Log Format (CLF)
|
||||
CommonFormat = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent}\n"
|
||||
// Apache Combined Log Format
|
||||
CombinedFormat = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent} \"${referer}\" \"${ua}\"\n"
|
||||
// JSON log formats
|
||||
JSONFormat = "{\"time\":\"${time}\",\"ip\":\"${ip}\",\"method\":\"${method}\",\"url\":\"${url}\",\"status\":${status},\"bytesSent\":${bytesSent}}\n"
|
||||
// Elastic Common Schema (ECS) Log Format
|
||||
ECSFormat = "{\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}\n"
|
||||
)
|
|
@ -40,7 +40,6 @@ func New(config ...Config) fiber.Handler {
|
|||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Set PID once
|
||||
pid := strconv.Itoa(os.Getpid())
|
||||
|
||||
|
|
|
@ -467,6 +467,124 @@ func Test_Logger_All(t *testing.T) {
|
|||
require.Equal(t, expected, buf.String())
|
||||
}
|
||||
|
||||
func Test_Logger_CLF_Format(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Format: CommonFormat,
|
||||
Stream: buf,
|
||||
}))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
|
||||
expected := fmt.Sprintf("0.0.0.0 - - [%s] \"%s %s %s\" %d %d\n",
|
||||
time.Now().Format("15:04:05"),
|
||||
fiber.MethodGet, "/?foo=bar", "HTTP/1.1",
|
||||
fiber.StatusNotFound,
|
||||
0)
|
||||
logResponse := buf.String()
|
||||
require.Equal(t, expected, logResponse)
|
||||
}
|
||||
|
||||
func Test_Logger_Combined_CLF_Format(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Format: CombinedFormat,
|
||||
Stream: buf,
|
||||
}))
|
||||
const expectedUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
|
||||
const expectedReferer = "http://example.com"
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)
|
||||
req.Header.Set("Referer", expectedReferer)
|
||||
req.Header.Set("User-Agent", expectedUA)
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
|
||||
expected := fmt.Sprintf("0.0.0.0 - - [%s] %q %d %d %q %q\n",
|
||||
time.Now().Format("15:04:05"),
|
||||
fmt.Sprintf("%s %s %s", fiber.MethodGet, "/?foo=bar", "HTTP/1.1"),
|
||||
fiber.StatusNotFound,
|
||||
0,
|
||||
expectedReferer,
|
||||
expectedUA)
|
||||
logResponse := buf.String()
|
||||
require.Equal(t, expected, logResponse)
|
||||
}
|
||||
|
||||
func Test_Logger_Json_Format(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Format: JSONFormat,
|
||||
Stream: buf,
|
||||
}))
|
||||
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
|
||||
expected := fmt.Sprintf(
|
||||
"{\"time\":%q,\"ip\":%q,\"method\":%q,\"url\":%q,\"status\":%d,\"bytesSent\":%d}\n",
|
||||
time.Now().Format("15:04:05"),
|
||||
"0.0.0.0",
|
||||
fiber.MethodGet,
|
||||
"/?foo=bar",
|
||||
fiber.StatusNotFound,
|
||||
0,
|
||||
)
|
||||
logResponse := buf.String()
|
||||
require.Equal(t, expected, logResponse)
|
||||
}
|
||||
|
||||
func Test_Logger_ECS_Format(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Format: ECSFormat,
|
||||
Stream: buf,
|
||||
}))
|
||||
|
||||
req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
|
||||
expected := fmt.Sprintf(
|
||||
"{\"@timestamp\":%q,\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":%q},\"http\":{\"request\":{\"method\":%q,\"url\":%q,\"protocol\":%q},\"response\":{\"status_code\":%d,\"body\":{\"bytes\":%d}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":%q}\n",
|
||||
time.Now().Format("15:04:05"),
|
||||
"0.0.0.0",
|
||||
fiber.MethodGet,
|
||||
"/?foo=bar",
|
||||
"HTTP/1.1",
|
||||
fiber.StatusNotFound,
|
||||
0,
|
||||
fmt.Sprintf("%s %s responded with %d", fiber.MethodGet, "/?foo=bar", fiber.StatusNotFound),
|
||||
)
|
||||
logResponse := buf.String()
|
||||
require.Equal(t, expected, logResponse)
|
||||
}
|
||||
|
||||
func getLatencyTimeUnits() []struct {
|
||||
unit string
|
||||
div time.Duration
|
||||
|
|
Loading…
Reference in New Issue