mirror of
https://github.com/kataras/iris.git
synced 2026-01-03 02:07:06 +00:00
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user