mirror of
https://github.com/kataras/iris.git
synced 2026-01-10 05:25:58 +00:00
improvements on the new accesslog middleware
relative to: https://github.com/kataras/iris/issues/1601
This commit is contained in:
94
middleware/accesslog/log.go
Normal file
94
middleware/accesslog/log.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package accesslog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12/context"
|
||||
"github.com/kataras/iris/v12/core/memstore"
|
||||
)
|
||||
|
||||
// Log represents the log data specifically for the accesslog middleware.
|
||||
type Log struct {
|
||||
// The AccessLog instance this Log was created of.
|
||||
Logger *AccessLog `json:"-"`
|
||||
|
||||
// The time the log is created.
|
||||
Now time.Time `json:"-"`
|
||||
// Timestamp the Now's unix timestamp (seconds).
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
|
||||
// Request-Response latency.
|
||||
Latency time.Duration `json:"latency"`
|
||||
// Init request's Method and Path.
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
// Sorted URL Query arguments.
|
||||
Query []memstore.StringEntry
|
||||
// Dynamic path parameters.
|
||||
PathParams []memstore.Entry
|
||||
// Fields any data information useful to represent this Log.
|
||||
Fields context.Map `json:"fields,omitempty"`
|
||||
|
||||
// The Request and Response raw bodies.
|
||||
// If they are escaped (e.g. JSON),
|
||||
// A third-party software can read it through:
|
||||
// data, _ := strconv.Unquote(log.Request)
|
||||
// err := json.Unmarshal([]byte(data), &customStruct)
|
||||
Request string `json:"request"`
|
||||
Response string `json:"response"`
|
||||
|
||||
// A copy of the Request's Context when Async is true (safe to use concurrently),
|
||||
// otherwise it's the current Context (not safe for concurrent access).
|
||||
Ctx *context.Context `json:"-"`
|
||||
}
|
||||
|
||||
// Formatter is responsible to print a Log to the accesslog's writer.
|
||||
type Formatter interface {
|
||||
// Format should print the Log.
|
||||
// Returns true on handle successfully,
|
||||
// otherwise the log will be printed using the default formatter.
|
||||
Format(log *Log) bool
|
||||
// SetWriter should inject the accesslog's output.
|
||||
SetOutput(dest io.Writer)
|
||||
}
|
||||
|
||||
// JSON is a Formatter type for JSON logs.
|
||||
type JSON struct {
|
||||
Prefix, Indent string
|
||||
EscapeHTML bool
|
||||
|
||||
enc *json.Encoder
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// SetOutput creates the json encoder writes to the "dest".
|
||||
// It's called automatically by the middleware when this Formatter is used.
|
||||
func (f *JSON) SetOutput(dest io.Writer) {
|
||||
if dest == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// All logs share the same accesslog's writer and it cannot change during serve-time.
|
||||
enc := json.NewEncoder(dest)
|
||||
enc.SetEscapeHTML(f.EscapeHTML)
|
||||
enc.SetIndent(f.Prefix, f.Indent)
|
||||
f.enc = enc
|
||||
}
|
||||
|
||||
// Format prints the logs in JSON format.
|
||||
func (f *JSON) Format(log *Log) bool {
|
||||
f.mu.Lock()
|
||||
if f.enc == nil {
|
||||
// If no custom writer is given then f.enc is nil,
|
||||
// this code block should only be executed once.
|
||||
// Also, the app's logger's writer cannot change during serve-time,
|
||||
// so all logs share the same instance output.
|
||||
f.SetOutput(log.Ctx.Application().Logger().Printer)
|
||||
}
|
||||
err := f.enc.Encode(log)
|
||||
f.mu.Unlock()
|
||||
return err == nil
|
||||
}
|
||||
Reference in New Issue
Block a user