Skip to content

Commit

Permalink
perf: improve memory usage in apmhttp module (#1531)
Browse files Browse the repository at this point in the history
  • Loading branch information
kruskall authored Oct 26, 2023
1 parent 96bf41a commit 099bcae
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 26 deletions.
6 changes: 3 additions & 3 deletions module/apmhttp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
func SetHeaders(req *http.Request, traceContext apm.TraceContext, propagateLegacyHeader bool) {
headerValue := FormatTraceparentHeader(traceContext)
if propagateLegacyHeader {
req.Header.Set(ElasticTraceparentHeader, headerValue)
req.Header[ElasticTraceparentHeader] = []string{headerValue}
}
req.Header.Set(W3CTraceparentHeader, headerValue)
req.Header[W3CTraceparentHeader] = []string{headerValue}
if tracestate := traceContext.State.String(); tracestate != "" {
req.Header.Set(TracestateHeader, tracestate)
req.Header[TracestateHeader] = []string{tracestate}
}
}

Expand Down
21 changes: 3 additions & 18 deletions module/apmhttp/requestname.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,21 @@ package apmhttp // import "go.elastic.co/apm/module/apmhttp/v2"

import (
"net/http"
"strings"
)

// UnknownRouteRequestName returns the transaction name for the server request, req,
// when the route could not be determined.
func UnknownRouteRequestName(req *http.Request) string {
const suffix = " unknown route"
var b strings.Builder
b.Grow(len(req.Method) + len(suffix))
b.WriteString(req.Method)
b.WriteString(suffix)
return b.String()
return req.Method + suffix
}

// ServerRequestName returns the transaction name for the server request, req.
func ServerRequestName(req *http.Request) string {
var b strings.Builder
b.Grow(len(req.Method) + len(req.URL.Path) + 1)
b.WriteString(req.Method)
b.WriteByte(' ')
b.WriteString(req.URL.Path)
return b.String()
return req.Method + " " + req.URL.Path
}

// ClientRequestName returns the span name for the client request, req.
func ClientRequestName(req *http.Request) string {
var b strings.Builder
b.Grow(len(req.Method) + len(req.URL.Host) + 1)
b.WriteString(req.Method)
b.WriteByte(' ')
b.WriteString(req.URL.Host)
return b.String()
return req.Method + " " + req.URL.Host
}
16 changes: 13 additions & 3 deletions module/apmhttp/traceheaders.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package apmhttp // import "go.elastic.co/apm/module/apmhttp/v2"

import (
"encoding/hex"
"fmt"
"strconv"
"strings"

"github.com/pkg/errors"
Expand Down Expand Up @@ -52,8 +52,18 @@ const (
// FormatTraceparentHeader formats the given trace context as a
// traceparent header.
func FormatTraceparentHeader(c apm.TraceContext) string {
const version = 0
return fmt.Sprintf("%02x-%032x-%016x-%02x", 0, c.Trace[:], c.Span[:], c.Options)
var traceId [32]byte
hex.Encode(traceId[:], c.Trace[:])

var spanId [16]byte
hex.Encode(spanId[:], c.Span[:])

opts := strconv.FormatUint(uint64(c.Options), 16)
if len(opts) == 1 {
opts = "0" + opts
}

return "00-" + string(traceId[:]) + "-" + string(spanId[:]) + "-" + opts
}

// ParseTraceparentHeader parses the given header, which is expected to be in
Expand Down
14 changes: 14 additions & 0 deletions module/apmhttp/traceheaders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,17 @@ func TestParseTracestateHeader(t *testing.T) {
tracestate, _ = assertParse("vendorname1=opaqueValue1", "vendorname2=opaqueValue2")
assert.Equal(t, "vendorname1=opaqueValue1,vendorname2=opaqueValue2", tracestate.String())
}

func BenchmarkTraceHeaders(b *testing.B) {
ctx := apm.TraceContext{
Trace: apm.TraceID{1},
Span: apm.SpanID{2},
Options: apm.TraceOptions(3),
}

b.Run("new", func(b *testing.B) {
for i := 0; i < b.N; i++ {
apmhttp.FormatTraceparentHeader(ctx)
}
})
}
2 changes: 1 addition & 1 deletion tracecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,5 +349,5 @@ func formatElasticTracestateValue(sampleRate float64) string {
// 0 -> "s:0"
// 1 -> "s:1"
// 0.55555 -> "s:0.5555" (any rounding should be applied prior)
return fmt.Sprintf("s:%.4g", sampleRate)
return "s:" + strconv.FormatFloat(sampleRate, 'g', 4, 64)
}
2 changes: 1 addition & 1 deletion transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (t *Tracer) StartTransactionOptions(name, transactionType string, opts Tran
captureBodyMask: CaptureBodyTransactions,
},
spanTimings: make(spanTimingsMap),
droppedSpansStats: make(droppedSpanTimingsMap, maxDroppedSpanStats),
droppedSpansStats: make(droppedSpanTimingsMap),
}
var seed int64
if err := binary.Read(cryptorand.Reader, binary.LittleEndian, &seed); err != nil {
Expand Down

0 comments on commit 099bcae

Please sign in to comment.