tlog.app/go/tlog@v0.23.1/tlog_test.go (about) 1 package tlog 2 3 import ( 4 "io" 5 "runtime" 6 "sync" 7 "testing" 8 9 "github.com/nikandfor/assert" 10 "github.com/nikandfor/hacked/low" 11 "tlog.app/go/loc" 12 13 "tlog.app/go/tlog/tlwire" 14 ) 15 16 func TestLoggerSmoke(t *testing.T) { 17 var buf low.Buf 18 19 l := New(&buf) 20 21 l.Printf("message %v %v", 1, "two") 22 23 t.Logf("dump:\n%v", tlwire.Dump(buf)) 24 buf = buf[:0] 25 26 l.Printw("message", "a", -1, "b", "two") 27 28 t.Logf("dump:\n%v", tlwire.Dump(buf)) 29 buf = buf[:0] 30 31 l.NewMessage(0, ID{}, "") 32 33 t.Logf("dump:\n%v", tlwire.Dump(buf)) 34 buf = buf[:0] 35 } 36 37 func TestLoggerSmokeConcurrent(t *testing.T) { 38 const N = 1000 39 40 var wg sync.WaitGroup 41 var buf low.Buf 42 43 l := New(&buf) 44 45 wg.Add(1) 46 go func() { 47 defer wg.Done() 48 49 for i := 0; i < N; i++ { 50 l.Printf("printf %v %v", i+1000, i+1001) 51 } 52 }() 53 54 wg.Add(1) 55 go func() { 56 defer wg.Done() 57 58 for i := 0; i < N; i++ { 59 l.Printw("printw", "i0", i+1000, "i1", i+1001) 60 } 61 }() 62 63 wg.Add(1) 64 go func() { 65 defer wg.Done() 66 67 for i := 0; i < N; i++ { 68 tr := l.Start("span") 69 tr.Printw("span.printw", "i0", i+1000, "i1", i+1001) 70 tr.Finish() 71 } 72 }() 73 74 wg.Add(1) 75 go func() { 76 defer wg.Done() 77 78 for i := 0; i < N; i++ { 79 tr := l.Start("span_observer") 80 _ = tr.Event("value", i+1000) 81 tr.Finish() 82 } 83 }() 84 85 wg.Wait() 86 } 87 88 func TestLoggerSetCallers(t *testing.T) { 89 nextLine := func() int { 90 _, _, line := loc.Caller(1).NameFileLine() 91 return line + 1 92 } 93 94 var buf low.Buf 95 var off int 96 97 l := New(&buf) 98 99 LoggerSetTimeNow(l, nil, nil) 100 101 exp := nextLine() 102 l.Printw("hello default caller") 103 104 checkCaller(t, exp, true, buf[off:]) 105 off = len(buf) 106 107 // 108 109 LoggerSetCallers(l, 0, runtime.Callers) 110 111 exp = nextLine() 112 l.Printw("hello runtime caller") 113 114 checkCaller(t, exp, true, buf[off:]) 115 off = len(buf) 116 117 LoggerSetCallers(l, 0, func(skip int, pc []uintptr) int { 118 t.Logf("skip for custom logger: %v", skip) 119 120 pc[0] = 0x777 121 loc.SetCache(loc.PC(pc[0]), "name", "file", 877) 122 return 1 123 }) 124 125 l.Printw("hello custom caller") 126 127 checkCaller(t, 877, true, buf[off:]) 128 off = len(buf) 129 130 LoggerSetCallers(l, 0, nil) 131 132 l.Printw("hello no caller") 133 134 checkCaller(t, 0, false, buf[off:]) 135 off = len(buf) //nolint:ineffassign,staticcheck,wastedassign 136 137 if t.Failed() { 138 t.Logf("dump:\n%v", tlwire.Dump(buf)) 139 buf = buf[:0] 140 } 141 } 142 143 func checkCaller(t *testing.T, line int, exists bool, b []byte) { 144 t.Helper() 145 146 var d tlwire.Decoder 147 var msg []byte 148 var pc loc.PC 149 found := false 150 151 tag, sub, i := d.Tag(b, 0) 152 if tag != tlwire.Map { 153 t.Errorf("not a map object") 154 return 155 } 156 157 for el := 0; sub == -1 || el < int(sub); el++ { 158 if d.Break(b, &i) { 159 break 160 } 161 162 var key []byte 163 key, i = d.Bytes(b, i) 164 165 tag, sem, vst := d.Tag(b, i) 166 167 switch { 168 case tag == tlwire.Semantic && sem == WireMessage && string(key) == KeyMessage: 169 msg, i = d.Bytes(b, vst) 170 case tag == tlwire.Semantic && sem == tlwire.Caller && string(key) == KeyCaller: 171 pc, i = d.Caller(b, i) 172 found = true 173 default: 174 i = d.Skip(b, i) 175 } 176 } 177 178 assert.Equal(t, exists, found, "msg: %s", msg) 179 180 if found { 181 _, _, pcline := pc.NameFileLine() 182 assert.Equal(t, line, pcline, "msg: %s", msg) 183 } 184 } 185 186 func BenchmarkLoggerPrintw(b *testing.B) { 187 b.ReportAllocs() 188 189 l := New(io.Discard) 190 191 for i := 0; i < b.N; i++ { 192 l.Printw("message", "a", i+1000, "b", i+1000, "c", "str") 193 } 194 } 195 196 func BenchmarkLoggerPrintf(b *testing.B) { 197 b.ReportAllocs() 198 199 l := New(io.Discard) 200 201 for i := 0; i < b.N; i++ { 202 l.Printf("message a %v b %v c %v", i+1000, i+1000, "str") 203 } 204 } 205 206 func BenchmarkLoggerStartPrintwFinish(b *testing.B) { 207 b.ReportAllocs() 208 209 l := New(io.Discard) 210 211 for i := 0; i < b.N; i++ { 212 tr := l.Start("span_name") 213 tr.Printw("message", "a", i+1000, "b", i+1000, "c", "str") 214 tr.Finish() 215 } 216 }