update field #8

Merged
andrey merged 2 commits from field into master 2024-01-02 15:45:36 +03:00
8 changed files with 316 additions and 34 deletions
Showing only changes of commit 3c83f30826 - Show all commits

View File

@@ -61,3 +61,8 @@ issues:
- gomnd - gomnd
- ireturn - ireturn
- exhaustruct - exhaustruct
- gochecknoglobals
- path: _example_test\.go
linters:
- lll
- goerr113

View File

@@ -12,7 +12,6 @@ import (
"gitoa.ru/go-4devs/log/field" "gitoa.ru/go-4devs/log/field"
) )
//nolint:gochecknoglobals
var ( var (
errExample = errors.New("fail") errExample = errors.New("fail")
_messages = fakeMessages(1000) _messages = fakeMessages(1000)

5
field/errors.go Normal file
View File

@@ -0,0 +1,5 @@
package field
import "errors"
var ErrUndefined = errors.New("indefined")

View File

@@ -85,7 +85,7 @@ func Uint8(key string, value uint8) Field {
func Uint8s(key string, value ...uint8) Field { func Uint8s(key string, value ...uint8) Field {
return Field{ return Field{
Key: key, Key: key,
Value: AnyValue(value), Value: Uint8sValue(value),
} }
} }
@@ -316,7 +316,7 @@ func Complex64(key string, value complex64) Field {
func Complex64s(key string, value ...complex64) Field { func Complex64s(key string, value ...complex64) Field {
return Field{ return Field{
Key: key, Key: key,
Value: AnyValue(value), Value: Complex64sValue(value),
} }
} }

View File

@@ -1,5 +1,7 @@
package field package field
import "fmt"
//go:generate stringer -type=Kind -linecomment -output=kind_string.go //go:generate stringer -type=Kind -linecomment -output=kind_string.go
type Kind int type Kind int
@@ -22,3 +24,63 @@ const (
KindGroup // group KindGroup // group
KindClosure // closure KindClosure // closure
) )
func (l Kind) MarshalJSON() ([]byte, error) {
return []byte("\"" + l.String() + "\""), nil
}
func (l *Kind) UnmarshalJSON(in []byte) error {
return l.UnmarshalText(in[1 : len(in)-1])
}
func (l Kind) MarshalText() ([]byte, error) {
return []byte(l.String()), nil
}
//nolint:gocyclo,cyclop
func (l *Kind) UnmarshalText(in []byte) error {
switch string(in) {
case KindAny.String():
*l = KindAny
case KindArray.String():
*l = KindArray
case KindNil.String():
*l = KindNil
case KindString.String():
*l = KindString
case KindBool.String():
*l = KindBool
case KindInt64.String():
*l = KindInt64
case KindUint64.String():
*l = KindUint64
case KindFloat32.String():
*l = KindFloat32
case KindFloat64.String():
*l = KindFloat64
case KindComplex128.String():
*l = KindComplex128
case KindBinary.String():
*l = KindBinary
case KindDuration.String():
*l = KindDuration
case KindTime.String():
*l = KindTime
case KindError.String():
*l = KindError
case KindGroup.String():
*l = KindGroup
case KindClosure.String():
*l = KindClosure
}
return fmt.Errorf("%w:filed(%v)", ErrUndefined, string(in))
}
func (l Kind) MarshalBinary() ([]byte, error) {
return []byte(l.String()), nil
}
func (l *Kind) UnmarshalBinary(in []byte) error {
return l.UnmarshalText(in)
}

View File

@@ -57,9 +57,14 @@ func BoolValue(v bool) Value {
func BoolsValue(values []bool) Value { func BoolsValue(values []bool) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindBool, any: func() []Value {
any: values, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = BoolValue(values[idx])
}
return vals
}, },
} }
} }
@@ -79,12 +84,33 @@ func Uint64Value(v uint64) Value {
} }
// Uint64sValue returns a Value for a []uint64. // Uint64sValue returns a Value for a []uint64.
func Uint64sValue(v []uint64) Value { func Uint64sValue(values []uint64) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindUint64, any: func() []Value {
any: v, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = Uint64Value(values[idx])
}
return vals
},
}
}
// Uint8sValue returns a Value for a []uint8.
func Uint8sValue(values []uint8) Value {
return Value{
Kind: KindArray,
num: uint64(len(values)),
any: func() []Value {
vals := make([]Value, len(values))
for idx := range values {
vals[idx] = Uint64Value(uint64(values[idx]))
}
return vals
}, },
} }
} }
@@ -107,9 +133,14 @@ func Int64Value(value int64) Value {
func Int64sValue(value []int64) Value { func Int64sValue(value []int64) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(value)),
Kind: KindInt64, any: func() []Value {
any: value, vals := make([]Value, len(value))
for idx := range value {
vals[idx] = Int64Value(value[idx])
}
return vals
}, },
} }
} }
@@ -129,12 +160,17 @@ func Float64Value(v float64) Value {
} }
// Float64Value returns a Value for a floating-points number. // Float64Value returns a Value for a floating-points number.
func Float64sValue(v []float64) Value { func Float64sValue(values []float64) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindFloat64, any: func() []Value {
any: v, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = Float64Value(values[idx])
}
return vals
}, },
} }
} }
@@ -148,6 +184,22 @@ func Float64pValue(v *float64) Value {
return Float64Value(*v) return Float64Value(*v)
} }
// Complex64sValue returns a Value for a []complex64.
func Complex64sValue(values []complex64) Value {
return Value{
Kind: KindArray,
num: uint64(len(values)),
any: func() []Value {
vals := make([]Value, len(values))
for idx := range values {
vals[idx] = Complex128Value(complex128(values[idx]))
}
return vals
},
}
}
// Complex128Value returns a Value for a complex128. // Complex128Value returns a Value for a complex128.
func Complex128Value(v complex128) Value { func Complex128Value(v complex128) Value {
return Value{ return Value{
@@ -157,12 +209,17 @@ func Complex128Value(v complex128) Value {
} }
// Complex128Value returns a Value for a []complex128. // Complex128Value returns a Value for a []complex128.
func Complex128sValue(v []complex128) Value { func Complex128sValue(values []complex128) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindComplex128, any: func() []Value {
any: v, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = Complex128Value(values[idx])
}
return vals
}, },
} }
} }
@@ -191,12 +248,17 @@ func TimepValue(v *time.Time) Value {
} }
// TimesValue returns a Value for a []time.Time. // TimesValue returns a Value for a []time.Time.
func TimesValue(v []time.Time) Value { func TimesValue(values []time.Time) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindTime, any: func() []Value {
any: v, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = TimeValue(values[idx])
}
return vals
}, },
} }
} }
@@ -223,12 +285,17 @@ func DurationpValue(v *time.Duration) Value {
} }
// DurationValue returns a Value for a *time.Duration. // DurationValue returns a Value for a *time.Duration.
func DurationsValue(v []time.Duration) Value { func DurationsValue(values []time.Duration) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(values)),
Kind: KindDuration, any: func() []Value {
any: v, vals := make([]Value, len(values))
for idx := range values {
vals[idx] = DurationValue(values[idx])
}
return vals
}, },
} }
} }
@@ -252,9 +319,14 @@ func ErrorValue(value error) Value {
func ErrorsValue(value []error) Value { func ErrorsValue(value []error) Value {
return Value{ return Value{
Kind: KindArray, Kind: KindArray,
any: Value{ num: uint64(len(value)),
Kind: KindError, any: func() []Value {
any: value, vals := make([]Value, len(value))
for idx := range value {
vals[idx] = ErrorValue(value[idx])
}
return vals
}, },
} }
} }
@@ -314,6 +386,8 @@ func AnyValue(v any) Value {
return Complex128sValue(value) return Complex128sValue(value)
case complex64: case complex64:
return Complex128Value(complex128(value)) return Complex128Value(complex128(value))
case []complex64:
return Complex64sValue(value)
case time.Duration: case time.Duration:
return DurationValue(value) return DurationValue(value)
case *time.Duration: case *time.Duration:
@@ -328,6 +402,8 @@ func AnyValue(v any) Value {
return TimesValue(value) return TimesValue(value)
case uint8: case uint8:
return Uint64Value(uint64(value)) return Uint64Value(uint64(value))
case []uint8:
return Uint8sValue(value)
case uint16: case uint16:
return Uint64Value(uint64(value)) return Uint64Value(uint64(value))
case uint32: case uint32:

View File

@@ -2,10 +2,12 @@ package log_test
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"math" "math"
"os" "os"
"sync/atomic" "sync/atomic"
"time"
"gitoa.ru/go-4devs/log" "gitoa.ru/go-4devs/log"
"gitoa.ru/go-4devs/log/entry" "gitoa.ru/go-4devs/log/entry"
@@ -13,7 +15,6 @@ import (
"gitoa.ru/go-4devs/log/level" "gitoa.ru/go-4devs/log/level"
) )
//nolint:gochecknoglobals
var ctx = context.Background() var ctx = context.Background()
func setStdout() { func setStdout() {
@@ -68,6 +69,141 @@ type Obj struct {
IsEnable bool IsEnable bool
} }
var (
obj = Obj{
Name: "test obj",
}
str = "test str"
boolsVal = true
intVal = int(math.MaxInt)
int8Val = int8(math.MaxInt8)
int16Val = int16(math.MaxInt16)
int32Val = int32(math.MaxInt32)
int64Val = int64(math.MaxInt64)
uintVal = uint(math.MaxUint)
uint8Val = uint8(math.MaxUint8)
uint16Val = uint16(math.MaxInt16)
uint32Val = uint32(math.MaxInt32)
uint64Val = uint64(math.MaxInt64)
float32Val = float32(math.MaxFloat32)
float64Val = float64(math.MaxFloat64)
minute = time.Minute
timeVal = time.Unix(0, math.MaxInt32)
)
func ExampleNew_anyField() {
logger := log.New(log.WithStdout(), log.WithJSONFormat())
logger.InfoKV(ctx, "any info message",
field.Any("obj", Obj{Name: "obj name"}),
field.Any("obj", &obj),
field.Any("int", intVal),
field.Any("uint", uintVal),
field.Any("float", float64Val),
field.Any("time", timeVal),
field.Any("duration", time.Hour),
field.Any("error", errors.New("error")),
)
// Output:
// {"msg":"any info message","obj":{"Name":"obj name","IsEnable":false},"obj":{"Name":"test obj","IsEnable":false},"int":9223372036854775807,"uint":18446744073709551615,"float":1.7976931348623157e+308,"time":"1970-01-01T03:00:02+03:00","duration":"1h0m0s","error":"error"}
}
func ExampleNew_arrayField() {
logger := log.New(log.WithStdout(), log.WithJSONFormat())
logger.InfoKV(ctx, "array info message",
field.Strings("strings", "string", str),
field.Bools("bools", true, false),
field.Ints("ints", 42, 24),
field.Int8s("int8s", 42, 24),
field.Int16s("int16s", 42, 24),
field.Int32s("int32s", 42, 24),
field.Int64s("int64s", 42, 24),
field.Uint8s("uint8s", uint8Val, 0),
field.Uint16s("uint16s", 42, 24),
field.Uint32s("uint32s", 42, 24),
field.Uint64s("uint64s", 42, 24),
field.Float32s("float32s", 42, 24),
field.Float64s("float64s", 42, 24),
field.Complex64s("complex64s", 42, 24),
field.Complex128s("complex128s", 42, 24),
field.Durations("durations", time.Minute, time.Second),
field.Times("times", time.Unix(0, 42), time.Unix(0, 24)),
field.Errors("errors", errors.New("error"), errors.New("error2")),
)
// Output:
// {"msg":"array info message","strings":["string","test str"],"bools":[true,false],"ints":[42,24],"int8s":[42,24],"int16s":[42,24],"int32s":[42,24],"int64s":[42,24],"uint8s":[255,0],"uint16s":[42,24],"uint32s":[42,24],"uint64s":[42,24],"float32s":[42,24],"float64s":[42,24],"complex64s":["(42+0i)","(24+0i)"],"complex128s":["(42+0i)","(24+0i)"],"durations":["1m0s","1s"],"times":["1970-01-01T03:00:00+03:00","1970-01-01T03:00:00+03:00"],"errors":["error","error2"]}
}
func ExampleNew_pointerField() {
logger := log.New(log.WithStdout(), log.WithJSONFormat())
logger.InfoKV(ctx, "pointer info message",
field.Stringp("stringp", &str),
field.Stringp("stringp", nil),
field.Boolp("boolp", &boolsVal),
field.Boolp("boolp", nil),
field.Intp("intp", &intVal),
field.Intp("intp", nil),
field.Int8p("int8p", &int8Val),
field.Int8p("int8p", nil),
field.Int16p("int16p", &int16Val),
field.Int16p("int16p", nil),
field.Int32p("int32p", &int32Val),
field.Int32p("int32p", nil),
field.Int64p("int64p", &int64Val),
field.Int64p("int64p", nil),
field.Uintp("uintp", &uintVal),
field.Uintp("uintp", nil),
field.Uint8p("uint8p", &uint8Val),
field.Uint8p("uint8p", nil),
field.Uint16p("uint16p", &uint16Val),
field.Uint16p("uint16p", nil),
field.Uint32p("uint32p", &uint32Val),
field.Uint32p("uint32p", nil),
field.Uint64p("uint64p", &uint64Val),
field.Uint64p("uint64p", nil),
field.Float32p("float32p", &float32Val),
field.Float32p("float32p", nil),
field.Float64p("float64p", &float64Val),
field.Float64p("float64p", nil),
field.Durationp("durationp", &minute),
field.Durationp("durationp", nil),
field.Timep("timep", &timeVal),
field.Timep("timep", nil),
)
// Output:
// {"msg":"pointer info message","stringp":"test str","stringp":null,"boolp":true,"boolp":null,"intp":9223372036854775807,"intp":null,"int8p":127,"int8p":null,"int16p":32767,"int16p":null,"int32p":2147483647,"int32p":null,"int64p":9223372036854775807,"int64p":null,"uintp":18446744073709551615,"uintp":null,"uint8p":255,"uint8p":null,"uint16p":32767,"uint16p":null,"uint32p":2147483647,"uint32p":null,"uint64p":9223372036854775807,"uint64p":null,"float32p":3.4028235e+38,"float32p":null,"float64p":1.7976931348623157e+308,"float64p":null,"durationp":"1m0s","durationp":null,"timep":"1970-01-01T03:00:02+03:00","timep":null}
}
func ExampleNew_fields() {
logger := log.New(log.WithStdout(), log.WithJSONFormat())
logger.InfoKV(ctx, "info message",
field.String("string", str),
field.Bool("bool", true),
field.Int("int", 42),
field.Int8("int8", 42),
field.Int16("int16", 42),
field.Int32("int32", 42),
field.Int64("int64", 42),
field.Uint8("uint8", uint8Val),
field.Uint16("uint16", 42),
field.Uint32("uint32", 42),
field.Uint64("uint64", 42),
field.Float32("float32", 42),
field.Float64("float64", 42),
field.Complex64("complex16", 42),
field.Complex128("complex128", 42),
field.Duration("duration", time.Minute),
field.Time("time", time.Unix(0, 42)),
field.FormatTime("format_time", time.UnixDate, timeVal),
field.Error("error", errors.New("error")),
)
// Output:
// {"msg":"info message","string":"test str","bool":true,"int":42,"int8":42,"int16":42,"int32":42,"int64":42,"uint8":255,"uint16":42,"uint32":42,"uint64":42,"float32":42,"float64":42,"complex16":"(42+0i)","complex128":"(42+0i)","duration":"1m0s","time":"1970-01-01T03:00:00+03:00","format_time":"Thu Jan 1 03:00:02 MSK 1970","error":"error"}
}
func ExampleNew_jsonFormat() { func ExampleNew_jsonFormat() {
logger := log.New(log.WithStdout(), log.WithJSONFormat()). logger := log.New(log.WithStdout(), log.WithJSONFormat()).
With( With(

View File

@@ -13,7 +13,6 @@ import (
"gitoa.ru/go-4devs/log/level" "gitoa.ru/go-4devs/log/level"
) )
//nolint:gochecknoglobals
var requestID ctxKey = "requestID" var requestID ctxKey = "requestID"
func TestFields(t *testing.T) { func TestFields(t *testing.T) {