1package lightstep_test 2 3import ( 4 "bytes" 5 "net/http" 6 "sync/atomic" 7 "testing" 8 9 "github.com/lightstep/lightstep-tracer-common/golang/gogo/collectorpb/collectorpbfakes" 10 . "github.com/lightstep/lightstep-tracer-go" 11 "github.com/opentracing/opentracing-go" 12) 13 14type CountingRecorder int32 15 16func (c *CountingRecorder) RecordSpan(r RawSpan) { 17 atomic.AddInt32((*int32)(c), 1) 18} 19 20func newTestTracer(recorder SpanRecorder) opentracing.Tracer { 21 opts := Options{ 22 AccessToken: "token", 23 ConnFactory: fakeGrpcConnection(new(collectorpbfakes.FakeCollectorServiceClient)), 24 Recorder: recorder, 25 } 26 return NewTracer(opts) 27} 28 29var tags []string 30 31func init() { 32 tags = make([]string, 1000) 33 for j := 0; j < len(tags); j++ { 34 tags[j] = "big string very big huuuuuuuuge" 35 } 36} 37 38func executeOps(sp opentracing.Span, numEvent, numTag, numItems int) { 39 for j := 0; j < numEvent; j++ { 40 sp.LogEvent("event") 41 } 42 for j := 0; j < numTag; j++ { 43 sp.SetTag(tags[j], nil) 44 } 45 for j := 0; j < numItems; j++ { 46 sp.SetBaggageItem(tags[j], tags[j]) 47 } 48} 49 50func benchmarkWithOps(b *testing.B, numEvent, numTag, numItems int) { 51 var r CountingRecorder 52 t := newTestTracer(&r) 53 benchmarkWithOpsAndCB(b, func() opentracing.Span { 54 return t.StartSpan("test") 55 }, numEvent, numTag, numItems) 56 if int(r) != b.N { 57 b.Fatalf("missing traces: expected %d, got %d", b.N, r) 58 } 59} 60 61func benchmarkWithOpsAndCB(b *testing.B, create func() opentracing.Span, 62 numEvent, numTag, numItems int) { 63 b.ResetTimer() 64 for i := 0; i < b.N; i++ { 65 sp := create() 66 executeOps(sp, numEvent, numTag, numItems) 67 sp.Finish() 68 } 69 b.StopTimer() 70} 71 72func BenchmarkSpan_Empty(b *testing.B) { 73 benchmarkWithOps(b, 0, 0, 0) 74} 75 76func BenchmarkSpan_100Events(b *testing.B) { 77 benchmarkWithOps(b, 100, 0, 0) 78} 79 80func BenchmarkSpan_1000Events(b *testing.B) { 81 benchmarkWithOps(b, 100, 0, 0) 82} 83 84func BenchmarkSpan_100Tags(b *testing.B) { 85 benchmarkWithOps(b, 0, 100, 0) 86} 87 88func BenchmarkSpan_1000Tags(b *testing.B) { 89 benchmarkWithOps(b, 0, 100, 0) 90} 91 92func BenchmarkSpan_100BaggageItems(b *testing.B) { 93 benchmarkWithOps(b, 0, 0, 100) 94} 95 96func BenchmarkSpan_100Events_100Tags_100BaggageItems(b *testing.B) { 97 var r CountingRecorder 98 t := newTestTracer(&r) 99 100 benchmarkWithOpsAndCB(b, func() opentracing.Span { 101 sp := t.StartSpan("test") 102 return sp 103 }, 100, 100, 100) 104 if int(r) != b.N { 105 b.Fatalf("missing traces: expected %d, got %d", b.N, r) 106 } 107} 108 109func benchmarkInject(b *testing.B, format opentracing.BuiltinFormat, numItems int) { 110 var r CountingRecorder 111 tracer := newTestTracer(&r) 112 sp := tracer.StartSpan("testing") 113 executeOps(sp, 0, 0, numItems) 114 var carrier interface{} 115 switch format { 116 case opentracing.TextMap: 117 carrier = opentracing.HTTPHeadersCarrier(http.Header{}) 118 case opentracing.Binary: 119 carrier = &bytes.Buffer{} 120 default: 121 b.Fatalf("unhandled format %d", format) 122 } 123 b.ResetTimer() 124 for i := 0; i < b.N; i++ { 125 err := tracer.Inject(sp.Context(), format, carrier) 126 if err != nil { 127 b.Fatal(err) 128 } 129 } 130} 131 132func benchmarkExtract(b *testing.B, format opentracing.BuiltinFormat, numItems int) { 133 var r CountingRecorder 134 tracer := newTestTracer(&r) 135 sp := tracer.StartSpan("testing") 136 executeOps(sp, 0, 0, numItems) 137 var carrier interface{} 138 switch format { 139 case opentracing.TextMap: 140 carrier = opentracing.HTTPHeadersCarrier(http.Header{}) 141 case opentracing.Binary: 142 carrier = &bytes.Buffer{} 143 default: 144 b.Fatalf("unhandled format %d", format) 145 } 146 if err := tracer.Inject(sp.Context(), format, carrier); err != nil { 147 b.Fatal(err) 148 } 149 150 // We create a new bytes.Buffer every time for tracer.Extract() to keep 151 // this benchmark realistic. 152 var rawBinaryBytes []byte 153 if format == opentracing.Binary { 154 rawBinaryBytes = carrier.(*bytes.Buffer).Bytes() 155 } 156 b.ResetTimer() 157 for i := 0; i < b.N; i++ { 158 if format == opentracing.Binary { 159 carrier = bytes.NewBuffer(rawBinaryBytes) 160 } 161 _, err := tracer.Extract(format, carrier) 162 if err != nil { 163 b.Fatal(err) 164 } 165 } 166} 167 168func BenchmarkInject_TextMap_Empty(b *testing.B) { 169 benchmarkInject(b, opentracing.TextMap, 0) 170} 171 172func BenchmarkInject_TextMap_100BaggageItems(b *testing.B) { 173 benchmarkInject(b, opentracing.TextMap, 100) 174} 175 176func BenchmarkJoin_TextMap_Empty(b *testing.B) { 177 benchmarkExtract(b, opentracing.TextMap, 0) 178} 179 180func BenchmarkJoin_TextMap_100BaggageItems(b *testing.B) { 181 benchmarkExtract(b, opentracing.TextMap, 100) 182} 183