accesslog: new HumanTime option as requested at #1661

This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-10-16 09:53:22 +03:00
parent 8e51a296b9
commit b816156e77
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
2 changed files with 52 additions and 4 deletions

View File

@ -1,7 +1,9 @@
package accesslog
import (
"bytes"
"io"
"strconv"
"strings"
jsoniter "github.com/json-iterator/go"
@ -13,6 +15,7 @@ type JSON struct {
// Note that, if set to > 0 then jsoniter is used instead of easyjson.
Indent string
EscapeHTML bool
HumanTime bool
jsoniter jsoniter.API
ac *AccessLog
@ -23,6 +26,8 @@ type JSON struct {
func (f *JSON) SetOutput(dest io.Writer) {
f.ac, _ = dest.(*AccessLog)
if indentStep := strings.Count(f.Indent, " "); indentStep > 0 {
// Note that: indent setting should always be spaces
// as the jsoniter does not support other chars.
f.jsoniter = jsoniter.Config{
TagKey: "json",
IndentionStep: indentStep,
@ -32,15 +37,52 @@ func (f *JSON) SetOutput(dest io.Writer) {
}
}
var (
timestampKeyB = []byte(`"timestamp":`)
timestampKeyIndentB = append(timestampKeyB, ' ')
timestampKeyVB = append(timestampKeyB, '0')
timestampIndentKeyVB = append(timestampKeyIndentB, '0')
)
// 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) {
if f.jsoniter != nil {
if f.HumanTime {
// 1. Don't write the unix timestamp,
// key will be visible though as we don't omit the field.
log.Timestamp = 0
}
b, err := f.jsoniter.Marshal(log)
if err != nil {
return true, err
}
if f.HumanTime {
// 2. Get the time text based on the configuration.
t := log.Now.Format(log.TimeFormat)
// 3. Find the "timestamp:$indent"
// and set it to the text one.
var (
oldT []byte
tsKey []byte
)
if f.Indent != "" {
oldT = timestampIndentKeyVB
tsKey = timestampKeyIndentB
} else {
oldT = timestampKeyVB
tsKey = timestampKeyB
}
newT := append(tsKey, strconv.Quote(t)...)
b = bytes.Replace(b, oldT, newT, 1)
}
f.ac.Write(append(b, newLine))
return true, nil
}

View File

@ -25,7 +25,13 @@ func (f *JSON) writeEasyJSON(in *Log) error {
} else {
out.RawString(prefix)
}
out.Int64(int64(in.Timestamp))
if f.HumanTime {
t := in.Now.Format(in.TimeFormat)
out.String(t)
} else {
out.Int64(in.Timestamp)
}
}
{
const prefix string = ",\"latency\":"
@ -40,17 +46,17 @@ func (f *JSON) writeEasyJSON(in *Log) error {
{
const prefix string = ",\"method\":"
out.RawString(prefix)
out.String(string(in.Method))
out.String(in.Method)
}
{
const prefix string = ",\"path\":"
out.RawString(prefix)
out.String(string(in.Path))
out.String(in.Path)
}
if in.IP != "" {
const prefix string = ",\"ip\":"
out.RawString(prefix)
out.String(string(in.IP))
out.String(in.IP)
}
if len(in.Query) != 0 {
const prefix string = ",\"query\":"