github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/libs/log/ocfmt_logger_test.go (about) 1 package log_test 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "math" 8 "regexp" 9 "testing" 10 11 kitlog "github.com/go-kit/log" 12 "github.com/stretchr/testify/assert" 13 14 "github.com/line/ostracon/libs/log" 15 ) 16 17 func TestOCFmtLogger(t *testing.T) { 18 t.Parallel() 19 buf := &bytes.Buffer{} 20 logger := log.NewOCFmtLogger(buf) 21 22 if err := logger.Log("hello", "world"); err != nil { 23 t.Fatal(err) 24 } 25 assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ hello=world\n$`), buf.String()) 26 27 buf.Reset() 28 if err := logger.Log("a", 1, "err", errors.New("error")); err != nil { 29 t.Fatal(err) 30 } 31 assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ a=1 err=error\n$`), buf.String()) 32 33 buf.Reset() 34 if err := logger.Log("std_map", map[int]int{1: 2}, "my_map", mymap{0: 0}); err != nil { 35 t.Fatal(err) 36 } 37 assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ std_map=map\[1:2\] my_map=special_behavior\n$`), buf.String()) 38 39 buf.Reset() 40 if err := logger.Log("level", "error"); err != nil { 41 t.Fatal(err) 42 } 43 assert.Regexp(t, regexp.MustCompile(`E\[.+\] unknown \s+\n$`), buf.String()) 44 45 buf.Reset() 46 if err := logger.Log("_msg", "Hello"); err != nil { 47 t.Fatal(err) 48 } 49 assert.Regexp(t, regexp.MustCompile(`N\[.+\] Hello \s+\n$`), buf.String()) 50 51 buf.Reset() 52 if err := logger.Log("module", "main", "module", "crypto", "module", "wire"); err != nil { 53 t.Fatal(err) 54 } 55 assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+module=wire\s+\n$`), buf.String()) 56 57 buf.Reset() 58 if err := logger.Log("hash", []byte("test me")); err != nil { 59 t.Fatal(err) 60 } 61 assert.Regexp(t, regexp.MustCompile(`N\[.+\] unknown \s+ hash=74657374206D65\n$`), buf.String()) 62 } 63 64 func BenchmarkOCFmtLoggerSimple(b *testing.B) { 65 benchmarkRunnerKitlog(b, log.NewOCFmtLogger(io.Discard), baseMessage) 66 } 67 68 func BenchmarkOCFmtLoggerContextual(b *testing.B) { 69 benchmarkRunnerKitlog(b, log.NewOCFmtLogger(io.Discard), withMessage) 70 } 71 72 func TestOCFmtLoggerConcurrency(t *testing.T) { 73 t.Parallel() 74 testConcurrency(t, log.NewOCFmtLogger(io.Discard), 10000) 75 } 76 77 func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Logger)) { 78 lc := kitlog.With(logger, "common_key", "common_value") 79 b.ReportAllocs() 80 b.ResetTimer() 81 for i := 0; i < b.N; i++ { 82 f(lc) 83 } 84 } 85 86 var ( 87 baseMessage = func(logger kitlog.Logger) { logger.Log("foo_key", "foo_value") } //nolint:errcheck 88 withMessage = func(logger kitlog.Logger) { kitlog.With(logger, "a", "b").Log("d", "f") } //nolint:errcheck 89 ) 90 91 // These test are designed to be run with the race detector. 92 93 func testConcurrency(t *testing.T, logger kitlog.Logger, total int) { 94 n := int(math.Sqrt(float64(total))) 95 share := total / n 96 97 errC := make(chan error, n) 98 99 for i := 0; i < n; i++ { 100 go func() { 101 errC <- spam(logger, share) 102 }() 103 } 104 105 for i := 0; i < n; i++ { 106 err := <-errC 107 if err != nil { 108 t.Fatalf("concurrent logging error: %v", err) 109 } 110 } 111 } 112 113 func spam(logger kitlog.Logger, count int) error { 114 for i := 0; i < count; i++ { 115 err := logger.Log("key", i) 116 if err != nil { 117 return err 118 } 119 } 120 return nil 121 } 122 123 type mymap map[int]int 124 125 func (m mymap) String() string { return "special_behavior" }