package log_test
import (
"context"
"errors"
"fmt"
"math"
"os"
"sync/atomic"
"time"
"gitoa.ru/go-4devs/log"
"gitoa.ru/go-4devs/log/entry"
"gitoa.ru/go-4devs/log/field"
"gitoa.ru/go-4devs/log/level"
)
var ctx = context . Background ( )
func setStdout ( ) {
// set stout for example by default stderror
log . SetLogger ( log . New ( log . WithStdout ( ) ) . With ( log . WithLevel ( log . KeyLevel , level . Debug ) ) )
}
func ExampleNew ( ) {
logger := log . New ( log . WithStdout ( ) )
logger . Info ( ctx , "same message" )
// Output: msg="same message"
}
func ExampleInfo ( ) {
setStdout ( )
log . Info ( ctx , "same message" )
// Output: msg="same message" level=info
}
func ExampleErrKV ( ) {
setStdout ( )
log . ErrKVs ( ctx , "same message" , "key" , "addition value" )
// Output: msg="same message" key="addition value" level=error
}
func ExampleNew_errf ( ) {
logger := log . New ( log . WithStdout ( ) )
logger . Errf ( ctx , "same message %d" , 1 )
// Output: msg="same message 1"
}
func ExampleNew_debugKV ( ) {
logger := log . New ( log . WithStdout ( ) ) . With ( log . WithLevel ( log . KeyLevel , level . Debug ) )
logger . DebugKVs ( ctx , "same message" , "error" , os . ErrNotExist )
// Output: msg="same message" error="file does not exist" level=debug
}
func ExampleNew_level ( ) {
logger := log . New ( log . WithStdout ( ) ) . With ( log . WithLevel ( log . KeyLevel , level . Error ) )
logger . Err ( ctx , "same error message" )
// Output: msg="same error message" level=error
}
func ExampleNew_level_info ( ) {
logger := log . New ( log . WithStdout ( ) ) . With ( log . WithLevel ( log . KeyLevel , level . Error ) )
logger . Info ( ctx , "same message" )
// Output:
}
type Obj struct {
Name string
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 ) . In ( time . UTC )
)
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-01T00:00:02Z","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 ) . In ( time . UTC ) , time . Unix ( 0 , 24 ) . In ( time . UTC ) ) ,
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-01T00:00:00Z","1970-01-01T00:00:00Z"],"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-01T00:00:02Z","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" , timeVal ) ,
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-01T00:00:02Z","format_time":"Thu Jan 1 00:00:02 UTC 1970","error":"error"}
}
func ExampleNew_jsonFormat ( ) {
logger := log . New ( log . WithStdout ( ) , log . WithJSONFormat ( ) ) .
With (
log . WithLevel ( log . KeyLevel , level . Debug ) ,
log . GoVersion ( "go-version" ) ,
)
logger . Err ( ctx , "same error message" )
logger . WarnKVs ( ctx , "same warn message" , "obj" , Obj { Name : "obj name" } )
// Output:
// {"msg":"same error message","level":"error","go-version":"go1.21.5"}
// {"msg":"same warn message","obj":{"Name":"obj name","IsEnable":false},"level":"warning","go-version":"go1.21.5"}
}
func ExampleNew_textEncoding ( ) {
logger := log . New ( log . WithStdout ( ) ) .
With (
log . WithLevel ( log . KeyLevel , level . Debug ) ,
log . GoVersion ( "go-version" ) ,
)
logger . Err ( ctx , "same error message" )
logger . InfoKVs ( ctx , "same info message" , "api-version" , 0.1 , "obj" , Obj { Name : "text value" , IsEnable : true } )
// Output:
// msg="same error message" level=error go-version=go1.21.5
// msg="same info message" api-version=0.1 obj={Name:text value IsEnable:true} level=info go-version=go1.21.5
}
type ctxKey string
func ( c ctxKey ) String ( ) string {
return string ( c )
}
func levelInfo ( ctx context . Context , entry * entry . Entry , handler log . Logger ) ( int , error ) {
return handler ( ctx , entry . Add ( field . String ( log . KeyLevel , entry . Level ( ) . String ( ) ) ) )
}
func ExampleWith ( ) {
var requestID ctxKey = "requestID"
vctx := context . WithValue ( ctx , requestID , "6a5fa048-7181-11ea-bc55-0242ac130003" )
logger := log . New ( log . WithStdout ( ) ) . With (
levelInfo ,
log . WithContextValue ( requestID ) ,
log . KeyValue ( "api" , "0.1.0" ) ,
log . GoVersion ( "go" ) ,
)
logger . Info ( vctx , "same message" )
// Output: msg="same message" level=info requestID=6a5fa048-7181-11ea-bc55-0242ac130003 api=0.1.0 go=go1.21.5
}
func ExampleLogger_Print ( ) {
logger := log . New ( log . WithStdout ( ) ) . With (
levelInfo ,
log . KeyValue ( "client" , "http" ) ,
log . KeyValue ( "api" , "0.1.0" ) ,
log . GoVersion ( "go" ) ,
)
logger . Print ( "same message" )
// Output: msg="same message" level=info client=http api=0.1.0 go=go1.21.5
}
func ExamplePrint ( ) {
setStdout ( )
log . Print ( "same message" )
// Output: msg="same message" level=info
}
func Example_fieldClosureFn ( ) {
cnt := int32 ( 0 )
closure := field . ClosureFn ( func ( ) any {
d := fmt . Sprintf ( "additional error data: %d" , cnt )
atomic . AddInt32 ( & cnt , 1 )
return d
} )
log := log . New ( log . WithStdout ( ) ) . With ( log . WithLevel ( log . KeyLevel , level . Info ) )
log . DebugKVs ( ctx , "debug message" , "data" , closure )
log . ErrKVs ( ctx , "error message" , "err" , closure )
log . WarnKVs ( ctx , "warn message" , "warn" , closure )
// Output:
// msg="error message" err="additional error data: 0" level=error
// msg="warn message" warn="additional error data: 1" level=warning
}
func Example_withGroup ( ) {
log := log . New ( log . WithStdout ( ) ) . With (
log . WithLevel ( log . KeyLevel , level . Info ) ,
)
log . ErrKVs ( ctx , "error message" ,
field . Groups ( "grous_field" ,
field . Error ( "err" , os . ErrDeadlineExceeded ) ,
field . Bool ( "bool" , false ) ,
) ,
)
log . WarnKV ( ctx , "error message" , field . ValuerFn ( "valuer_field" , func ( ) any {
return field . Fields {
field . Int ( "int_value" , math . MaxInt ) ,
field . Uint8 ( "uint8_value" , math . MaxUint8 ) ,
}
} ) )
// Output:
// msg="error message" grous_field.err="i/o timeout" grous_field.bool=false level=error
// msg="error message" valuer_field.int_value=9223372036854775807 valuer_field.uint8_value=255 level=warning
}