1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-03 02:07:06 +00:00

accesslog: improvements and new features

relative to: #1601 and #1624
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-09-13 02:56:22 +03:00
parent 7d5789c3de
commit 4845b77177
16 changed files with 612 additions and 261 deletions

View File

@@ -1,54 +1,50 @@
package accesslog
import (
"encoding/json"
"io"
"sync"
"strings"
jsoniter "github.com/json-iterator/go"
)
// JSON is a Formatter type for JSON logs.
type JSON struct {
Prefix, Indent string
EscapeHTML bool
// Indent in spaces.
// Note that, if set to > 0 then jsoniter is used instead of easyjson.
Indent string
EscapeHTML bool
enc *json.Encoder
mu sync.Mutex
lockEncoder bool
jsoniter jsoniter.API
ac *AccessLog
}
// 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
f.ac, _ = dest.(*AccessLog)
if indentStep := strings.Count(f.Indent, " "); indentStep > 0 {
f.jsoniter = jsoniter.Config{
TagKey: "json",
IndentionStep: indentStep,
EscapeHTML: f.EscapeHTML,
SortMapKeys: true,
}.Froze()
}
// 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.lockEncoder = f.Prefix != "" || f.Indent != ""
f.enc = enc
}
// Format prints the logs in JSON format.
// Writes to the destination directly,
// locks on each Format call.
func (f *JSON) Format(log *Log) (bool, error) {
// f.mu.Lock()
// ^ This lock is not required as the writer is
// protected with mutex if necessary or configurated to do so.
// However, if we navigate through the
// internal encoding's source code we'll see that it
// uses a field for its indent buffer,
// therefore it's only useful when Prefix or Indent was not empty.
if f.lockEncoder {
f.mu.Lock()
}
err := f.enc.Encode(log)
if f.lockEncoder {
f.mu.Unlock()
if f.jsoniter != nil {
b, err := f.jsoniter.Marshal(log)
if err != nil {
return true, err
}
f.ac.Write(append(b, newLine))
return true, nil
}
err := f.writeEasyJSON(log)
return true, err
}