diff options
author | 2021-11-13 12:29:08 +0100 | |
---|---|---|
committer | 2021-11-13 12:29:08 +0100 | |
commit | 829a934d23ab221049b4d54926305d8d5d64c9ad (patch) | |
tree | f4e382b289c113d3ba8a3c7a183507a5609c46c0 /vendor/codeberg.org/gruf/go-logger | |
parent | smtp + email confirmation (#285) (diff) | |
download | gotosocial-829a934d23ab221049b4d54926305d8d5d64c9ad.tar.xz |
update dependencies (#296)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-logger')
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/LICENSE | 9 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/README.md | 9 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/clock.go | 21 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/default.go | 87 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/entry.go | 231 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/format.go | 640 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/hook.go | 13 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/level.go | 39 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-logger/logger.go | 153 |
9 files changed, 1202 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-logger/LICENSE b/vendor/codeberg.org/gruf/go-logger/LICENSE new file mode 100644 index 000000000..b7c4417ac --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2021 gruf + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/codeberg.org/gruf/go-logger/README.md b/vendor/codeberg.org/gruf/go-logger/README.md new file mode 100644 index 000000000..a255a2ea9 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/README.md @@ -0,0 +1,9 @@ +Fast levelled logging package with customizable formatting. + +Supports logging in 2 modes: +- no locks, fastest possible logging, no guarantees for io.Writer thread safety +- mutex locks during writes, still far faster than standard library logger + +Running without locks isn't likely to cause you any issues*, but if it does, you can wrap your `io.Writer` using `AddSafety()` when instantiating your new Logger. Even when running the benchmarks, this library has no printing issues without locks, so in most cases you'll be fine, but the safety is there if you need it. + +*most logging libraries advertising high speeds are likely not performing mutex locks, which is why with this library you have the option to opt-in/out of them.
\ No newline at end of file diff --git a/vendor/codeberg.org/gruf/go-logger/clock.go b/vendor/codeberg.org/gruf/go-logger/clock.go new file mode 100644 index 000000000..5e6f877f0 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/clock.go @@ -0,0 +1,21 @@ +package logger + +import ( + "sync" + "time" + + "codeberg.org/gruf/go-nowish" +) + +var ( + clock = nowish.Clock{} + clockOnce = sync.Once{} +) + +// startClock starts the global nowish clock +func startClock() { + clockOnce.Do(func() { + clock.Start(time.Millisecond * 10) + clock.SetFormat("2006-01-02 15:04:05") + }) +} diff --git a/vendor/codeberg.org/gruf/go-logger/default.go b/vendor/codeberg.org/gruf/go-logger/default.go new file mode 100644 index 000000000..e2932e733 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/default.go @@ -0,0 +1,87 @@ +package logger + +import ( + "os" + "sync" +) + +var ( + instance *Logger + instanceOnce = sync.Once{} +) + +// 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 +func Debug(a ...interface{}) { + Default().Debug(a...) +} + +// 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 +func Info(a ...interface{}) { + Default().Info(a...) +} + +// 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 +func Warn(a ...interface{}) { + Default().Warn(a...) +} + +// 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 +func Error(a ...interface{}) { + Default().Error(a...) +} + +// 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) +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) +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 +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 +func Logf(lvl LEVEL, s string, a ...interface{}) { + Default().Logf(lvl, s, a...) +} + +// 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 +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 new file mode 100644 index 000000000..f2fe293aa --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/entry.go @@ -0,0 +1,231 @@ +package logger + +import ( + "context" + "time" + + "codeberg.org/gruf/go-bytes" +) + +// Entry defines an entry in the log +type Entry struct { + ctx context.Context + lvl LEVEL + buf *bytes.Buffer + log *Logger +} + +// Context returns the current set Entry context.Context +func (e *Entry) Context() context.Context { + return e.ctx +} + +// WithContext updates Entry context value to the supplied +func (e *Entry) WithContext(ctx context.Context) *Entry { + e.ctx = ctx + return e +} + +// Level appends the supplied level to the log entry, and sets the entry level. +// Please note this CAN be called and append log levels multiple times +func (e *Entry) Level(lvl LEVEL) *Entry { + e.log.Format.AppendLevel(e.buf, lvl) + e.buf.WriteByte(' ') + e.lvl = lvl + return e +} + +// Timestamp appends the current timestamp to the log entry. Please note this +// CAN be called and append the timestamp multiple times +func (e *Entry) Timestamp() *Entry { + e.log.Format.AppendTimestamp(e.buf, clock.NowFormat()) + e.buf.WriteByte(' ') + return e +} + +// TimestampIf performs Entry.Timestamp() only IF timestamping is enabled for the Logger. +// Please note this CAN be called multiple times +func (e *Entry) TimestampIf() *Entry { + if e.log.Timestamp { + e.Timestamp() + } + return e +} + +// Hooks applies currently set Hooks to the Entry. Please note this CAN be +// called and perform the Hooks multiple times +func (e *Entry) Hooks() *Entry { + for _, hook := range e.log.Hooks { + hook.Do(e) + } + return e +} + +// Byte appends a byte value as key-value pair to the log entry +func (e *Entry) Byte(key string, value byte) *Entry { + e.log.Format.AppendByteField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Bytes appends a byte slice value as key-value pair to the log entry +func (e *Entry) Bytes(key string, value []byte) *Entry { + e.log.Format.AppendBytesField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Str appends a string value as key-value pair to the log entry +func (e *Entry) Str(key string, value string) *Entry { + e.log.Format.AppendStringField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Strs appends a string slice value as key-value pair to the log entry +func (e *Entry) Strs(key string, value []string) *Entry { + e.log.Format.AppendStringsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Int appends an int value as key-value pair to the log entry +func (e *Entry) Int(key string, value int) *Entry { + e.log.Format.AppendIntField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Ints appends an int slice value as key-value pair to the log entry +func (e *Entry) Ints(key string, value []int) *Entry { + e.log.Format.AppendIntsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Uint appends a uint value as key-value pair to the log entry +func (e *Entry) Uint(key string, value uint) *Entry { + e.log.Format.AppendUintField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Uints appends a uint slice value as key-value pair to the log entry +func (e *Entry) Uints(key string, value []uint) *Entry { + e.log.Format.AppendUintsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Float appends a float value as key-value pair to the log entry +func (e *Entry) Float(key string, value float64) *Entry { + e.log.Format.AppendFloatField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Floats appends a float slice value as key-value pair to the log entry +func (e *Entry) Floats(key string, value []float64) *Entry { + e.log.Format.AppendFloatsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Bool appends a bool value as key-value pair to the log entry +func (e *Entry) Bool(key string, value bool) *Entry { + e.log.Format.AppendBoolField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Bools appends a bool slice value as key-value pair to the log entry +func (e *Entry) Bools(key string, value []bool) *Entry { + e.log.Format.AppendBoolsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Time appends a time.Time value as key-value pair to the log entry +func (e *Entry) Time(key string, value time.Time) *Entry { + e.log.Format.AppendTimeField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Times appends a time.Time slice value as key-value pair to the log entry +func (e *Entry) Times(key string, value []time.Time) *Entry { + e.log.Format.AppendTimesField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Duration appends a time.Duration value as key-value pair to the log entry +func (e *Entry) Duration(key string, value time.Duration) *Entry { + e.log.Format.AppendDurationField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Durations appends a time.Duration slice value as key-value pair to the log entry +func (e *Entry) Durations(key string, value []time.Duration) *Entry { + e.log.Format.AppendDurationsField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Field appends an interface value as key-value pair to the log entry +func (e *Entry) Field(key string, value interface{}) *Entry { + e.log.Format.AppendField(e.buf, key, value) + e.buf.WriteByte(' ') + return e +} + +// Fields appends a map of key-value pairs to the log entry +func (e *Entry) Fields(fields map[string]interface{}) *Entry { + e.log.Format.AppendFields(e.buf, fields) + e.buf.WriteByte(' ') + return e +} + +// Msg appends the 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() +func (e *Entry) Msgf(s string, a ...interface{}) { + e.log.Format.AppendMsgf(e.buf, s, a...) + e.Send() +} + +// Send triggers write of the log entry, skipping if the entry's log LEVEL +// is below the currently set Logger level, and releases the Entry back to +// the Logger's Entry pool. So it is NOT safe to continue using this Entry +// object after calling .Send(), .Msg() or .Msgf() +func (e *Entry) Send() { + // If nothing to do, return + if e.lvl < e.log.Level || e.buf.Len() < 1 { + e.reset() + return + } + + // Final new line + if e.buf.B[e.buf.Len()-1] != '\n' { + e.buf.WriteByte('\n') + } + + // Write, reset and release + e.log.Output.Write(e.buf.B) + e.reset() +} + +func (e *Entry) reset() { + // Reset all + e.ctx = nil + e.buf.Reset() + e.lvl = unset + + // Release to pool + e.log.pool.Put(e) +} diff --git a/vendor/codeberg.org/gruf/go-logger/format.go b/vendor/codeberg.org/gruf/go-logger/format.go new file mode 100644 index 000000000..214773ff3 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/format.go @@ -0,0 +1,640 @@ +package logger + +import ( + "fmt" + "reflect" + "strconv" + "time" + + "codeberg.org/gruf/go-bytes" +) + +// Check our types impl LogFormat +var _ LogFormat = &TextFormat{} + +// LogFormat defines a method of formatting log entries +type LogFormat interface { + 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) +} + +func (f *TextFormat) AppendField(buf *bytes.Buffer, key string, value interface{}) { + appendKey(buf, key) + appendIface(buf, value, false) +} + +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(' ') + } + + // Drop last space + if len(fields) > 0 { + buf.Truncate(1) + } +} + +func (f *TextFormat) AppendByteField(buf *bytes.Buffer, key string, value byte) { + appendKey(buf, key) + appendByte(buf, value) +} + +func (f *TextFormat) AppendBytesField(buf *bytes.Buffer, key string, value []byte) { + appendKey(buf, key) + appendBytes(buf, value) +} + +func (f *TextFormat) AppendStringField(buf *bytes.Buffer, key string, value string) { + appendKey(buf, key) + appendString(buf, value) +} + +func (f *TextFormat) AppendStringsField(buf *bytes.Buffer, key string, value []string) { + appendKey(buf, key) + appendStringSlice(buf, value) +} + +func (f *TextFormat) AppendBoolField(buf *bytes.Buffer, key string, value bool) { + appendKey(buf, key) + appendBool(buf, value) +} + +func (f *TextFormat) AppendBoolsField(buf *bytes.Buffer, key string, value []bool) { + appendKey(buf, key) + appendBoolSlice(buf, value) +} + +func (f *TextFormat) AppendIntField(buf *bytes.Buffer, key string, value int) { + appendKey(buf, key) + appendInt(buf, int64(value)) +} + +func (f *TextFormat) AppendIntsField(buf *bytes.Buffer, key string, value []int) { + appendKey(buf, key) + appendIntSlice(buf, value) +} + +func (f *TextFormat) AppendUintField(buf *bytes.Buffer, key string, value uint) { + appendKey(buf, key) + appendUint(buf, uint64(value)) +} + +func (f *TextFormat) AppendUintsField(buf *bytes.Buffer, key string, value []uint) { + appendKey(buf, key) + appendUintSlice(buf, value) +} + +func (f *TextFormat) AppendFloatField(buf *bytes.Buffer, key string, value float64) { + appendKey(buf, key) + appendFloat(buf, value) +} + +func (f *TextFormat) AppendFloatsField(buf *bytes.Buffer, key string, value []float64) { + appendKey(buf, key) + appendFloatSlice(buf, value) +} + +func (f *TextFormat) AppendTimeField(buf *bytes.Buffer, key string, value time.Time) { + appendKey(buf, key) + appendTime(buf, value) +} + +func (f *TextFormat) AppendTimesField(buf *bytes.Buffer, key string, value []time.Time) { + appendKey(buf, key) + appendTimeSlice(buf, value) +} + +func (f *TextFormat) AppendDurationField(buf *bytes.Buffer, key string, value time.Duration) { + appendKey(buf, key) + appendDuration(buf, value) +} + +func (f *TextFormat) AppendDurationsField(buf *bytes.Buffer, key string, value []time.Duration) { + appendKey(buf, key) + appendDurationSlice(buf, value) +} + +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 + } + + // Write message as-is + fmt.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="`) + fmt.Fprintf(buf, s, a...) + buf.WriteByte('"') + return + } + + // Write message as-is + fmt.Fprintf(buf, s, a...) +} diff --git a/vendor/codeberg.org/gruf/go-logger/hook.go b/vendor/codeberg.org/gruf/go-logger/hook.go new file mode 100644 index 000000000..2345ca93b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/hook.go @@ -0,0 +1,13 @@ +package logger + +// Hook defines a log Entry modifier +type Hook interface { + Do(*Entry) +} + +// HookFunc is a simple adapter to allow functions to satisfy the Hook interface +type HookFunc func(*Entry) + +func (hook HookFunc) Do(entry *Entry) { + hook(entry) +} diff --git a/vendor/codeberg.org/gruf/go-logger/level.go b/vendor/codeberg.org/gruf/go-logger/level.go new file mode 100644 index 000000000..cb0073240 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/level.go @@ -0,0 +1,39 @@ +package logger + +// LEVEL defines a level of logging +type LEVEL uint8 + +// Available levels of logging. +const ( + unset LEVEL = 255 + DEBUG LEVEL = 5 + INFO LEVEL = 10 + WARN LEVEL = 15 + ERROR LEVEL = 20 + FATAL LEVEL = 25 +) + +var unknownLevel = "unknown" + +// Levels defines a mapping of log LEVELs to formatted level strings +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", + } +} + +// LevelString fetches the appropriate level string for the provided level, or "unknown" +func (l Levels) LevelString(lvl LEVEL) string { + str, ok := l[lvl] + if !ok { + return unknownLevel + } + return str +} diff --git a/vendor/codeberg.org/gruf/go-logger/logger.go b/vendor/codeberg.org/gruf/go-logger/logger.go new file mode 100644 index 000000000..25d573df1 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-logger/logger.go @@ -0,0 +1,153 @@ +package logger + +import ( + "context" + "io" + "os" + "sync" + "sync/atomic" + + "codeberg.org/gruf/go-bytes" +) + +type Logger struct { + // Hooks defines a list of hooks which are called before an entry + // is written. This should NOT be modified while the Logger is in use + Hooks []Hook + + // Level is the current log LEVEL, entries at level below the + // currently set level will not be output. This should NOT + // be modified while the Logger is in use + Level LEVEL + + // Timestamp defines whether to automatically append timestamps + // to entries written via Logger convience methods and specifically + // Entry.TimestampIf(). This should NOT be modified while Logger in use + Timestamp bool + + // Format is the log entry LogFormat to use. This should NOT + // be modified while the Logger is in use + Format LogFormat + + // BufferSize is the Entry buffer size to use when allocating + // new Entry objects. This should be modified atomically + BufSize int64 + + // Output is the log's output writer. This should NOT be + // modified while the Logger is in use + Output io.Writer + + // entry pool + pool sync.Pool +} + +// New returns a new Logger instance with defaults +func New(out io.Writer) *Logger { + return NewWith(0 /* all */, true, NewLogFmt(false), 512, out) +} + +// NewWith returns a new Logger instance with supplied configuration +func NewWith(lvl LEVEL, timestamp bool, fmt LogFormat, bufsize int64, out io.Writer) *Logger { + // Create new logger object + log := &Logger{ + Level: lvl, + Timestamp: timestamp, + Format: fmt, + BufSize: bufsize, + Output: out, + pool: sync.Pool{}, + } + + // Ensure clock running + startClock() + + // Set-up logger Entry pool + log.pool.New = func() interface{} { + return &Entry{ + lvl: unset, + buf: &bytes.Buffer{B: make([]byte, 0, atomic.LoadInt64(&log.BufSize))}, + log: log, + } + } + + return log +} + +// Entry returns a new Entry from the Logger's pool with background context +func (l *Logger) Entry() *Entry { + return l.pool.Get().(*Entry).WithContext(context.Background()) +} + +// Debug prints the provided arguments with the debug prefix +func (l *Logger) Debug(a ...interface{}) { + l.Entry().TimestampIf().Level(DEBUG).Hooks().Msg(a...) +} + +// Debugf prints the provided format string and arguments with the debug prefix +func (l *Logger) Debugf(s string, a ...interface{}) { + l.Entry().TimestampIf().Level(DEBUG).Hooks().Msgf(s, a...) +} + +// Info prints the provided arguments with the info prefix +func (l *Logger) Info(a ...interface{}) { + l.Entry().TimestampIf().Level(INFO).Hooks().Msg(a...) +} + +// Infof prints the provided format string and arguments with the info prefix +func (l *Logger) Infof(s string, a ...interface{}) { + l.Entry().TimestampIf().Level(INFO).Hooks().Msgf(s, a...) +} + +// Warn prints the provided arguments with the warn prefix +func (l *Logger) Warn(a ...interface{}) { + l.Entry().TimestampIf().Level(WARN).Hooks().Msg(a...) +} + +// Warnf prints the provided format string and arguments with the warn prefix +func (l *Logger) Warnf(s string, a ...interface{}) { + l.Entry().TimestampIf().Level(WARN).Hooks().Msgf(s, a...) +} + +// Error prints the provided arguments with the error prefix +func (l *Logger) Error(a ...interface{}) { + l.Entry().TimestampIf().Level(ERROR).Hooks().Msg(a...) +} + +// Errorf prints the provided format string and arguments with the error prefix +func (l *Logger) Errorf(s string, a ...interface{}) { + l.Entry().TimestampIf().Level(ERROR).Hooks().Msgf(s, a...) +} + +// Fatal prints provided arguments with the fatal prefix before exiting the program +// with os.Exit(1) +func (l *Logger) Fatal(a ...interface{}) { + defer os.Exit(1) + l.Entry().TimestampIf().Level(FATAL).Hooks().Msg(a...) +} + +// Fatalf prints provided the provided format string and arguments with the fatal prefix +// before exiting the program with os.Exit(1) +func (l *Logger) Fatalf(s string, a ...interface{}) { + defer os.Exit(1) + l.Entry().TimestampIf().Level(FATAL).Hooks().Msgf(s, a...) +} + +// Log prints the provided arguments with the supplied log level +func (l *Logger) Log(lvl LEVEL, a ...interface{}) { + l.Entry().TimestampIf().Hooks().Msg(a...) +} + +// Logf prints the provided format string and arguments with the supplied log level +func (l *Logger) Logf(lvl LEVEL, s string, a ...interface{}) { + l.Entry().TimestampIf().Hooks().Msgf(s, a...) +} + +// Print simply prints provided arguments +func (l *Logger) Print(a ...interface{}) { + l.Entry().Hooks().Msg(a...) +} + +// Printf simply prints provided the provided format string and arguments +func (l *Logger) Printf(s string, a ...interface{}) { + l.Entry().Hooks().Msgf(s, a...) +} |