Skip to content

Commit

Permalink
backup
Browse files Browse the repository at this point in the history
  • Loading branch information
flc1125 committed Dec 9, 2024
1 parent c6da5fa commit f62983d
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 44 deletions.
14 changes: 9 additions & 5 deletions instrumentation/net/http/otelhttp/internal/semconv/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
"go.opentelemetry.io/otel/metric"
)

// OTelSemConvStabilityOptIn is an environment variable.
// That can be set to "old" or "http/dup" to opt into the new HTTP semantic conventions.
const OTelSemConvStabilityOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN"

type ResponseTelemetry struct {
StatusCode int
ReadBytes int64
Expand All @@ -32,9 +36,9 @@ type HTTPServer struct {
serverLatencyMeasure metric.Float64Histogram

// New metrics
requestDurationHistogram metric.Float64Histogram
requestBodySizeHistogram metric.Int64Histogram
responseBodySizeHistogram metric.Int64Histogram
requestDurationHistogram metric.Float64Histogram
}

// RequestTraceAttrs returns trace attributes for an HTTP request received by a
Expand Down Expand Up @@ -120,21 +124,21 @@ func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) {
if s.duplicate && s.requestDurationHistogram != nil && s.requestBodySizeHistogram != nil && s.responseBodySizeHistogram != nil {
attributes := newHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes)
o := metric.WithAttributeSet(attribute.NewSet(attributes...))
s.requestDurationHistogram.Record(ctx, md.ElapsedTime, o)
s.requestBodySizeHistogram.Record(ctx, md.RequestSize, o)
s.responseBodySizeHistogram.Record(ctx, md.ResponseSize, o)
s.requestDurationHistogram.Record(ctx, md.ElapsedTime, o)
}
}

func NewHTTPServer(meter metric.Meter) HTTPServer {
env := strings.ToLower(os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN"))
env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn))
duplicate := env == "http/dup"
server := HTTPServer{
duplicate: duplicate,
}
server.requestBytesCounter, server.responseBytesCounter, server.serverLatencyMeasure = oldHTTPServer{}.createMeasures(meter)
if duplicate {
server.requestDurationHistogram, server.requestBodySizeHistogram, server.responseBodySizeHistogram = newHTTPServer{}.createMeasures(meter)
server.requestBodySizeHistogram, server.responseBodySizeHistogram, server.requestDurationHistogram = newHTTPServer{}.createMeasures(meter)
}
return server
}
Expand All @@ -149,7 +153,7 @@ type HTTPClient struct {
}

func NewHTTPClient(meter metric.Meter) HTTPClient {
env := strings.ToLower(os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN"))
env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn))
client := HTTPClient{
duplicate: env == "http/dup",
}
Expand Down
36 changes: 23 additions & 13 deletions instrumentation/net/http/otelhttp/internal/semconv/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,41 +94,51 @@ func TestHTTPClientDoesNotPanic(t *testing.T) {
}
}

type testInst struct {
type testRecorder[T any] struct {
embedded.Int64Counter
embedded.Int64Histogram
embedded.Float64Histogram

intValue int64
floatValue float64
value T
attributes []attribute.KeyValue
}

func (t *testInst) Add(ctx context.Context, incr int64, options ...metric.AddOption) {
t.intValue = incr
var (
_ metric.Int64Counter = (*testRecorder[int64])(nil)
_ metric.Float64Histogram = (*testRecorder[float64])(nil)
_ metric.Int64Histogram = (*testRecorder[int64])(nil)
_ metric.Float64Histogram = (*testRecorder[float64])(nil)
)

func (t *testRecorder[T]) Add(_ context.Context, incr T, options ...metric.AddOption) {
t.value = incr
cfg := metric.NewAddConfig(options)
attr := cfg.Attributes()
t.attributes = attr.ToSlice()
}

func (t *testInst) Record(ctx context.Context, value float64, options ...metric.RecordOption) {
t.floatValue = value
func (t *testRecorder[T]) Record(_ context.Context, value T, options ...metric.RecordOption) {
t.value = value
cfg := metric.NewRecordConfig(options)
attr := cfg.Attributes()
t.attributes = attr.ToSlice()
}

func NewTestHTTPServer() HTTPServer {
return HTTPServer{
requestBytesCounter: &testInst{},
responseBytesCounter: &testInst{},
serverLatencyMeasure: &testInst{},
requestBytesCounter: &testRecorder[int64]{},
responseBytesCounter: &testRecorder[int64]{},
serverLatencyMeasure: &testRecorder[float64]{},
requestBodySizeHistogram: &testRecorder[int64]{},
responseBodySizeHistogram: &testRecorder[int64]{},
requestDurationHistogram: &testRecorder[float64]{},
}
}

func NewTestHTTPClient() HTTPClient {
return HTTPClient{
requestBytesCounter: &testInst{},
responseBytesCounter: &testInst{},
latencyMeasure: &testInst{},
requestBytesCounter: &testRecorder[int64]{},
responseBytesCounter: &testRecorder[int64]{},
latencyMeasure: &testRecorder[float64]{},
}
}
19 changes: 9 additions & 10 deletions instrumentation/net/http/otelhttp/internal/semconv/httpconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,12 @@ func (n newHTTPServer) Route(route string) attribute.KeyValue {
return semconvNew.HTTPRoute(route)
}

func (n newHTTPServer) createMeasures(meter metric.Meter) (metric.Float64Histogram, metric.Int64Histogram, metric.Int64Histogram) {
func (n newHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Histogram, metric.Int64Histogram, metric.Float64Histogram) {
if meter == nil {
return noop.Float64Histogram{}, noop.Int64Histogram{}, noop.Int64Histogram{}
return noop.Int64Histogram{}, noop.Int64Histogram{}, noop.Float64Histogram{}
}

var err error
requestDurationHistogram, err := meter.Float64Histogram(
semconvNew.HTTPServerRequestDurationName,
metric.WithUnit(semconvNew.HTTPServerRequestDurationUnit),
metric.WithDescription(semconvNew.HTTPServerRequestDurationDescription),
)
handleErr(err)

requestBodySizeHistogram, err := meter.Int64Histogram(
semconvNew.HTTPServerRequestBodySizeName,
metric.WithUnit(semconvNew.HTTPServerRequestBodySizeUnit),
Expand All @@ -228,8 +221,14 @@ func (n newHTTPServer) createMeasures(meter metric.Meter) (metric.Float64Histogr
metric.WithDescription(semconvNew.HTTPServerResponseBodySizeDescription),
)
handleErr(err)
requestDurationHistogram, err := meter.Float64Histogram(
semconvNew.HTTPServerRequestDurationName,
metric.WithUnit(semconvNew.HTTPServerRequestDurationUnit),
metric.WithDescription(semconvNew.HTTPServerRequestDurationDescription),
)
handleErr(err)

return requestDurationHistogram, requestBodySizeHistogram, responseBodySizeHistogram
return requestBodySizeHistogram, responseBodySizeHistogram, requestDurationHistogram
}

func (n newHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package semconv

import (
"context"
"errors"
"fmt"
"net/http"
Expand All @@ -17,7 +18,7 @@ import (
)

func TestNewTraceRequest(t *testing.T) {
t.Setenv("OTEL_SEMCONV_STABILITY_OPT_IN", "http/dup")
t.Setenv(OTelSemConvStabilityOptIn, "http/dup")
serv := NewHTTPServer(nil)
want := func(req testServerReq) []attribute.KeyValue {
return []attribute.KeyValue{
Expand Down Expand Up @@ -95,6 +96,49 @@ func TestNewTraceResponse(t *testing.T) {
}
}

func TestNewRecordMetrics(t *testing.T) {
t.Setenv(OTelSemConvStabilityOptIn, "http/dup")
server := NewTestHTTPServer()
server.duplicate = true
req, err := http.NewRequest("POST", "http://example.com", nil)
assert.NoError(t, err)

server.RecordMetrics(context.Background(), ServerMetricData{
ServerName: "stuff",
ResponseSize: 200,
MetricAttributes: MetricAttributes{
Req: req,
StatusCode: 301,
AdditionalAttributes: []attribute.KeyValue{
attribute.String("key", "value"),
},
},
MetricData: MetricData{
RequestSize: 100,
ElapsedTime: 300,
},
})

assert.Equal(t, int64(100), server.requestBodySizeHistogram.(*testRecorder[int64]).value)
assert.Equal(t, int64(200), server.responseBodySizeHistogram.(*testRecorder[int64]).value)
assert.Equal(t, float64(300), server.requestDurationHistogram.(*testRecorder[float64]).value)

want := []attribute.KeyValue{
attribute.String("http.scheme", "http"),
attribute.String("http.method", "POST"),
attribute.Int64("http.status_code", 301),
attribute.String("key", "value"),
attribute.String("net.host.name", "stuff"),
attribute.String("net.protocol.name", "http"),
attribute.String("net.protocol.version", "1.1"),
}
_ = want

// assert.ElementsMatch(t, want, server.requestBodySizeHistogram.(*testRecorder[int64]).attributes)
// assert.ElementsMatch(t, want, server.responseBodySizeHistogram.(*testRecorder[int64]).attributes)
// assert.ElementsMatch(t, want, server.requestDurationHistogram.(*testRecorder[float64]).attributes)
}

func TestNewMethod(t *testing.T) {
testCases := []struct {
method string
Expand Down Expand Up @@ -131,7 +175,7 @@ func TestNewMethod(t *testing.T) {
}

func TestNewTraceRequest_Client(t *testing.T) {
t.Setenv("OTEL_SEMCONV_STABILITY_OPT_IN", "http/dup")
t.Setenv(OTelSemConvStabilityOptIn, "http/dup")
body := strings.NewReader("Hello, world!")
url := "https://example.com:8888/foo/bar?stuff=morestuff"
req := httptest.NewRequest("pOST", url, body)
Expand All @@ -156,7 +200,7 @@ func TestNewTraceRequest_Client(t *testing.T) {
}

func TestNewTraceResponse_Client(t *testing.T) {
t.Setenv("OTEL_SEMCONV_STABILITY_OPT_IN", "http/dup")
t.Setenv(OTelSemConvStabilityOptIn, "http/dup")
testcases := []struct {
resp http.Response
want []attribute.KeyValue
Expand Down
26 changes: 13 additions & 13 deletions instrumentation/net/http/otelhttp/internal/semconv/v1.20.0_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (

func TestV120TraceRequest(t *testing.T) {
// Anything but "http" or "http/dup" works.
t.Setenv("OTEL_SEMCONV_STABILITY_OPT_IN", "old")
t.Setenv(OTelSemConvStabilityOptIn, "old")
serv := NewHTTPServer(nil)
want := func(req testServerReq) []attribute.KeyValue {
return []attribute.KeyValue{
Expand Down Expand Up @@ -108,9 +108,9 @@ func TestV120RecordMetrics(t *testing.T) {
},
})

assert.Equal(t, int64(100), server.requestBytesCounter.(*testInst).intValue)
assert.Equal(t, int64(200), server.responseBytesCounter.(*testInst).intValue)
assert.Equal(t, float64(300), server.serverLatencyMeasure.(*testInst).floatValue)
assert.Equal(t, int64(100), server.requestBytesCounter.(*testRecorder[int64]).value)
assert.Equal(t, int64(200), server.responseBytesCounter.(*testRecorder[int64]).value)
assert.Equal(t, float64(300), server.serverLatencyMeasure.(*testRecorder[float64]).value)

want := []attribute.KeyValue{
attribute.String("http.scheme", "http"),
Expand All @@ -122,9 +122,9 @@ func TestV120RecordMetrics(t *testing.T) {
attribute.String("net.protocol.version", "1.1"),
}

assert.ElementsMatch(t, want, server.requestBytesCounter.(*testInst).attributes)
assert.ElementsMatch(t, want, server.responseBytesCounter.(*testInst).attributes)
assert.ElementsMatch(t, want, server.serverLatencyMeasure.(*testInst).attributes)
assert.ElementsMatch(t, want, server.requestBytesCounter.(*testRecorder[int64]).attributes)
assert.ElementsMatch(t, want, server.responseBytesCounter.(*testRecorder[int64]).attributes)
assert.ElementsMatch(t, want, server.serverLatencyMeasure.(*testRecorder[float64]).attributes)
}

func TestV120ClientRequest(t *testing.T) {
Expand Down Expand Up @@ -183,9 +183,9 @@ func TestV120ClientMetrics(t *testing.T) {
ElapsedTime: 300,
}, opts)

assert.Equal(t, int64(100), client.requestBytesCounter.(*testInst).intValue)
assert.Equal(t, int64(200), client.responseBytesCounter.(*testInst).intValue)
assert.Equal(t, float64(300), client.latencyMeasure.(*testInst).floatValue)
assert.Equal(t, int64(100), client.requestBytesCounter.(*testRecorder[int64]).value)
assert.Equal(t, int64(200), client.responseBytesCounter.(*testRecorder[int64]).value)
assert.Equal(t, float64(300), client.latencyMeasure.(*testRecorder[float64]).value)

want := []attribute.KeyValue{
attribute.String("http.method", "POST"),
Expand All @@ -194,9 +194,9 @@ func TestV120ClientMetrics(t *testing.T) {
attribute.String("net.peer.name", "example.com"),
}

assert.ElementsMatch(t, want, client.requestBytesCounter.(*testInst).attributes)
assert.ElementsMatch(t, want, client.responseBytesCounter.(*testInst).attributes)
assert.ElementsMatch(t, want, client.latencyMeasure.(*testInst).attributes)
assert.ElementsMatch(t, want, client.requestBytesCounter.(*testRecorder[int64]).attributes)
assert.ElementsMatch(t, want, client.responseBytesCounter.(*testRecorder[int64]).attributes)
assert.ElementsMatch(t, want, client.latencyMeasure.(*testRecorder[float64]).attributes)
}

func TestStandardizeHTTPMethodMetric(t *testing.T) {
Expand Down

0 comments on commit f62983d

Please sign in to comment.