go.undefinedlabs.com/scopeagent@v0.4.2/instrumentation/testing/logger.go (about) 1 package testing 2 3 import ( 4 "fmt" 5 "sync" 6 "testing" 7 _ "unsafe" 8 9 "github.com/opentracing/opentracing-go/log" 10 "github.com/undefinedlabs/go-mpatch" 11 12 "go.undefinedlabs.com/scopeagent/instrumentation" 13 "go.undefinedlabs.com/scopeagent/tags" 14 ) 15 16 var ( 17 patchLock sync.Mutex 18 19 errorPatch *mpatch.Patch 20 errorfPatch *mpatch.Patch 21 fatalPatch *mpatch.Patch 22 fatalfPatch *mpatch.Patch 23 logPatch *mpatch.Patch 24 logfPatch *mpatch.Patch 25 skipPatch *mpatch.Patch 26 skipfPatch *mpatch.Patch 27 ) 28 29 //go:linkname llog testing.(*common).log 30 func llog(t *testing.T, s string) 31 32 //go:linkname lError testing.(*common).Error 33 func lError(t *testing.T, args ...interface{}) 34 35 //go:linkname lErrorf testing.(*common).Errorf 36 func lErrorf(t *testing.T, format string, args ...interface{}) 37 38 //go:linkname lFatal testing.(*common).Fatal 39 func lFatal(t *testing.T, args ...interface{}) 40 41 //go:linkname lFatalf testing.(*common).Fatalf 42 func lFatalf(t *testing.T, format string, args ...interface{}) 43 44 //go:linkname lLog testing.(*common).Log 45 func lLog(t *testing.T, args ...interface{}) 46 47 //go:linkname lLogf testing.(*common).Logf 48 func lLogf(t *testing.T, format string, args ...interface{}) 49 50 //go:linkname lSkip testing.(*common).Skip 51 func lSkip(t *testing.T, args ...interface{}) 52 53 //go:linkname lSkipf testing.(*common).Skipf 54 func lSkipf(t *testing.T, format string, args ...interface{}) 55 56 func PatchTestingLogger() { 57 patchError() 58 patchErrorf() 59 patchFatal() 60 patchFatalf() 61 patchLog() 62 patchLogf() 63 patchSkip() 64 patchSkipf() 65 } 66 67 func UnpatchTestingLogger() { 68 patchLock.Lock() 69 defer patchLock.Unlock() 70 71 if errorPatch != nil { 72 logOnError(errorPatch.Unpatch()) 73 } 74 if errorfPatch != nil { 75 logOnError(errorfPatch.Unpatch()) 76 } 77 if fatalPatch != nil { 78 logOnError(fatalPatch.Unpatch()) 79 } 80 if fatalfPatch != nil { 81 logOnError(fatalfPatch.Unpatch()) 82 } 83 if logPatch != nil { 84 logOnError(logPatch.Unpatch()) 85 } 86 if logfPatch != nil { 87 logOnError(logfPatch.Unpatch()) 88 } 89 if skipPatch != nil { 90 logOnError(skipPatch.Unpatch()) 91 } 92 if skipfPatch != nil { 93 logOnError(skipfPatch.Unpatch()) 94 } 95 } 96 97 func patchError() { 98 patchWithArgs(&errorPatch, lError, func(test *Test, args ...interface{}) { 99 test.t.Helper() 100 s := fmt.Sprintln(args...) 101 if test.span != nil { 102 test.span.LogFields( 103 log.String(tags.EventType, tags.LogEvent), 104 log.String(tags.EventMessage, s), 105 log.String(tags.EventSource, getSourceFileAndNumber(2)), 106 log.String(tags.LogEventLevel, tags.LogLevel_ERROR), 107 log.String("log.internal_level", "Error"), 108 log.String("log.logger", "testing"), 109 ) 110 } 111 llog(test.t, s) 112 test.t.Fail() 113 }) 114 } 115 116 func patchErrorf() { 117 patchWithFormatAndArgs(&errorfPatch, lErrorf, func(test *Test, format string, args ...interface{}) { 118 test.t.Helper() 119 s := fmt.Sprintf(format, args...) 120 if test.span != nil { 121 test.span.LogFields( 122 log.String(tags.EventType, tags.LogEvent), 123 log.String(tags.EventMessage, s), 124 log.String(tags.EventSource, getSourceFileAndNumber(2)), 125 log.String(tags.LogEventLevel, tags.LogLevel_ERROR), 126 log.String("log.internal_level", "Error"), 127 log.String("log.logger", "testing"), 128 ) 129 } 130 llog(test.t, s) 131 test.t.Fail() 132 }) 133 } 134 135 func patchFatal() { 136 patchWithArgs(&fatalPatch, lFatal, func(test *Test, args ...interface{}) { 137 test.t.Helper() 138 s := fmt.Sprintln(args...) 139 if test.span != nil { 140 test.span.LogFields( 141 log.String(tags.EventType, tags.EventTestFailure), 142 log.String(tags.EventMessage, s), 143 log.String(tags.EventSource, getSourceFileAndNumber(2)), 144 log.String("log.internal_level", "Fatal"), 145 log.String("log.logger", "testing"), 146 ) 147 } 148 llog(test.t, s) 149 test.t.FailNow() 150 }) 151 } 152 153 func patchFatalf() { 154 patchWithFormatAndArgs(&fatalfPatch, lFatalf, func(test *Test, format string, args ...interface{}) { 155 test.t.Helper() 156 s := fmt.Sprintf(format, args...) 157 if test.span != nil { 158 test.span.LogFields( 159 log.String(tags.EventType, tags.EventTestFailure), 160 log.String(tags.EventMessage, s), 161 log.String(tags.EventSource, getSourceFileAndNumber(2)), 162 log.String("log.internal_level", "Fatal"), 163 log.String("log.logger", "testing"), 164 ) 165 } 166 llog(test.t, s) 167 test.t.FailNow() 168 }) 169 } 170 171 func patchLog() { 172 patchWithArgs(&logPatch, lLog, func(test *Test, args ...interface{}) { 173 test.t.Helper() 174 s := fmt.Sprintln(args...) 175 if test.span != nil { 176 test.span.LogFields( 177 log.String(tags.EventType, tags.LogEvent), 178 log.String(tags.EventMessage, s), 179 log.String(tags.EventSource, getSourceFileAndNumber(2)), 180 log.String(tags.LogEventLevel, tags.LogLevel_INFO), 181 log.String("log.internal_level", "Log"), 182 log.String("log.logger", "testing"), 183 ) 184 } 185 llog(test.t, s) 186 }) 187 } 188 189 func patchLogf() { 190 patchWithFormatAndArgs(&logfPatch, lLogf, func(test *Test, format string, args ...interface{}) { 191 test.t.Helper() 192 s := fmt.Sprintf(format, args...) 193 if test.span != nil { 194 test.span.LogFields( 195 log.String(tags.EventType, tags.LogEvent), 196 log.String(tags.EventMessage, s), 197 log.String(tags.EventSource, getSourceFileAndNumber(2)), 198 log.String(tags.LogEventLevel, tags.LogLevel_INFO), 199 log.String("log.internal_level", "Log"), 200 log.String("log.logger", "testing"), 201 ) 202 } 203 llog(test.t, s) 204 }) 205 } 206 207 func patchSkip() { 208 patchWithArgs(&skipPatch, lSkip, func(test *Test, args ...interface{}) { 209 test.t.Helper() 210 s := fmt.Sprintln(args...) 211 if test.span != nil { 212 test.span.LogFields( 213 log.String(tags.EventType, tags.EventTestSkip), 214 log.String(tags.EventMessage, s), 215 log.String(tags.EventSource, getSourceFileAndNumber(2)), 216 log.String("log.internal_level", "Skip"), 217 log.String("log.logger", "testing"), 218 ) 219 } 220 llog(test.t, s) 221 test.t.SkipNow() 222 }) 223 } 224 225 func patchSkipf() { 226 patchWithFormatAndArgs(&skipfPatch, lSkipf, func(test *Test, format string, args ...interface{}) { 227 test.t.Helper() 228 s := fmt.Sprintf(format, args...) 229 if test.span != nil { 230 test.span.LogFields( 231 log.String(tags.EventType, tags.EventTestSkip), 232 log.String(tags.EventMessage, s), 233 log.String(tags.EventSource, getSourceFileAndNumber(2)), 234 log.String("log.internal_level", "Skip"), 235 log.String("log.logger", "testing"), 236 ) 237 } 238 llog(test.t, s) 239 test.t.SkipNow() 240 }) 241 } 242 243 func patchWithArgs(patchValue **mpatch.Patch, method interface{}, methodBody func(test *Test, args ...interface{})) { 244 lPatch, err := mpatch.PatchMethod(method, func(t *testing.T, args ...interface{}) { 245 if t == nil { 246 instrumentation.Logger().Println("testing.T is nil") 247 return 248 } 249 t.Helper() 250 test := GetTest(t) 251 if test == nil { 252 instrumentation.Logger().Printf("test struct for %v doesn't exist\n", t.Name()) 253 return 254 } 255 methodBody(test, args...) 256 }) 257 logOnError(err) 258 *patchValue = lPatch 259 } 260 261 func patchWithFormatAndArgs(patchValue **mpatch.Patch, method interface{}, methodBody func(test *Test, format string, args ...interface{})) { 262 lPatch, err := mpatch.PatchMethod(method, func(t *testing.T, format string, args ...interface{}) { 263 if t == nil { 264 instrumentation.Logger().Println("testing.T is nil") 265 return 266 } 267 t.Helper() 268 test := GetTest(t) 269 if test == nil { 270 instrumentation.Logger().Printf("test struct for %v doesn't exist\n", t.Name()) 271 return 272 } 273 methodBody(test, format, args...) 274 }) 275 logOnError(err) 276 *patchValue = lPatch 277 } 278 279 func logOnError(err error) { 280 if err != nil { 281 instrumentation.Logger().Println(err) 282 } 283 }