@@ -365,72 +365,89 @@ func (v *Values) ExtractRequest(r *http.Request) error {
365365
366366// SpanStartAttributes returns a list of attributes to be used when starting a span.
367367func (v * Values ) SpanStartAttributes () []attribute.KeyValue {
368- result := v .commonAttributes (5 )
368+ return v .AppendStartAttributes (make ([]attribute.KeyValue , 0 , 8 + 5 ))
369+ }
370+
371+ // AppendStartAttributes appends attributes to be used when starting a span.
372+ // Use this method instead of `SpanStartAttributes()` when you want to preallocate/reuse attributes slice.
373+ func (v * Values ) AppendStartAttributes (attrs []attribute.KeyValue ) []attribute.KeyValue {
374+ attrs = v .appendCommonAttributes (attrs )
369375 if v .NetworkPeerAddress != "" {
370- result = append (result , semconv .NetworkPeerAddress (v .NetworkPeerAddress ))
376+ attrs = append (attrs , semconv .NetworkPeerAddress (v .NetworkPeerAddress ))
371377 }
372378 if v .NetworkPeerPort != 0 {
373- result = append (result , semconv .NetworkPeerPort (v .NetworkPeerPort ))
379+ attrs = append (attrs , semconv .NetworkPeerPort (v .NetworkPeerPort ))
374380 }
375381 if v .ClientAddress != "" {
376- result = append (result , semconv .ClientAddress (v .ClientAddress ))
382+ attrs = append (attrs , semconv .ClientAddress (v .ClientAddress ))
377383 }
378384 if v .UserAgentOriginal != "" {
379- result = append (result , semconv .UserAgentOriginal (v .UserAgentOriginal ))
385+ attrs = append (attrs , semconv .UserAgentOriginal (v .UserAgentOriginal ))
380386 }
381387 if v .URLPath != "" {
382- result = append (result , semconv .URLPath (v .URLPath ))
388+ attrs = append (attrs , semconv .URLPath (v .URLPath ))
383389 }
384- return result
390+ return attrs
385391}
386392
387393// SpanEndAttributes returns a list of attributes to be used when ending a span, after the next handler has been executed.
388394func (v * Values ) SpanEndAttributes () []attribute.KeyValue {
389- return []attribute.KeyValue {
395+ return v .AppendSpanEndAttributes (make ([]attribute.KeyValue , 0 , 3 ))
396+ }
397+
398+ // AppendSpanEndAttributes appends attributes to be used when ending a span, after the next handler has been executed.
399+ // Use this method instead of `SpanEndAttributes()` when you want to preallocate/reuse attributes slice.
400+ func (v * Values ) AppendSpanEndAttributes (attrs []attribute.KeyValue ) []attribute.KeyValue {
401+ return append (attrs ,
390402 semconv .HTTPResponseStatusCode (v .HTTPResponseStatusCode ),
391403 semconv .HTTPRequestBodySize (int (v .HTTPRequestBodySize )),
392404 semconv .HTTPResponseBodySize (int (v .HTTPResponseBodySize )),
393- }
405+ )
394406}
395407
396408// MetricAttributes creates attributes for metric instruments from extracted values.
397409// See also: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/
398410func (v * Values ) MetricAttributes () []attribute.KeyValue {
399- result := v .commonAttributes (1 )
411+ return v .AppendMetricAttributes (make ([]attribute.KeyValue , 0 , 8 + 1 ))
412+ }
413+
414+ // AppendMetricAttributes appends attributes for metric instruments from extracted values.
415+ // Use this method instead of `MetricAttributes()` when you want to preallocate/reuse attributes slice.
416+ // See also: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/
417+ func (v * Values ) AppendMetricAttributes (attrs []attribute.KeyValue ) []attribute.KeyValue {
418+ attrs = v .appendCommonAttributes (attrs )
400419 if v .HTTPResponseStatusCode != 0 {
401- result = append (result , semconv .HTTPResponseStatusCode (v .HTTPResponseStatusCode ))
420+ attrs = append (attrs , semconv .HTTPResponseStatusCode (v .HTTPResponseStatusCode ))
402421 }
403- return result
422+ return attrs
404423}
405424
406- func (v * Values ) commonAttributes (additionalSize int ) []attribute.KeyValue {
407- result := make ([]attribute.KeyValue , 0 , 8 + additionalSize )
408-
425+ func (v * Values ) appendCommonAttributes (attrs []attribute.KeyValue ) []attribute.KeyValue {
409426 method := otherMethodAttr
410427 if m , ok := knownMethods [v .HTTPMethod ]; ok {
411428 method = m
412429 }
413- result = append (result ,
430+ attrs = append (attrs ,
414431 method ,
415432 semconv .ServerAddress (v .ServerAddress ),
416433 semconv .URLScheme (v .URLScheme ),
417434 )
418435 if v .HTTPRoute != "" {
419- result = append (result , semconv .HTTPRoute (v .HTTPRoute ))
436+ attrs = append (attrs , semconv .HTTPRoute (v .HTTPRoute ))
420437 }
421438 if v .ServerPort != 0 {
422- result = append (result , semconv .ServerPort (v .ServerPort ))
439+ attrs = append (attrs , semconv .ServerPort (v .ServerPort ))
423440 }
424441 if v .HTTPMethodOriginal != "" {
425- result = append (result , semconv .HTTPRequestMethodOriginal (v .HTTPMethodOriginal ))
442+ attrs = append (attrs , semconv .HTTPRequestMethodOriginal (v .HTTPMethodOriginal ))
426443 }
427444 if v .NetworkProtocolName != "" {
428- result = append (result , semconv .NetworkProtocolName (v .NetworkProtocolName ))
445+ attrs = append (attrs , semconv .NetworkProtocolName (v .NetworkProtocolName ))
429446 }
430447 if v .NetworkProtocolVersion != "" {
431- result = append (result , semconv .NetworkProtocolVersion (v .NetworkProtocolVersion ))
448+ attrs = append (attrs , semconv .NetworkProtocolVersion (v .NetworkProtocolVersion ))
432449 }
433- return result
450+ return attrs
434451}
435452
436453// http.request.method: HTTP request method value SHOULD be “known” to the instrumentation.
0 commit comments