diff options
author | 2021-11-27 15:26:58 +0100 | |
---|---|---|
committer | 2021-11-27 15:26:58 +0100 | |
commit | 182b4eea73881c611a0f519576aa6ad2aa6799c2 (patch) | |
tree | 230fac469690fcee8797b13585e739be148d4789 /vendor/codeberg.org/gruf/go-logger | |
parent | Require confirmed email when checking oauth token (#332) (diff) | |
download | gotosocial-182b4eea73881c611a0f519576aa6ad2aa6799c2.tar.xz |
Update dependencies (#333)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-logger')
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/clock.go | 2 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/default.go | 30 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/entry.go | 29 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/format.go | 650 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/format_text.go | 915 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/level.go | 10 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/logger.go | 2 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/writer.go | 29 |
8 files changed, 1040 insertions, 627 deletions
diff --git a/vendor/codeberg.org/gruf/go-logger/clock.go b/vendor/codeberg.org/gruf/go-logger/clock.go index 5e6f877f0..aed97c339 100644 --- a/vendor/codeberg.org/gruf/go-logger/clock.go +++ b/vendor/codeberg.org/gruf/go-logger/clock.go @@ -12,7 +12,7 @@ var ( clockOnce = sync.Once{} ) -// startClock starts the global nowish clock +// startClock starts the global nowish clock. func startClock() { clockOnce.Do(func() { clock.Start(time.Millisecond * 10) diff --git a/vendor/codeberg.org/gruf/go-logger/default.go b/vendor/codeberg.org/gruf/go-logger/default.go index e2932e733..0da1f6a66 100644 --- a/vendor/codeberg.org/gruf/go-logger/default.go +++ b/vendor/codeberg.org/gruf/go-logger/default.go @@ -10,78 +10,78 @@ var ( instanceOnce = sync.Once{} ) -// Default returns the default Logger instance +// Default returns the default Logger instance. func Default() *Logger { instanceOnce.Do(func() { instance = New(os.Stdout) }) return instance } -// Debug prints the provided arguments with the debug prefix to the global Logger instance +// Debug prints the provided arguments with the debug prefix to the global Logger instance. func Debug(a ...interface{}) { Default().Debug(a...) } -// Debugf prints the provided format string and arguments with the debug prefix to the global Logger instance +// Debugf prints the provided format string and arguments with the debug prefix to the global Logger instance. func Debugf(s string, a ...interface{}) { Default().Debugf(s, a...) } -// Info prints the provided arguments with the info prefix to the global Logger instance +// Info prints the provided arguments with the info prefix to the global Logger instance. func Info(a ...interface{}) { Default().Info(a...) } -// Infof prints the provided format string and arguments with the info prefix to the global Logger instance +// Infof prints the provided format string and arguments with the info prefix to the global Logger instance. func Infof(s string, a ...interface{}) { Default().Infof(s, a...) } -// Warn prints the provided arguments with the warn prefix to the global Logger instance +// Warn prints the provided arguments with the warn prefix to the global Logger instance. func Warn(a ...interface{}) { Default().Warn(a...) } -// Warnf prints the provided format string and arguments with the warn prefix to the global Logger instance +// Warnf prints the provided format string and arguments with the warn prefix to the global Logger instance. func Warnf(s string, a ...interface{}) { Default().Warnf(s, a...) } -// Error prints the provided arguments with the error prefix to the global Logger instance +// Error prints the provided arguments with the error prefix to the global Logger instance. func Error(a ...interface{}) { Default().Error(a...) } -// Errorf prints the provided format string and arguments with the error prefix to the global Logger instance +// Errorf prints the provided format string and arguments with the error prefix to the global Logger instance. func Errorf(s string, a ...interface{}) { Default().Errorf(s, a...) } -// Fatal prints the provided arguments with the fatal prefix to the global Logger instance before exiting the program with os.Exit(1) +// Fatal prints the provided arguments with the fatal prefix to the global Logger instance before exiting the program with os.Exit(1). func Fatal(a ...interface{}) { Default().Fatal(a...) } -// Fatalf prints the provided format string and arguments with the fatal prefix to the global Logger instance before exiting the program with os.Exit(1) +// Fatalf prints the provided format string and arguments with the fatal prefix to the global Logger instance before exiting the program with os.Exit(1). func Fatalf(s string, a ...interface{}) { Default().Fatalf(s, a...) } -// Log prints the provided arguments with the supplied log level to the global Logger instance +// Log prints the provided arguments with the supplied log level to the global Logger instance. func Log(lvl LEVEL, a ...interface{}) { Default().Log(lvl, a...) } -// Logf prints the provided format string and arguments with the supplied log level to the global Logger instance +// Logf prints the provided format string and arguments with the supplied log level to the global Logger instance. func Logf(lvl LEVEL, s string, a ...interface{}) { Default().Logf(lvl, s, a...) } -// Print simply prints provided arguments to the global Logger instance +// Print simply prints provided arguments to the global Logger instance. func Print(a ...interface{}) { Default().Print(a...) } -// Printf simply prints provided the provided format string and arguments to the global Logger instance +// Printf simply prints provided the provided format string and arguments to the global Logger instance. func Printf(s string, a ...interface{}) { Default().Printf(s, a...) } diff --git a/vendor/codeberg.org/gruf/go-logger/entry.go b/vendor/codeberg.org/gruf/go-logger/entry.go index f2fe293aa..aad4b4885 100644 --- a/vendor/codeberg.org/gruf/go-logger/entry.go +++ b/vendor/codeberg.org/gruf/go-logger/entry.go @@ -7,7 +7,7 @@ import ( "codeberg.org/gruf/go-bytes" ) -// Entry defines an entry in the log +// Entry defines an entry in the log, it is NOT safe for concurrent use type Entry struct { ctx context.Context lvl LEVEL @@ -187,13 +187,34 @@ func (e *Entry) Fields(fields map[string]interface{}) *Entry { return e } -// Msg appends the formatted final message to the log and calls .Send() +// Value appends the given value to the log entry formatted as a value, without a key. +func (e *Entry) Value(value interface{}) *Entry { + e.log.Format.AppendValue(e.buf, value) + e.buf.WriteByte(' ') + return e +} + +// Values appends the given values to the log entry formatted as values, without a key. +func (e *Entry) Values(values ...interface{}) *Entry { + e.log.Format.AppendValues(e.buf, values) + e.buf.WriteByte(' ') + return e +} + +// Args appends the given args formatted using the log formatter (usually faster than printf) without any key-value / value formatting. +func (e *Entry) Args(a ...interface{}) *Entry { + e.log.Format.AppendArgs(e.buf, a) + e.buf.WriteByte(' ') + return e +} + +// Msg appends the fmt.Sprint() formatted final message to the log and calls .Send() func (e *Entry) Msg(a ...interface{}) { e.log.Format.AppendMsg(e.buf, a...) e.Send() } -// Msgf appends the formatted final message to the log and calls .Send() +// Msgf appends the fmt.Sprintf() formatted final message to the log and calls .Send() func (e *Entry) Msgf(s string, a ...interface{}) { e.log.Format.AppendMsgf(e.buf, s, a...) e.Send() @@ -210,7 +231,7 @@ func (e *Entry) Send() { return } - // Final new line + // Ensure a final new line if e.buf.B[e.buf.Len()-1] != '\n' { e.buf.WriteByte('\n') } diff --git a/vendor/codeberg.org/gruf/go-logger/format.go b/vendor/codeberg.org/gruf/go-logger/format.go index 214773ff3..234cf0b2c 100644 --- a/vendor/codeberg.org/gruf/go-logger/format.go +++ b/vendor/codeberg.org/gruf/go-logger/format.go @@ -1,9 +1,6 @@ package logger import ( - "fmt" - "reflect" - "strconv" "time" "codeberg.org/gruf/go-bytes" @@ -14,627 +11,78 @@ var _ LogFormat = &TextFormat{} // LogFormat defines a method of formatting log entries type LogFormat interface { + // AppendLevel appends given log level to the log buffer AppendLevel(buf *bytes.Buffer, lvl LEVEL) - AppendTimestamp(buf *bytes.Buffer, fmtNow string) - AppendField(buf *bytes.Buffer, key string, value interface{}) - AppendFields(buf *bytes.Buffer, fields map[string]interface{}) - AppendByteField(buf *bytes.Buffer, key string, value byte) - AppendBytesField(buf *bytes.Buffer, key string, value []byte) - AppendStringField(buf *bytes.Buffer, key string, value string) - AppendStringsField(buf *bytes.Buffer, key string, value []string) - AppendBoolField(buf *bytes.Buffer, key string, value bool) - AppendBoolsField(buf *bytes.Buffer, key string, value []bool) - AppendIntField(buf *bytes.Buffer, key string, value int) - AppendIntsField(buf *bytes.Buffer, key string, value []int) - AppendUintField(buf *bytes.Buffer, key string, value uint) - AppendUintsField(buf *bytes.Buffer, key string, value []uint) - AppendFloatField(buf *bytes.Buffer, key string, value float64) - AppendFloatsField(buf *bytes.Buffer, key string, value []float64) - AppendTimeField(buf *bytes.Buffer, key string, value time.Time) - AppendTimesField(buf *bytes.Buffer, key string, value []time.Time) - AppendDurationField(buf *bytes.Buffer, key string, value time.Duration) - AppendDurationsField(buf *bytes.Buffer, key string, value []time.Duration) - AppendMsg(buf *bytes.Buffer, a ...interface{}) - AppendMsgf(buf *bytes.Buffer, s string, a ...interface{}) -} - -// TextFormat is the default LogFormat implementation, with very similar formatting to logfmt -type TextFormat struct { - // Strict defines whether to use strict key-value pair formatting, - // i.e. should the level, timestamp and msg be formatted as key-value pairs - // or simply be printed as-is - Strict bool - - // Levels defines the map of log LEVELs to level strings this LogFormat will use - Levels Levels -} - -// NewLogFmt returns a newly set LogFmt object, with DefaultLevels() set -func NewLogFmt(strict bool) *TextFormat { - return &TextFormat{ - Strict: strict, - Levels: DefaultLevels(), - } -} - -// appendReflectValue will safely append a reflected value -func appendReflectValue(buf *bytes.Buffer, v reflect.Value, isKey bool) { - switch v.Kind() { - case reflect.Slice: - appendSliceType(buf, v) - case reflect.Map: - appendMapType(buf, v) - case reflect.Struct: - appendStructType(buf, v) - case reflect.Ptr: - if v.IsNil() { - appendNil(buf) - } else { - appendIface(buf, v.Elem().Interface(), isKey) - } - default: - // Just print reflect string - appendString(buf, v.String()) - } -} - -// appendKey should only be used in the case of directly setting key-value pairs, -// not in the case of appendMapType, appendStructType -func appendKey(buf *bytes.Buffer, key string) { - if len(key) > 0 { - // Only write key if here - appendStringUnquoted(buf, key) - buf.WriteByte('=') - } -} - -// appendSlice performs provided fn and writes square brackets [] around it -func appendSlice(buf *bytes.Buffer, fn func()) { - buf.WriteByte('[') - fn() - buf.WriteByte(']') -} - -// appendMap performs provided fn and writes curly braces {} around it -func appendMap(buf *bytes.Buffer, fn func()) { - buf.WriteByte('{') - fn() - buf.WriteByte('}') -} - -// appendStruct performs provided fn and writes curly braces {} around it -func appendStruct(buf *bytes.Buffer, fn func()) { - buf.WriteByte('{') - fn() - buf.WriteByte('}') -} - -// appendNil writes a nil value placeholder to buf -func appendNil(buf *bytes.Buffer) { - buf.WriteString(`<nil>`) -} - -// appendByte writes a single byte to buf -func appendByte(buf *bytes.Buffer, b byte) { - buf.WriteByte(b) -} - -// appendBytes writes a quoted byte slice to buf -func appendBytes(buf *bytes.Buffer, b []byte) { - buf.WriteByte('"') - buf.Write(b) - buf.WriteByte('"') -} - -// appendBytesUnquoted writes a byte slice to buf as-is -func appendBytesUnquoted(buf *bytes.Buffer, b []byte) { - buf.Write(b) -} - -// appendString writes a quoted string to buf -func appendString(buf *bytes.Buffer, s string) { - buf.WriteByte('"') - buf.WriteString(s) - buf.WriteByte('"') -} - -// appendStringUnquoted writes a string as-is to buf -func appendStringUnquoted(buf *bytes.Buffer, s string) { - buf.WriteString(s) -} - -// appendStringSlice writes a slice of strings to buf -func appendStringSlice(buf *bytes.Buffer, s []string) { - appendSlice(buf, func() { - for _, s := range s { - appendString(buf, s) - buf.WriteByte(',') - } - if len(s) > 0 { - buf.Truncate(1) - } - }) -} - -// appendBool writes a formatted bool to buf -func appendBool(buf *bytes.Buffer, b bool) { - buf.B = strconv.AppendBool(buf.B, b) -} - -// appendBool writes a slice of formatted bools to buf -func appendBoolSlice(buf *bytes.Buffer, b []bool) { - appendSlice(buf, func() { - // Write elements - for _, b := range b { - appendBool(buf, b) - buf.WriteByte(',') - } - - // Drop last comma - if len(b) > 0 { - buf.Truncate(1) - } - }) -} - -// appendInt writes a formatted int to buf -func appendInt(buf *bytes.Buffer, i int64) { - buf.B = strconv.AppendInt(buf.B, i, 10) -} - -// appendIntSlice writes a slice of formatted int to buf -func appendIntSlice(buf *bytes.Buffer, i []int) { - appendSlice(buf, func() { - // Write elements - for _, i := range i { - appendInt(buf, int64(i)) - buf.WriteByte(',') - } - - // Drop last comma - if len(i) > 0 { - buf.Truncate(1) - } - }) -} - -// appendUint writes a formatted uint to buf -func appendUint(buf *bytes.Buffer, u uint64) { - buf.B = strconv.AppendUint(buf.B, u, 10) -} - -// appendUintSlice writes a slice of formatted uint to buf -func appendUintSlice(buf *bytes.Buffer, u []uint) { - appendSlice(buf, func() { - // Write elements - for _, u := range u { - appendUint(buf, uint64(u)) - buf.WriteByte(',') - } - - // Drop last comma - if len(u) > 0 { - buf.Truncate(1) - } - }) -} - -// appendFloat writes a formatted float to buf -func appendFloat(buf *bytes.Buffer, f float64) { - buf.B = strconv.AppendFloat(buf.B, f, 'G', -1, 64) -} - -// appendFloatSlice writes a slice formatted floats to buf -func appendFloatSlice(buf *bytes.Buffer, f []float64) { - appendSlice(buf, func() { - // Write elements - for _, f := range f { - appendFloat(buf, f) - buf.WriteByte(',') - } - - // Drop last comma - if len(f) > 0 { - buf.Truncate(1) - } - }) -} - -// appendTime writes a formatted, quoted time string to buf -func appendTime(buf *bytes.Buffer, t time.Time) { - buf.WriteByte('"') - buf.B = t.AppendFormat(buf.B, time.RFC1123) - buf.WriteByte('"') -} - -// appendTimeUnquoted writes a formatted time string to buf as-is -func appendTimeUnquoted(buf *bytes.Buffer, t time.Time) { - buf.B = t.AppendFormat(buf.B, time.RFC1123) -} -// appendTimeSlice writes a slice of formatted time strings to buf -func appendTimeSlice(buf *bytes.Buffer, t []time.Time) { - appendSlice(buf, func() { - // Write elements - for _, t := range t { - appendTime(buf, t) - buf.WriteByte(',') - } - - // Drop last comma - if len(t) > 0 { - buf.Truncate(1) - } - }) -} - -// appendDuration writes a formatted, quoted duration string to buf -func appendDuration(buf *bytes.Buffer, d time.Duration) { - appendString(buf, d.String()) -} - -// appendDurationUnquoted writes a formatted duration string to buf as-is -func appendDurationUnquoted(buf *bytes.Buffer, d time.Duration) { - appendStringUnquoted(buf, d.String()) -} - -// appendDurationSlice writes a slice of formatted, quoted duration strings to buf -func appendDurationSlice(buf *bytes.Buffer, d []time.Duration) { - appendSlice(buf, func() { - // Write elements - for _, d := range d { - appendString(buf, d.String()) - buf.WriteByte(',') - } - - // Drop last comma - if len(d) > 0 { - buf.Truncate(1) - } - }) -} - -// appendIface parses and writes a formatted interface value to buf -func appendIface(buf *bytes.Buffer, i interface{}, isKey bool) { - switch i := i.(type) { - case nil: - appendNil(buf) - case byte: - appendByte(buf, i) - case []byte: - if isKey { - // Keys don't get quoted - appendBytesUnquoted(buf, i) - } else { - appendBytes(buf, i) - } - case string: - if isKey { - // Keys don't get quoted - appendStringUnquoted(buf, i) - } else { - appendString(buf, i) - } - case []string: - appendStringSlice(buf, i) - case int: - appendInt(buf, int64(i)) - case int8: - appendInt(buf, int64(i)) - case int16: - appendInt(buf, int64(i)) - case int32: - appendInt(buf, int64(i)) - case int64: - appendInt(buf, i) - case []int: - appendIntSlice(buf, i) - case uint: - appendUint(buf, uint64(i)) - case uint16: - appendUint(buf, uint64(i)) - case uint32: - appendUint(buf, uint64(i)) - case uint64: - appendUint(buf, i) - case []uint: - appendUintSlice(buf, i) - case float32: - appendFloat(buf, float64(i)) - case float64: - appendFloat(buf, i) - case []float64: - appendFloatSlice(buf, i) - case bool: - appendBool(buf, i) - case []bool: - appendBoolSlice(buf, i) - case time.Time: - if isKey { - // Keys don't get quoted - appendTimeUnquoted(buf, i) - } else { - appendTime(buf, i) - } - case *time.Time: - if isKey { - // Keys don't get quoted - appendTimeUnquoted(buf, *i) - } else { - appendTime(buf, *i) - } - case []time.Time: - appendTimeSlice(buf, i) - case time.Duration: - if isKey { - // Keys dont get quoted - appendDurationUnquoted(buf, i) - } else { - appendDuration(buf, i) - } - case []time.Duration: - appendDurationSlice(buf, i) - case map[string]interface{}: - appendIfaceMap(buf, i) - case error: - if isKey { - // Keys don't get quoted - appendStringUnquoted(buf, i.Error()) - } else { - appendString(buf, i.Error()) - } - case fmt.Stringer: - if isKey { - // Keys don't get quoted - appendStringUnquoted(buf, i.String()) - } else { - appendString(buf, i.String()) - } - default: - // If we reached here, we need reflection. - appendReflectValue(buf, reflect.ValueOf(i), isKey) - } -} - -// appendIfaceMap writes a map of key-value pairs (as a set of fields) to buf -func appendIfaceMap(buf *bytes.Buffer, v map[string]interface{}) { - appendMap(buf, func() { - // Write map pairs! - for key, value := range v { - appendStringUnquoted(buf, key) - buf.WriteByte('=') - appendIface(buf, value, false) - buf.WriteByte(' ') - } - - // Drop last space - if len(v) > 0 { - buf.Truncate(1) - } - }) -} - -// appendSliceType writes a slice of unknown type (parsed by reflection) to buf -func appendSliceType(buf *bytes.Buffer, v reflect.Value) { - n := v.Len() - appendSlice(buf, func() { - for i := 0; i < n; i++ { - appendIface(buf, v.Index(i).Interface(), false) - buf.WriteByte(',') - } - - // Drop last comma - if n > 0 { - buf.Truncate(1) - } - }) -} - -// appendMapType writes a map of unknown types (parsed by reflection) to buf -func appendMapType(buf *bytes.Buffer, v reflect.Value) { - // Get a map iterator - r := v.MapRange() - n := v.Len() - - // Now begin creating the map! - appendMap(buf, func() { - // Iterate pairs - for r.Next() { - appendIface(buf, r.Key().Interface(), true) - buf.WriteByte('=') - appendIface(buf, r.Value().Interface(), false) - buf.WriteByte(' ') - } - - // Drop last space - if n > 0 { - buf.Truncate(1) - } - }) -} - -// appendStructType writes a struct (as a set of key-value fields) to buf -func appendStructType(buf *bytes.Buffer, v reflect.Value) { - // Get value type & no. fields - t := v.Type() - n := v.NumField() - w := 0 - - // Iter and write struct fields - appendStruct(buf, func() { - for i := 0; i < n; i++ { - vfield := v.Field(i) - - // Check for unexported fields - if !vfield.CanInterface() { - continue - } - - // Append the struct member as field key-value - appendStringUnquoted(buf, t.Field(i).Name) - buf.WriteByte('=') - appendIface(buf, vfield.Interface(), false) - buf.WriteByte(' ') - - // Iter written count - w++ - } - - // Drop last space - if w > 0 { - buf.Truncate(1) - } - }) -} - -func (f *TextFormat) AppendLevel(buf *bytes.Buffer, lvl LEVEL) { - if f.Strict { - // Strict format, append level key - buf.WriteString(`level=`) - buf.WriteString(f.Levels.LevelString(lvl)) - return - } - - // Write level string - buf.WriteByte('[') - buf.WriteString(f.Levels.LevelString(lvl)) - buf.WriteByte(']') -} - -func (f *TextFormat) AppendTimestamp(buf *bytes.Buffer, now string) { - if f.Strict { - // Strict format, use key and quote - appendStringUnquoted(buf, `time`) - buf.WriteByte('=') - appendString(buf, now) - return - } - - // Write time as-is - appendStringUnquoted(buf, now) -} + // AppendTimestamp appends given time format string to the log buffer + AppendTimestamp(buf *bytes.Buffer, fmtNow string) -func (f *TextFormat) AppendField(buf *bytes.Buffer, key string, value interface{}) { - appendKey(buf, key) - appendIface(buf, value, false) -} + // AppendField appends given key-value pair to the log buffer + AppendField(buf *bytes.Buffer, key string, value interface{}) -func (f *TextFormat) AppendFields(buf *bytes.Buffer, fields map[string]interface{}) { - // Append individual fields - for key, value := range fields { - appendKey(buf, key) - appendIface(buf, value, false) - buf.WriteByte(' ') - } + // AppendFields appends given key-values pairs to the log buffer + AppendFields(buf *bytes.Buffer, fields map[string]interface{}) - // Drop last space - if len(fields) > 0 { - buf.Truncate(1) - } -} + // AppendValue appends given interface formatted as value to the log buffer + AppendValue(buf *bytes.Buffer, value interface{}) -func (f *TextFormat) AppendByteField(buf *bytes.Buffer, key string, value byte) { - appendKey(buf, key) - appendByte(buf, value) -} + // AppendValues appends given interfaces formatted as values to the log buffer + AppendValues(buf *bytes.Buffer, slice []interface{}) -func (f *TextFormat) AppendBytesField(buf *bytes.Buffer, key string, value []byte) { - appendKey(buf, key) - appendBytes(buf, value) -} + // AppendArgs appends given interfaces raw to the log buffer + AppendArgs(buf *bytes.Buffer, args []interface{}) -func (f *TextFormat) AppendStringField(buf *bytes.Buffer, key string, value string) { - appendKey(buf, key) - appendString(buf, value) -} + // AppendByteField appends given byte value as key-value pair to the log buffer + AppendByteField(buf *bytes.Buffer, key string, value byte) -func (f *TextFormat) AppendStringsField(buf *bytes.Buffer, key string, value []string) { - appendKey(buf, key) - appendStringSlice(buf, value) -} + // AppendBytesField appends given byte slice value as key-value pair to the log buffer + AppendBytesField(buf *bytes.Buffer, key string, value []byte) -func (f *TextFormat) AppendBoolField(buf *bytes.Buffer, key string, value bool) { - appendKey(buf, key) - appendBool(buf, value) -} + // AppendStringField appends given string value as key-value pair to the log buffer + AppendStringField(buf *bytes.Buffer, key string, value string) -func (f *TextFormat) AppendBoolsField(buf *bytes.Buffer, key string, value []bool) { - appendKey(buf, key) - appendBoolSlice(buf, value) -} + // AppendStringsField appends given string slice value as key-value pair to the log buffer + AppendStringsField(buf *bytes.Buffer, key string, value []string) -func (f *TextFormat) AppendIntField(buf *bytes.Buffer, key string, value int) { - appendKey(buf, key) - appendInt(buf, int64(value)) -} + // AppendBoolField appends given bool value as key-value pair to the log buffer + AppendBoolField(buf *bytes.Buffer, key string, value bool) -func (f *TextFormat) AppendIntsField(buf *bytes.Buffer, key string, value []int) { - appendKey(buf, key) - appendIntSlice(buf, value) -} + // AppendBoolsField appends given bool slice value as key-value pair to the log buffer + AppendBoolsField(buf *bytes.Buffer, key string, value []bool) -func (f *TextFormat) AppendUintField(buf *bytes.Buffer, key string, value uint) { - appendKey(buf, key) - appendUint(buf, uint64(value)) -} + // AppendIntField appends given int value as key-value pair to the log buffer + AppendIntField(buf *bytes.Buffer, key string, value int) -func (f *TextFormat) AppendUintsField(buf *bytes.Buffer, key string, value []uint) { - appendKey(buf, key) - appendUintSlice(buf, value) -} + // AppendIntsField appends given int slice value as key-value pair to the log buffer + AppendIntsField(buf *bytes.Buffer, key string, value []int) -func (f *TextFormat) AppendFloatField(buf *bytes.Buffer, key string, value float64) { - appendKey(buf, key) - appendFloat(buf, value) -} + // AppendUintField appends given uint value as key-value pair to the log buffer + AppendUintField(buf *bytes.Buffer, key string, value uint) -func (f *TextFormat) AppendFloatsField(buf *bytes.Buffer, key string, value []float64) { - appendKey(buf, key) - appendFloatSlice(buf, value) -} + // AppendUintsField appends given uint slice value as key-value pair to the log buffer + AppendUintsField(buf *bytes.Buffer, key string, value []uint) -func (f *TextFormat) AppendTimeField(buf *bytes.Buffer, key string, value time.Time) { - appendKey(buf, key) - appendTime(buf, value) -} + // AppendFloatField appends given float value as key-value pair to the log buffer + AppendFloatField(buf *bytes.Buffer, key string, value float64) -func (f *TextFormat) AppendTimesField(buf *bytes.Buffer, key string, value []time.Time) { - appendKey(buf, key) - appendTimeSlice(buf, value) -} + // AppendFloatsField appends given float slice value as key-value pair to the log buffer + AppendFloatsField(buf *bytes.Buffer, key string, value []float64) -func (f *TextFormat) AppendDurationField(buf *bytes.Buffer, key string, value time.Duration) { - appendKey(buf, key) - appendDuration(buf, value) -} + // AppendTimeField appends given time value as key-value pair to the log buffer + AppendTimeField(buf *bytes.Buffer, key string, value time.Time) -func (f *TextFormat) AppendDurationsField(buf *bytes.Buffer, key string, value []time.Duration) { - appendKey(buf, key) - appendDurationSlice(buf, value) -} + // AppendTimesField appends given time slice value as key-value pair to the log buffer + AppendTimesField(buf *bytes.Buffer, key string, value []time.Time) -func (f *TextFormat) AppendMsg(buf *bytes.Buffer, a ...interface{}) { - if f.Strict { - // Strict format, use key and quote - buf.WriteString(`msg="`) - fmt.Fprint(buf, a...) - buf.WriteByte('"') - return - } + // AppendDurationField appends given duration value as key-value pair to the log buffer + AppendDurationField(buf *bytes.Buffer, key string, value time.Duration) - // Write message as-is - fmt.Fprint(buf, a...) -} + // AppendDurationsField appends given duration slice value as key-value pair to the log buffer + AppendDurationsField(buf *bytes.Buffer, key string, value []time.Duration) -func (f *TextFormat) AppendMsgf(buf *bytes.Buffer, s string, a ...interface{}) { - if f.Strict { - // Strict format, use key and quote - buf.WriteString(`msg="`) - fmt.Fprintf(buf, s, a...) - buf.WriteByte('"') - return - } + // AppendMsg appends given msg as key-value pair to the log buffer using fmt.Sprint(...) formatting + AppendMsg(buf *bytes.Buffer, a ...interface{}) - // Write message as-is - fmt.Fprintf(buf, s, a...) + // AppendMsgf appends given msg format string as key-value pair to the log buffer using fmt.Sprintf(...) formatting + AppendMsgf(buf *bytes.Buffer, s string, a ...interface{}) } diff --git a/vendor/codeberg.org/gruf/go-logger/format_text.go b/vendor/codeberg.org/gruf/go-logger/format_text.go new file mode 100644 index 000000000..e2380884b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/format_text.go @@ -0,0 +1,915 @@ +package logger + +import ( + stdfmt "fmt" + "reflect" + "strconv" + "time" + "unsafe" + + "codeberg.org/gruf/go-bytes" +) + +// DefaultTextFormat is the default TextFormat instance +var DefaultTextFormat = TextFormat{ + Strict: false, + MaxDepth: 5, + Levels: DefaultLevels(), + TimeFormat: time.RFC1123, +} + +// TextFormat is the default LogFormat implementation, with very similar formatting to logfmt +type TextFormat struct { + // Strict defines whether to use strict key-value pair formatting, i.e. should the level + // timestamp and msg be formatted as key-value pairs (with forced quoting for msg) + Strict bool + + // MaxDepth specifies the max depth of fields the formatter will iterate + MaxDepth uint8 + + // Levels defines the map of log LEVELs to level strings + Levels Levels + + // TimeFormat specifies the time formatting to use + TimeFormat string +} + +// fmt returns a new format instance based on receiver TextFormat and given buffer +func (f TextFormat) fmt(buf *bytes.Buffer) format { + return format{ + isKey: false, + depth: 0, + txt: f, + buf: buf, + } +} + +func (f TextFormat) AppendLevel(buf *bytes.Buffer, lvl LEVEL) { + if f.Strict { + // Strict format, append level key + buf.WriteString(`level=`) + buf.WriteString(f.Levels.LevelString(lvl)) + return + } + + // Write level string + buf.WriteByte('[') + buf.WriteString(f.Levels.LevelString(lvl)) + buf.WriteByte(']') +} + +func (f TextFormat) AppendTimestamp(buf *bytes.Buffer, now string) { + if f.Strict { + // Strict format, use key and quote + buf.WriteString(`time=`) + appendString(f.fmt(buf), now) + return + } + + // Write time as-is + buf.WriteString(now) +} + +func (f TextFormat) AppendField(buf *bytes.Buffer, key string, value interface{}) { + appendKey(buf, key) + appendIfaceOrRValue(f.fmt(buf), value) +} + +func (f TextFormat) AppendFields(buf *bytes.Buffer, fields map[string]interface{}) { + fmt := f.fmt(buf) + + // Append individual fields + for key, value := range fields { + appendKey(buf, key) + appendIfaceOrRValue(fmt, value) + buf.WriteByte(' ') + } + + // Drop last space + if len(fields) > 0 { + buf.Truncate(1) + } +} + +func (f TextFormat) AppendValue(buf *bytes.Buffer, value interface{}) { + appendIfaceOrRValue(f.fmt(buf).IsKey(true), value) +} + +func (f TextFormat) AppendValues(buf *bytes.Buffer, values []interface{}) { + // Prepare formatter + fmt := f.fmt(buf).IsKey(true) + + // Append each of the values + for _, value := range values { + appendIfaceOrRValue(fmt, value) + buf.WriteByte(' ') + } + + // Drop last space + if len(values) > 0 { + buf.Truncate(1) + } +} + +func (f TextFormat) AppendArgs(buf *bytes.Buffer, args []interface{}) { + // Prepare formatter + fmt := f.fmt(buf).IsKey(true).IsRaw(true) + + // Append each of the values + for _, arg := range args { + appendIfaceOrRValue(fmt, arg) + buf.WriteByte(' ') + } + + // Drop last space + if len(args) > 0 { + buf.Truncate(1) + } +} + +func (f TextFormat) AppendByteField(buf *bytes.Buffer, key string, value byte) { + appendKey(buf, key) + appendByte(f.fmt(buf), value) +} + +func (f TextFormat) AppendBytesField(buf *bytes.Buffer, key string, value []byte) { + appendKey(buf, key) + appendBytes(f.fmt(buf), value) +} + +func (f TextFormat) AppendStringField(buf *bytes.Buffer, key string, value string) { + appendKey(buf, key) + appendString(f.fmt(buf), value) +} + +func (f TextFormat) AppendStringsField(buf *bytes.Buffer, key string, value []string) { + appendKey(buf, key) + appendStringSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendBoolField(buf *bytes.Buffer, key string, value bool) { + appendKey(buf, key) + appendBool(f.fmt(buf), value) +} + +func (f TextFormat) AppendBoolsField(buf *bytes.Buffer, key string, value []bool) { + appendKey(buf, key) + appendBoolSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendIntField(buf *bytes.Buffer, key string, value int) { + appendKey(buf, key) + appendInt(f.fmt(buf), int64(value)) +} + +func (f TextFormat) AppendIntsField(buf *bytes.Buffer, key string, value []int) { + appendKey(buf, key) + appendIntSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendUintField(buf *bytes.Buffer, key string, value uint) { + appendKey(buf, key) + appendUint(f.fmt(buf), uint64(value)) +} + +func (f TextFormat) AppendUintsField(buf *bytes.Buffer, key string, value []uint) { + appendKey(buf, key) + appendUintSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendFloatField(buf *bytes.Buffer, key string, value float64) { + appendKey(buf, key) + appendFloat(f.fmt(buf), value) +} + +func (f TextFormat) AppendFloatsField(buf *bytes.Buffer, key string, value []float64) { + appendKey(buf, key) + appendFloatSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendTimeField(buf *bytes.Buffer, key string, value time.Time) { + appendKey(buf, key) + appendTime(f.fmt(buf), value) +} + +func (f TextFormat) AppendTimesField(buf *bytes.Buffer, key string, value []time.Time) { + appendKey(buf, key) + appendTimeSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendDurationField(buf *bytes.Buffer, key string, value time.Duration) { + appendKey(buf, key) + appendDuration(f.fmt(buf), value) +} + +func (f TextFormat) AppendDurationsField(buf *bytes.Buffer, key string, value []time.Duration) { + appendKey(buf, key) + appendDurationSlice(f.fmt(buf), value) +} + +func (f TextFormat) AppendMsg(buf *bytes.Buffer, a ...interface{}) { + if f.Strict { + // Strict format, use key and quote + buf.WriteString(`msg=`) + buf.B = strconv.AppendQuote(buf.B, stdfmt.Sprint(a...)) + return + } + + // Write message as-is + stdfmt.Fprint(buf, a...) +} + +func (f TextFormat) AppendMsgf(buf *bytes.Buffer, s string, a ...interface{}) { + if f.Strict { + // Strict format, use key and quote + buf.WriteString(`msg=`) + buf.B = strconv.AppendQuote(buf.B, stdfmt.Sprintf(s, a...)) + return + } + + // Write message as-is + stdfmt.Fprintf(buf, s, a...) +} + +// format is the object passed among the append___ formatting functions +type format struct { + raw bool + isKey bool + depth uint8 + txt TextFormat + buf *bytes.Buffer +} + +// IsKey returns format instance with key set to value +func (f format) IsKey(is bool) format { + return format{ + raw: f.raw, + isKey: is, + depth: f.depth, + txt: f.txt, + buf: f.buf, + } +} + +// IsRaw returns format instance with raw set to value +func (f format) IsRaw(is bool) format { + return format{ + raw: is, + isKey: f.isKey, + depth: f.depth, + txt: f.txt, + buf: f.buf, + } +} + +// IncrDepth returns format instance with depth incremented +func (f format) IncrDepth() format { + return format{ + raw: f.raw, + isKey: f.isKey, + depth: f.depth + 1, + txt: f.txt, + buf: f.buf, + } +} + +// appendByte writes a single byte to buf +func appendByte(fmt format, b byte) { + fmt.buf.WriteByte(b) +} + +// appendBytes writes a quoted byte slice to buf +func appendBytes(fmt format, b []byte) { + if !fmt.isKey && b == nil { + // Values CAN be nil formatted + appendNilType(fmt, `[]byte`) + } else { + appendString(fmt, bytes.BytesToString(b)) + } +} + +// appendString writes an escaped, double-quoted string to buf +func appendString(fmt format, s string) { + if !fmt.raw { + // Only handle quoting if NOT raw + if !strconv.CanBackquote(s) || !fmt.isKey { + // All non-keys and multiline keys get quoted + escaped + fmt.buf.B = strconv.AppendQuote(fmt.buf.B, s) + return + } else if containsSpaceOrTab(s) { + // Key containing spaces/tabs, quote this + fmt.buf.WriteByte('"') + fmt.buf.WriteString(s) + fmt.buf.WriteByte('"') + return + } + } + + // Safe to leave unquoted + fmt.buf.WriteString(s) +} + +// appendStringSlice writes a slice of strings to buf +func appendStringSlice(fmt format, s []string) { + // Check for nil slice + if s == nil { + appendNilType(fmt, `[]string`) + return + } + + fmt.buf.WriteByte('[') + + // Prepare formatter + fmt = fmt.IsKey(false) + + // Write elements + for _, s := range s { + appendString(fmt, s) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(s) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendBool writes a formatted bool to buf +func appendBool(fmt format, b bool) { + fmt.buf.B = strconv.AppendBool(fmt.buf.B, b) +} + +// appendBool writes a slice of formatted bools to buf +func appendBoolSlice(fmt format, b []bool) { + // Check for nil slice + if b == nil { + appendNilType(fmt, `[]bool`) + return + } + + fmt.buf.WriteByte('[') + + // Write elements + for _, b := range b { + appendBool(fmt, b) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(b) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendInt writes a formatted int to buf +func appendInt(fmt format, i int64) { + fmt.buf.B = strconv.AppendInt(fmt.buf.B, i, 10) +} + +// appendIntSlice writes a slice of formatted int to buf +func appendIntSlice(fmt format, i []int) { + // Check for nil slice + if i == nil { + appendNilType(fmt, `[]int`) + return + } + + fmt.buf.WriteByte('[') + + // Write elements + for _, i := range i { + appendInt(fmt, int64(i)) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(i) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendUint writes a formatted uint to buf +func appendUint(fmt format, u uint64) { + fmt.buf.B = strconv.AppendUint(fmt.buf.B, u, 10) +} + +// appendUintSlice writes a slice of formatted uint to buf +func appendUintSlice(fmt format, u []uint) { + // Check for nil slice + if u == nil { + appendNilType(fmt, `[]uint`) + return + } + + fmt.buf.WriteByte('[') + + // Write elements + for _, u := range u { + appendUint(fmt, uint64(u)) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(u) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendFloat writes a formatted float to buf +func appendFloat(fmt format, f float64) { + fmt.buf.B = strconv.AppendFloat(fmt.buf.B, f, 'G', -1, 64) +} + +// appendFloatSlice writes a slice formatted floats to buf +func appendFloatSlice(fmt format, f []float64) { + // Check for nil slice + if f == nil { + appendNilType(fmt, `[]float64`) + return + } + + fmt.buf.WriteByte('[') + + // Write elements + for _, f := range f { + appendFloat(fmt, f) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(f) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendTime writes a formatted, quoted time string to buf +func appendTime(fmt format, t time.Time) { + appendString(fmt.IsKey(true), t.Format(fmt.txt.TimeFormat)) +} + +// appendTimeSlice writes a slice of formatted time strings to buf +func appendTimeSlice(fmt format, t []time.Time) { + // Check for nil slice + if t == nil { + appendNilType(fmt, `[]time.Time`) + return + } + + fmt.buf.WriteByte('[') + + // Prepare formatter + fmt = fmt.IsKey(true) + + // Write elements + for _, t := range t { + appendString(fmt, t.Format(fmt.txt.TimeFormat)) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(t) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendDuration writes a formatted, quoted duration string to buf +func appendDuration(fmt format, d time.Duration) { + appendString(fmt.IsKey(true), d.String()) +} + +// appendDurationSlice writes a slice of formatted, quoted duration strings to buf +func appendDurationSlice(fmt format, d []time.Duration) { + // Check for nil slice + if d == nil { + appendNilType(fmt, `[]time.Duration`) + return + } + + fmt.buf.WriteByte('[') + + // Prepare formatter + fmt = fmt.IsKey(true) + + // Write elements + for _, d := range d { + appendString(fmt, d.String()) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(d) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendComplex writes a formatted complex128 to buf +func appendComplex(fmt format, c complex128) { + appendFloat(fmt, real(c)) + fmt.buf.WriteByte('+') + appendFloat(fmt, imag(c)) + fmt.buf.WriteByte('i') +} + +// appendComplexSlice writes a slice of formatted complex128s to buf +func appendComplexSlice(fmt format, c []complex128) { + // Check for nil slice + if c == nil { + appendNilType(fmt, `[]complex128`) + return + } + + fmt.buf.WriteByte('[') + + // Write elements + for _, c := range c { + appendComplex(fmt, c) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if len(c) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// notNil will safely check if 'v' is nil without dealing with weird Go interface nil bullshit. +func notNil(i interface{}) bool { + // cast to get fat pointer + e := *(*struct { + typeOf unsafe.Pointer // ignored + valueOf unsafe.Pointer + })(unsafe.Pointer(&i)) + + // check if value part is nil + return (e.valueOf != nil) +} + +// appendNilType will append a formatted nil of type 't' +func appendNilType(fmt format, t string) { + fmt.buf.WriteByte('(') + fmt.buf.WriteString(t) + fmt.buf.WriteString(`)(<nil>)`) +} + +// appendNilValue will append a formatted nil of type fetched from value 'v' +func appendNilRValue(fmt format, v reflect.Value) { + appendNilType(fmt, v.Type().String()) +} + +// appendIfaceOrReflectValue will attempt to append as interface, falling back to reflection +func appendIfaceOrRValue(fmt format, i interface{}) { + // Check we haven't hit max + if fmt.depth >= fmt.txt.MaxDepth { + fmt.buf.WriteString("...") + return + } + + // Incr the depth + fmt = fmt.IncrDepth() + + // Attempt to append interface, fallback to reflect + if !appendIface(fmt, i) { + appendRValue(fmt, reflect.ValueOf(i)) + } +} + +// appendReflectValueOrIface will attempt to interface the reflect.Value, falling back to using this directly +func appendRValueOrIface(fmt format, v reflect.Value) { + // Check we haven't hit max + if fmt.depth >= fmt.txt.MaxDepth { + fmt.buf.WriteString("...") + return + } + + // Incr the depth + fmt = fmt.IncrDepth() + + // Attempt to interface reflect value, fallback to handling value itself + if !v.CanInterface() || !appendIface(fmt, v.Interface()) { + appendRValue(fmt, v) + } +} + +// appendIface parses and writes a formatted interface value to buf +func appendIface(fmt format, i interface{}) bool { + switch i := i.(type) { + case nil: + fmt.buf.WriteString(`<nil>`) + case byte: + appendByte(fmt, i) + case []byte: + appendBytes(fmt, i) + case string: + appendString(fmt, i) + case []string: + appendStringSlice(fmt, i) + case int: + appendInt(fmt, int64(i)) + case int8: + appendInt(fmt, int64(i)) + case int16: + appendInt(fmt, int64(i)) + case int32: + appendInt(fmt, int64(i)) + case int64: + appendInt(fmt, i) + case []int: + appendIntSlice(fmt, i) + case uint: + appendUint(fmt, uint64(i)) + case uint16: + appendUint(fmt, uint64(i)) + case uint32: + appendUint(fmt, uint64(i)) + case uint64: + appendUint(fmt, i) + case []uint: + appendUintSlice(fmt, i) + case float32: + appendFloat(fmt, float64(i)) + case float64: + appendFloat(fmt, i) + case []float64: + appendFloatSlice(fmt, i) + case bool: + appendBool(fmt, i) + case []bool: + appendBoolSlice(fmt, i) + case time.Time: + appendTime(fmt, i) + case []time.Time: + appendTimeSlice(fmt, i) + case time.Duration: + appendDuration(fmt, i) + case []time.Duration: + appendDurationSlice(fmt, i) + case complex64: + appendComplex(fmt, complex128(i)) + case complex128: + appendComplex(fmt, i) + case []complex128: + appendComplexSlice(fmt, i) + case map[string]interface{}: + appendIfaceMap(fmt, i) + case error: + if notNil(i) /* use safer nil check */ { + appendString(fmt, i.Error()) + } else { + appendNilType(fmt, reflect.TypeOf(i).String()) + } + case stdfmt.Stringer: + if notNil(i) /* use safer nil check */ { + appendString(fmt, i.String()) + } else { + appendNilType(fmt, reflect.TypeOf(i).String()) + } + default: + return false // could not handle + } + + return true +} + +// appendReflectValue will safely append a reflected value +func appendRValue(fmt format, v reflect.Value) { + switch v.Kind() { + case reflect.Float32, reflect.Float64: + appendFloat(fmt, v.Float()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + appendInt(fmt, v.Int()) + case reflect.Uint8: + appendByte(fmt, uint8(v.Uint())) + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + appendUint(fmt, v.Uint()) + case reflect.Bool: + appendBool(fmt, v.Bool()) + case reflect.Array: + appendArrayType(fmt, v) + case reflect.Slice: + appendSliceType(fmt, v) + case reflect.Map: + appendMapType(fmt, v) + case reflect.Struct: + appendStructType(fmt, v) + case reflect.Ptr: + if v.IsNil() { + appendNilRValue(fmt, v) + } else { + appendRValue(fmt, v.Elem()) + } + case reflect.UnsafePointer: + fmt.buf.WriteString("(unsafe.Pointer)") + fmt.buf.WriteByte('(') + if u := v.Pointer(); u != 0 { + fmt.buf.WriteString("0x") + fmt.buf.B = strconv.AppendUint(fmt.buf.B, uint64(u), 16) + } else { + fmt.buf.WriteString(`<nil>`) + } + fmt.buf.WriteByte(')') + case reflect.Uintptr: + fmt.buf.WriteString("(uintptr)") + fmt.buf.WriteByte('(') + if u := v.Uint(); u != 0 { + fmt.buf.WriteString("0x") + fmt.buf.B = strconv.AppendUint(fmt.buf.B, u, 16) + } else { + fmt.buf.WriteString(`<nil>`) + } + fmt.buf.WriteByte(')') + case reflect.String: + appendString(fmt, v.String()) + case reflect.Complex64, reflect.Complex128: + appendComplex(fmt, v.Complex()) + case reflect.Func, reflect.Chan, reflect.Interface: + if v.IsNil() { + appendNilRValue(fmt, v) + } else { + fmt.buf.WriteString(v.String()) + } + default: + fmt.buf.WriteString(v.String()) + } +} + +// appendIfaceMap writes a map of key-value pairs (as a set of fields) to buf +func appendIfaceMap(fmt format, v map[string]interface{}) { + // Catch nil map + if v == nil { + appendNilType(fmt, `map[string]interface{}`) + return + } + + fmt.buf.WriteByte('{') + + // Prepare formatters + fmtKey := fmt.IsKey(true) + fmtVal := fmt.IsKey(false) + + // Write map pairs! + for key, value := range v { + appendString(fmtKey, key) + fmt.buf.WriteByte('=') + appendIfaceOrRValue(fmtVal, value) + fmt.buf.WriteByte(' ') + } + + // Drop last space + if len(v) > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte('}') +} + +// appendArrayType writes an array of unknown type (parsed by reflection) to buf, unlike appendSliceType does NOT catch nil slice +func appendArrayType(fmt format, v reflect.Value) { + // get no. elements + n := v.Len() + + fmt.buf.WriteByte('[') + + // Prepare formatter + fmt = fmt.IsKey(false) + + // Write values + for i := 0; i < n; i++ { + appendRValueOrIface(fmt, v.Index(i)) + fmt.buf.WriteByte(',') + } + + // Drop last comma + if n > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte(']') +} + +// appendSliceType writes a slice of unknown type (parsed by reflection) to buf +func appendSliceType(fmt format, v reflect.Value) { + if v.IsNil() { + appendNilRValue(fmt, v) + } else { + appendArrayType(fmt, v) + } +} + +// appendMapType writes a map of unknown types (parsed by reflection) to buf +func appendMapType(fmt format, v reflect.Value) { + // Catch nil map + if v.IsNil() { + appendNilRValue(fmt, v) + return + } + + // Get a map iterator + r := v.MapRange() + n := v.Len() + + fmt.buf.WriteByte('{') + + // Prepare formatters + fmtKey := fmt.IsKey(true) + fmtVal := fmt.IsKey(false) + + // Iterate pairs + for r.Next() { + appendRValueOrIface(fmtKey, r.Key()) + fmt.buf.WriteByte('=') + appendRValueOrIface(fmtVal, r.Value()) + fmt.buf.WriteByte(' ') + } + + // Drop last space + if n > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte('}') +} + +// appendStructType writes a struct (as a set of key-value fields) to buf +func appendStructType(fmt format, v reflect.Value) { + // Get value type & no. fields + t := v.Type() + n := v.NumField() + w := 0 + + fmt.buf.WriteByte('{') + + // Prepare formatters + fmtKey := fmt.IsKey(true) + fmtVal := fmt.IsKey(false) + + // Iterate fields + for i := 0; i < n; i++ { + vfield := v.Field(i) + + if !vfield.CanInterface() { + // This is an unexported field + appendRValue(fmtVal, vfield) + } else { + // This is an exported field! + appendString(fmtKey, t.Field(i).Name) + fmt.buf.WriteByte('=') + appendRValueOrIface(fmtVal, vfield) + } + + // Iter written count + fmt.buf.WriteByte(' ') + w++ + } + + // Drop last space + if w > 0 { + fmt.buf.Truncate(1) + } + + fmt.buf.WriteByte('}') +} + +// appendKey should only be used in the case of directly setting key-value pairs, +// not in the case of appendMapType, appendStructType +func appendKey(buf *bytes.Buffer, key string) { + if len(key) > 0 { + if containsSpaceOrTab(key) { + // Key containing spaces/tabs, quote this + buf.WriteByte('"') + buf.WriteString(key) + buf.WriteByte('"') + } else { + // Key is safe to leave unquoted + buf.WriteString(key) + } + + // Write final '=' + buf.WriteByte('=') + } +} + +// containsSpaceOrTab checks if "s" contains space or tabs +func containsSpaceOrTab(s string) bool { + for _, r := range s { + if r == ' ' || r == '\t' { + return true + } + } + return false +} diff --git a/vendor/codeberg.org/gruf/go-logger/level.go b/vendor/codeberg.org/gruf/go-logger/level.go index cb0073240..76c9ed2b3 100644 --- a/vendor/codeberg.org/gruf/go-logger/level.go +++ b/vendor/codeberg.org/gruf/go-logger/level.go @@ -21,11 +21,11 @@ type Levels map[LEVEL]string // DefaultLevels returns the default set of log levels func DefaultLevels() Levels { return Levels{ - DEBUG: "debug", - INFO: "info", - WARN: "warn", - ERROR: "error", - FATAL: "fatal", + DEBUG: "DEBUG", + INFO: "INFO", + WARN: "WARN", + ERROR: "ERROR", + FATAL: "FATAL", } } diff --git a/vendor/codeberg.org/gruf/go-logger/logger.go b/vendor/codeberg.org/gruf/go-logger/logger.go index 25d573df1..895d3690f 100644 --- a/vendor/codeberg.org/gruf/go-logger/logger.go +++ b/vendor/codeberg.org/gruf/go-logger/logger.go @@ -43,7 +43,7 @@ type Logger struct { // New returns a new Logger instance with defaults func New(out io.Writer) *Logger { - return NewWith(0 /* all */, true, NewLogFmt(false), 512, out) + return NewWith(0 /* all */, true, DefaultTextFormat, 512, out) } // NewWith returns a new Logger instance with supplied configuration diff --git a/vendor/codeberg.org/gruf/go-logger/writer.go b/vendor/codeberg.org/gruf/go-logger/writer.go new file mode 100644 index 000000000..72321f518 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/writer.go @@ -0,0 +1,29 @@ +package logger + +import ( + "io" + "io/ioutil" + "sync" +) + +// AddSafety wraps an io.Writer to provide mutex locking protection +func AddSafety(w io.Writer) io.Writer { + if w == nil { + w = ioutil.Discard + } else if sw, ok := w.(*safeWriter); ok { + return sw + } + return &safeWriter{wr: w} +} + +// safeWriter wraps an io.Writer to provide mutex locking on write +type safeWriter struct { + wr io.Writer + mu sync.Mutex +} + +func (w *safeWriter) Write(b []byte) (int, error) { + w.mu.Lock() + defer w.mu.Unlock() + return w.wr.Write(b) +} |