Skip to content

Commit

Permalink
Use an atomic.Int64 as bodyWrapper read bytes counter (#5080)
Browse files Browse the repository at this point in the history
* use an atomic.Int64 as bodyWrapper read bytes counter

* add changelog entry

---------

Co-authored-by: Tyler Yahn <[email protected]>
  • Loading branch information
dmathieu and MrAlias authored Feb 13, 2024
1 parent ee76330 commit 43ec73b
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The deprecated `ResponseContentLength` constant in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` is removed. (#4894)
- The deprecated `ServerLatency` constant in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` is removed. (#4894)

### Fixed

- Retrieving the body bytes count in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` does not cause a data race anymore. (#5080)

## [1.23.0/0.48.0/0.17.0/0.3.0] - 2024-02-06

### Added
Expand Down
4 changes: 2 additions & 2 deletions instrumentation/net/http/otelhttp/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,15 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http

next.ServeHTTP(w, r.WithContext(ctx))

setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err)
setAfterServeAttributes(span, bw.read.Load(), rww.written, rww.statusCode, bw.err, rww.err)

// Add metrics
attributes := append(labeler.Get(), semconvutil.HTTPServerRequestMetrics(h.server, r)...)
if rww.statusCode > 0 {
attributes = append(attributes, semconv.HTTPStatusCode(rww.statusCode))
}
o := metric.WithAttributes(attributes...)
h.requestBytesCounter.Add(ctx, bw.read, o)
h.requestBytesCounter.Add(ctx, bw.read.Load(), o)
h.responseBytesCounter.Add(ctx, rww.written, o)

// Use floating point division here for higher precision (instead of Millisecond method).
Expand Down
2 changes: 1 addition & 1 deletion instrumentation/net/http/otelhttp/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
metricAttrs = append(metricAttrs, semconv.HTTPStatusCode(res.StatusCode))
}
o := metric.WithAttributes(metricAttrs...)
t.requestBytesCounter.Add(ctx, bw.read, o)
t.requestBytesCounter.Add(ctx, bw.read.Load(), o)
// For handling response bytes we leverage a callback when the client reads the http response
readRecordFunc := func(n int64) {
t.responseBytesCounter.Add(ctx, n, o)
Expand Down
5 changes: 3 additions & 2 deletions instrumentation/net/http/otelhttp/wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"io"
"net/http"
"sync/atomic"

"go.opentelemetry.io/otel/propagation"
)
Expand All @@ -30,14 +31,14 @@ type bodyWrapper struct {
io.ReadCloser
record func(n int64) // must not be nil

read int64
read atomic.Int64
err error
}

func (w *bodyWrapper) Read(b []byte) (int, error) {
n, err := w.ReadCloser.Read(b)
n1 := int64(n)
w.read += n1
w.read.Add(n1)
w.err = err
w.record(n1)
return n, err
Expand Down

0 comments on commit 43ec73b

Please sign in to comment.