mirror of https://github.com/gofiber/fiber.git
Improve interface for custom logger func (#2225)
* - logger: fix custom tag - use real bytebufferpool dependency instead of the internal * - logger: fix custom tag - use real bytebufferpool dependency instead of the internal * - logger: fix custom tag - use real bytebufferpool dependency instead of the internal * - logger: fix custom tag - use real bytebufferpool dependency instead of the internalpull/2227/head
parent
92ce4aac77
commit
e4b3b5c708
2
ctx.go
2
ctx.go
|
@ -24,10 +24,10 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/internal/dictpool"
|
||||
"github.com/gofiber/fiber/v2/internal/schema"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/internal/storage/memory"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -6,6 +6,7 @@ require (
|
|||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/mattn/go-runewidth v0.0.14
|
||||
github.com/valyala/bytebufferpool v1.0.0
|
||||
github.com/valyala/fasthttp v1.41.0
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
|
||||
)
|
||||
|
@ -14,6 +15,5 @@ require (
|
|||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/klauspost/compress v1.15.9 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
)
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
)
|
||||
|
||||
var testSimpleHandler = func(c *Ctx) error {
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Aliaksandr Valialkin, VertaMedia
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
package bytebufferpool
|
||||
|
||||
import "io"
|
||||
|
||||
// ByteBuffer provides byte buffer, which can be used for minimizing
|
||||
// memory allocations.
|
||||
//
|
||||
// ByteBuffer may be used with functions appending data to the given []byte
|
||||
// slice. See example code for details.
|
||||
//
|
||||
// Use Get for obtaining an empty byte buffer.
|
||||
type ByteBuffer struct {
|
||||
|
||||
// B is a byte buffer to use in append-like workloads.
|
||||
// See example code for details.
|
||||
B []byte
|
||||
}
|
||||
|
||||
// Len returns the size of the byte buffer.
|
||||
func (b *ByteBuffer) Len() int {
|
||||
return len(b.B)
|
||||
}
|
||||
|
||||
// ReadFrom implements io.ReaderFrom.
|
||||
//
|
||||
// The function appends all the data read from r to b.
|
||||
func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error) {
|
||||
p := b.B
|
||||
nStart := int64(len(p))
|
||||
nMax := int64(cap(p))
|
||||
n := nStart
|
||||
if nMax == 0 {
|
||||
nMax = 64
|
||||
p = make([]byte, nMax)
|
||||
} else {
|
||||
p = p[:nMax]
|
||||
}
|
||||
for {
|
||||
if n == nMax {
|
||||
nMax *= 2
|
||||
bNew := make([]byte, nMax)
|
||||
copy(bNew, p)
|
||||
p = bNew
|
||||
}
|
||||
nn, err := r.Read(p[n:])
|
||||
n += int64(nn)
|
||||
if err != nil {
|
||||
b.B = p[:n]
|
||||
n -= nStart
|
||||
if err == io.EOF {
|
||||
return n, nil
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WriteTo implements io.WriterTo.
|
||||
func (b *ByteBuffer) WriteTo(w io.Writer) (int64, error) {
|
||||
n, err := w.Write(b.B)
|
||||
return int64(n), err
|
||||
}
|
||||
|
||||
// Bytes returns b.B, i.e. all the bytes accumulated in the buffer.
|
||||
//
|
||||
// The purpose of this function is bytes.Buffer compatibility.
|
||||
func (b *ByteBuffer) Bytes() []byte {
|
||||
return b.B
|
||||
}
|
||||
|
||||
// Write implements io.Writer - it appends p to ByteBuffer.B
|
||||
func (b *ByteBuffer) Write(p []byte) (int, error) {
|
||||
b.B = append(b.B, p...)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// WriteByte appends the byte c to the buffer.
|
||||
//
|
||||
// The purpose of this function is bytes.Buffer compatibility.
|
||||
//
|
||||
// The function always returns nil.
|
||||
func (b *ByteBuffer) WriteByte(c byte) error {
|
||||
b.B = append(b.B, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteString appends s to ByteBuffer.B.
|
||||
func (b *ByteBuffer) WriteString(s string) (int, error) {
|
||||
b.B = append(b.B, s...)
|
||||
return len(s), nil
|
||||
}
|
||||
|
||||
// Set sets ByteBuffer.B to p.
|
||||
func (b *ByteBuffer) Set(p []byte) {
|
||||
b.B = append(b.B[:0], p...)
|
||||
}
|
||||
|
||||
// SetString sets ByteBuffer.B to s.
|
||||
func (b *ByteBuffer) SetString(s string) {
|
||||
b.B = append(b.B[:0], s...)
|
||||
}
|
||||
|
||||
// String returns string representation of ByteBuffer.B.
|
||||
func (b *ByteBuffer) String() string {
|
||||
return string(b.B)
|
||||
}
|
||||
|
||||
// Reset makes ByteBuffer.B empty.
|
||||
func (b *ByteBuffer) Reset() {
|
||||
b.B = b.B[:0]
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
package bytebufferpool
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
const (
|
||||
minBitSize = 6 // 2**6=64 is a CPU cache line size
|
||||
steps = 20
|
||||
|
||||
minSize = 1 << minBitSize
|
||||
maxSize = 1 << (minBitSize + steps - 1)
|
||||
|
||||
calibrateCallsThreshold = 42000
|
||||
maxPercentile = 0.95
|
||||
)
|
||||
|
||||
// Pool represents byte buffer pool.
|
||||
//
|
||||
// Distinct pools may be used for distinct types of byte buffers.
|
||||
// Properly determined byte buffer types with their own pools may help reducing
|
||||
// memory waste.
|
||||
type Pool struct {
|
||||
calls [steps]uint64
|
||||
calibrating uint64
|
||||
|
||||
defaultSize uint64
|
||||
maxSize uint64
|
||||
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
var defaultPool Pool
|
||||
|
||||
// Get returns an empty byte buffer from the pool.
|
||||
//
|
||||
// Got byte buffer may be returned to the pool via Put call.
|
||||
// This reduces the number of memory allocations required for byte buffer
|
||||
// management.
|
||||
func Get() *ByteBuffer { return defaultPool.Get() }
|
||||
|
||||
// Get returns new byte buffer with zero length.
|
||||
//
|
||||
// The byte buffer may be returned to the pool via Put after the use
|
||||
// in order to minimize GC overhead.
|
||||
func (p *Pool) Get() *ByteBuffer {
|
||||
v := p.pool.Get()
|
||||
if v != nil {
|
||||
return v.(*ByteBuffer)
|
||||
}
|
||||
return &ByteBuffer{
|
||||
B: make([]byte, 0, atomic.LoadUint64(&p.defaultSize)),
|
||||
}
|
||||
}
|
||||
|
||||
// Put returns byte buffer to the pool.
|
||||
//
|
||||
// ByteBuffer.B mustn't be touched after returning it to the pool.
|
||||
// Otherwise data races will occur.
|
||||
func Put(b *ByteBuffer) { defaultPool.Put(b) }
|
||||
|
||||
// Put releases byte buffer obtained via Get to the pool.
|
||||
//
|
||||
// The buffer mustn't be accessed after returning to the pool.
|
||||
func (p *Pool) Put(b *ByteBuffer) {
|
||||
idx := index(len(b.B))
|
||||
|
||||
if atomic.AddUint64(&p.calls[idx], 1) > calibrateCallsThreshold {
|
||||
p.calibrate()
|
||||
}
|
||||
|
||||
maxSize := int(atomic.LoadUint64(&p.maxSize))
|
||||
if maxSize == 0 || cap(b.B) <= maxSize {
|
||||
b.Reset()
|
||||
p.pool.Put(b)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pool) calibrate() {
|
||||
if !atomic.CompareAndSwapUint64(&p.calibrating, 0, 1) {
|
||||
return
|
||||
}
|
||||
|
||||
a := make(callSizes, 0, steps)
|
||||
var callsSum uint64
|
||||
for i := uint64(0); i < steps; i++ {
|
||||
calls := atomic.SwapUint64(&p.calls[i], 0)
|
||||
callsSum += calls
|
||||
a = append(a, callSize{
|
||||
calls: calls,
|
||||
size: minSize << i,
|
||||
})
|
||||
}
|
||||
sort.Sort(a)
|
||||
|
||||
defaultSize := a[0].size
|
||||
maxSize := defaultSize
|
||||
|
||||
maxSum := uint64(float64(callsSum) * maxPercentile)
|
||||
callsSum = 0
|
||||
for i := 0; i < steps; i++ {
|
||||
if callsSum > maxSum {
|
||||
break
|
||||
}
|
||||
callsSum += a[i].calls
|
||||
size := a[i].size
|
||||
if size > maxSize {
|
||||
maxSize = size
|
||||
}
|
||||
}
|
||||
|
||||
atomic.StoreUint64(&p.defaultSize, defaultSize)
|
||||
atomic.StoreUint64(&p.maxSize, maxSize)
|
||||
|
||||
atomic.StoreUint64(&p.calibrating, 0)
|
||||
}
|
||||
|
||||
type callSize struct {
|
||||
calls uint64
|
||||
size uint64
|
||||
}
|
||||
|
||||
type callSizes []callSize
|
||||
|
||||
func (ci callSizes) Len() int {
|
||||
return len(ci)
|
||||
}
|
||||
|
||||
func (ci callSizes) Less(i, j int) bool {
|
||||
return ci[i].calls > ci[j].calls
|
||||
}
|
||||
|
||||
func (ci callSizes) Swap(i, j int) {
|
||||
ci[i], ci[j] = ci[j], ci[i]
|
||||
}
|
||||
|
||||
func index(n int) int {
|
||||
n--
|
||||
n >>= minBitSize
|
||||
idx := 0
|
||||
for n > 0 {
|
||||
n >>= 1
|
||||
idx++
|
||||
}
|
||||
if idx >= steps {
|
||||
idx = steps - 1
|
||||
}
|
||||
return idx
|
||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||
"hash/crc32"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -40,7 +40,7 @@ app.Use(logger.New())
|
|||
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "[${ip}]:${port} ${status} - ${method} ${path}\n",
|
||||
Format: "[${ip}]:${port} ${status} - ${method} ${path}\n",
|
||||
}))
|
||||
```
|
||||
|
||||
|
@ -80,8 +80,8 @@ app.Use(logger.New(logger.Config{
|
|||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
CustomTags: map[string]logger.LogFunc{
|
||||
"custom_tag": func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString("it is a custom tag")
|
||||
"custom_tag": func(output logger.Buffer, c *fiber.Ctx, data *logger.Data, extraParam string) (int, error) {
|
||||
return output.WriteString("it is a custom tag")
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
@ -145,11 +145,9 @@ type Config struct {
|
|||
//
|
||||
// Default: os.Stdout
|
||||
Output io.Writer
|
||||
|
||||
enableColors bool
|
||||
enableLatency bool
|
||||
timeZoneLocation *time.Location
|
||||
}
|
||||
|
||||
type LogFunc func(buf logger.Buffer, c *fiber.Ctx, data *logger.Data, extraParam string) (int, error)
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
|
@ -64,7 +63,20 @@ const (
|
|||
paramSeparator = ":"
|
||||
)
|
||||
|
||||
type LogFunc func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error)
|
||||
type Buffer interface {
|
||||
Len() int
|
||||
ReadFrom(r io.Reader) (int64, error)
|
||||
WriteTo(w io.Writer) (int64, error)
|
||||
Bytes() []byte
|
||||
Write(p []byte) (int, error)
|
||||
WriteByte(c byte) error
|
||||
WriteString(s string) (int, error)
|
||||
Set(p []byte)
|
||||
SetString(s string)
|
||||
String() string
|
||||
}
|
||||
|
||||
type LogFunc func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error)
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
|
|
|
@ -13,9 +13,8 @@ import (
|
|||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
)
|
||||
|
||||
// New creates a new middleware handler
|
||||
|
@ -207,8 +206,8 @@ func New(config ...Config) fiber.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
func appendInt(buf *bytebufferpool.ByteBuffer, v int) (int, error) {
|
||||
old := len(buf.B)
|
||||
buf.B = fasthttp.AppendUint(buf.B, v)
|
||||
return len(buf.B) - old, nil
|
||||
func appendInt(output Buffer, v int) (int, error) {
|
||||
old := output.Len()
|
||||
output.Set(fasthttp.AppendUint(output.Bytes(), v))
|
||||
return output.Len() - old, nil
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import (
|
|||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/middleware/requestid"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
@ -424,8 +424,8 @@ func Test_CustomTags(t *testing.T) {
|
|||
app.Use(New(Config{
|
||||
Format: "${custom_tag}",
|
||||
CustomTags: map[string]LogFunc{
|
||||
"custom_tag": func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(customTag)
|
||||
"custom_tag": func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(customTag)
|
||||
},
|
||||
},
|
||||
Output: buf,
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/internal/bytebufferpool"
|
||||
)
|
||||
|
||||
// Logger variables
|
||||
|
@ -56,145 +55,145 @@ const (
|
|||
func createTagMap(cfg *Config) map[string]LogFunc {
|
||||
// Set default tags
|
||||
tagFunctions := map[string]LogFunc{
|
||||
TagReferer: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Get(fiber.HeaderReferer))
|
||||
TagReferer: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Get(fiber.HeaderReferer))
|
||||
},
|
||||
TagProtocol: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Protocol())
|
||||
TagProtocol: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Protocol())
|
||||
},
|
||||
TagPort: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Port())
|
||||
TagPort: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Port())
|
||||
},
|
||||
TagIP: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.IP())
|
||||
TagIP: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.IP())
|
||||
},
|
||||
TagIPs: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Get(fiber.HeaderXForwardedFor))
|
||||
TagIPs: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Get(fiber.HeaderXForwardedFor))
|
||||
},
|
||||
TagHost: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Hostname())
|
||||
TagHost: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Hostname())
|
||||
},
|
||||
TagPath: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Path())
|
||||
TagPath: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Path())
|
||||
},
|
||||
TagURL: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.OriginalURL())
|
||||
TagURL: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.OriginalURL())
|
||||
},
|
||||
TagUA: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Get(fiber.HeaderUserAgent))
|
||||
TagUA: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Get(fiber.HeaderUserAgent))
|
||||
},
|
||||
TagBody: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.Write(c.Body())
|
||||
TagBody: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.Write(c.Body())
|
||||
},
|
||||
TagBytesReceived: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return appendInt(buf, len(c.Request().Body()))
|
||||
TagBytesReceived: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return appendInt(output, len(c.Request().Body()))
|
||||
},
|
||||
TagBytesSent: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return appendInt(buf, len(c.Response().Body()))
|
||||
TagBytesSent: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return appendInt(output, len(c.Response().Body()))
|
||||
},
|
||||
TagRoute: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Route().Path)
|
||||
TagRoute: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Route().Path)
|
||||
},
|
||||
TagResBody: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.Write(c.Response().Body())
|
||||
TagResBody: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.Write(c.Response().Body())
|
||||
},
|
||||
TagReqHeaders: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagReqHeaders: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
reqHeaders := make([]string, 0)
|
||||
for k, v := range c.GetReqHeaders() {
|
||||
reqHeaders = append(reqHeaders, k+"="+v)
|
||||
}
|
||||
return buf.Write([]byte(strings.Join(reqHeaders, "&")))
|
||||
return output.Write([]byte(strings.Join(reqHeaders, "&")))
|
||||
},
|
||||
TagQueryStringParams: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Request().URI().QueryArgs().String())
|
||||
TagQueryStringParams: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Request().URI().QueryArgs().String())
|
||||
},
|
||||
|
||||
TagBlack: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Black)
|
||||
TagBlack: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Black)
|
||||
},
|
||||
TagRed: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Red)
|
||||
TagRed: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Red)
|
||||
},
|
||||
TagGreen: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Green)
|
||||
TagGreen: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Green)
|
||||
},
|
||||
TagYellow: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Yellow)
|
||||
TagYellow: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Yellow)
|
||||
},
|
||||
TagBlue: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Blue)
|
||||
TagBlue: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Blue)
|
||||
},
|
||||
TagMagenta: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Magenta)
|
||||
TagMagenta: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Magenta)
|
||||
},
|
||||
TagCyan: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Cyan)
|
||||
TagCyan: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Cyan)
|
||||
},
|
||||
TagWhite: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.White)
|
||||
TagWhite: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.White)
|
||||
},
|
||||
TagReset: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.App().Config().ColorScheme.Reset)
|
||||
TagReset: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.App().Config().ColorScheme.Reset)
|
||||
},
|
||||
TagError: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagError: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
if data.ChainErr != nil {
|
||||
return buf.WriteString(data.ChainErr.Error())
|
||||
return output.WriteString(data.ChainErr.Error())
|
||||
}
|
||||
return buf.WriteString("-")
|
||||
return output.WriteString("-")
|
||||
},
|
||||
TagReqHeader: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Get(extraParam))
|
||||
TagReqHeader: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Get(extraParam))
|
||||
},
|
||||
TagHeader: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Get(extraParam))
|
||||
TagHeader: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Get(extraParam))
|
||||
},
|
||||
TagRespHeader: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.GetRespHeader(extraParam))
|
||||
TagRespHeader: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.GetRespHeader(extraParam))
|
||||
},
|
||||
TagQuery: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Query(extraParam))
|
||||
TagQuery: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Query(extraParam))
|
||||
},
|
||||
TagForm: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.FormValue(extraParam))
|
||||
TagForm: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.FormValue(extraParam))
|
||||
},
|
||||
TagCookie: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(c.Cookies(extraParam))
|
||||
TagCookie: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(c.Cookies(extraParam))
|
||||
},
|
||||
TagLocals: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagLocals: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
switch v := c.Locals(extraParam).(type) {
|
||||
case []byte:
|
||||
return buf.Write(v)
|
||||
return output.Write(v)
|
||||
case string:
|
||||
return buf.WriteString(v)
|
||||
return output.WriteString(v)
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
return buf.WriteString(fmt.Sprintf("%v", v))
|
||||
return output.WriteString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
},
|
||||
TagStatus: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagStatus: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
if cfg.enableColors {
|
||||
colors := c.App().Config().ColorScheme
|
||||
return buf.WriteString(fmt.Sprintf("%s %3d %s", statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset))
|
||||
return output.WriteString(fmt.Sprintf("%s %3d %s", statusColor(c.Response().StatusCode(), colors), c.Response().StatusCode(), colors.Reset))
|
||||
}
|
||||
return appendInt(buf, c.Response().StatusCode())
|
||||
return appendInt(output, c.Response().StatusCode())
|
||||
},
|
||||
TagMethod: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagMethod: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
if cfg.enableColors {
|
||||
colors := c.App().Config().ColorScheme
|
||||
return buf.WriteString(fmt.Sprintf("%s %-7s %s", methodColor(c.Method(), colors), c.Method(), colors.Reset))
|
||||
return output.WriteString(fmt.Sprintf("%s %-7s %s", methodColor(c.Method(), colors), c.Method(), colors.Reset))
|
||||
}
|
||||
return buf.WriteString(c.Method())
|
||||
return output.WriteString(c.Method())
|
||||
},
|
||||
TagPid: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(data.Pid)
|
||||
TagPid: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(data.Pid)
|
||||
},
|
||||
TagLatency: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
TagLatency: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
latency := data.Stop.Sub(data.Start).Round(time.Millisecond)
|
||||
return buf.WriteString(fmt.Sprintf("%7v", latency))
|
||||
return output.WriteString(fmt.Sprintf("%7v", latency))
|
||||
},
|
||||
TagTime: func(buf *bytebufferpool.ByteBuffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return buf.WriteString(data.Timestamp.Load().(string))
|
||||
TagTime: func(output Buffer, c *fiber.Ctx, data *Data, extraParam string) (int, error) {
|
||||
return output.WriteString(data.Timestamp.Load().(string))
|
||||
},
|
||||
}
|
||||
// merge with custom tags from user
|
||||
|
|
Loading…
Reference in New Issue