log/formatter_keyvalue.go

87 lines
2.1 KiB
Go

// Copyright 2023 Martin Riedl
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package golog
import (
"fmt"
"strings"
"time"
)
type FormatterKeyValue struct {
TimeFormat string
builder strings.Builder
isFirstKVWritten bool
}
func NewFormatterKeyValue() *FormatterKeyValue {
return &FormatterKeyValue{
TimeFormat: time.RFC3339,
}
}
func (formatter *FormatterKeyValue) Begin(entry *Entry) {
// reset builder
formatter.builder.Reset()
// add timestamp
formatter.addKV("time", entry.Time.Format(formatter.TimeFormat))
// add loglevel
formatter.addKV("level", entry.Level.String())
}
func (formatter *FormatterKeyValue) Process(entry *Entry) {
// add message
formatter.addKV("message", entry.Message)
// add call stack
if len(entry.CallStack) > 0 {
caller := entry.CallStack[0]
formatter.addKV("file", fmt.Sprintf("%s:%d", caller.File, caller.Line))
formatter.addKV("function", caller.Function)
}
// add additional fields
for _, content := range entry.Content {
formatter.addKV(content.Key, content.Value)
}
}
func (formatter *FormatterKeyValue) addKV(key string, value any) {
// convert any to string
val := fmt.Sprintf("%v", value)
// check, if value should be escaped
if strings.ContainsAny(val, " \t\n\r=:\\") {
val = fmt.Sprintf("%q", val)
}
// add space, if required
if formatter.isFirstKVWritten {
formatter.builder.WriteString(" ")
}
formatter.isFirstKVWritten = true
// add field
formatter.builder.WriteString(key)
formatter.builder.WriteString("=")
formatter.builder.WriteString(val)
}
func (formatter *FormatterKeyValue) End(entry *Entry) []byte {
// send data
return []byte(formatter.builder.String())
}