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