Skip to content

Commit 81855d7

Browse files
authored
fix: update to latest otel semconv (#1668)
Signed-off-by: Michael Beemer <[email protected]>
1 parent c07ffba commit 81855d7

File tree

9 files changed

+68
-45
lines changed

9 files changed

+68
-45
lines changed

core/pkg/telemetry/builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"go.opentelemetry.io/otel/sdk/metric"
2222
"go.opentelemetry.io/otel/sdk/resource"
2323
"go.opentelemetry.io/otel/sdk/trace"
24-
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
24+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
2525
"go.uber.org/zap"
2626
"google.golang.org/grpc"
2727
"google.golang.org/grpc/credentials"

core/pkg/telemetry/builder_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"go.opentelemetry.io/otel/sdk/metric"
1313
"go.opentelemetry.io/otel/sdk/metric/metricdata"
1414
"go.opentelemetry.io/otel/sdk/resource"
15-
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
15+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
1616
"go.uber.org/zap"
1717
"go.uber.org/zap/zaptest/observer"
1818
)

core/pkg/telemetry/metrics.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"go.opentelemetry.io/otel/sdk/instrumentation"
1111
msdk "go.opentelemetry.io/otel/sdk/metric"
1212
"go.opentelemetry.io/otel/sdk/resource"
13-
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
13+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
1414
)
1515

1616
const (
@@ -19,15 +19,15 @@ const (
1919
FeatureFlagReasonKey = attribute.Key("feature_flag.reason")
2020
ExceptionTypeKey = attribute.Key("ExceptionTypeKeyName")
2121

22-
httpRequestDurationMetric = "http.server.duration"
23-
httpResponseSizeMetric = "http.server.response.size"
22+
httpRequestDurationMetric = "http.server.request.duration"
23+
httpResponseSizeMetric = "http.server.response.body.size"
2424
httpActiveRequestsMetric = "http.server.active_requests"
2525
impressionMetric = "feature_flag." + ProviderName + ".impression"
26-
reasonMetric = "feature_flag." + ProviderName + ".evaluation.reason"
26+
reasonMetric = "feature_flag." + ProviderName + ".result.reason"
2727
)
2828

2929
type IMetricsRecorder interface {
30-
HTTPAttributes(svcName, url, method, code string) []attribute.KeyValue
30+
HTTPAttributes(svcName, url, method, code, scheme string) []attribute.KeyValue
3131
HTTPRequestDuration(ctx context.Context, duration time.Duration, attrs []attribute.KeyValue)
3232
HTTPResponseSize(ctx context.Context, sizeBytes int64, attrs []attribute.KeyValue)
3333
InFlightRequestStart(ctx context.Context, attrs []attribute.KeyValue)
@@ -38,7 +38,7 @@ type IMetricsRecorder interface {
3838

3939
type NoopMetricsRecorder struct{}
4040

41-
func (NoopMetricsRecorder) HTTPAttributes(_, _, _, _ string) []attribute.KeyValue {
41+
func (NoopMetricsRecorder) HTTPAttributes(_, _, _, _, _ string) []attribute.KeyValue {
4242
return []attribute.KeyValue{}
4343
}
4444

@@ -68,12 +68,13 @@ type MetricsRecorder struct {
6868
reasons metric.Int64Counter
6969
}
7070

71-
func (r MetricsRecorder) HTTPAttributes(svcName, url, method, code string) []attribute.KeyValue {
71+
func (r MetricsRecorder) HTTPAttributes(svcName, url, method, code, scheme string) []attribute.KeyValue {
7272
return []attribute.KeyValue{
7373
semconv.ServiceNameKey.String(svcName),
74-
semconv.HTTPURLKey.String(url),
75-
semconv.HTTPMethodKey.String(method),
76-
semconv.HTTPStatusCodeKey.String(code),
74+
semconv.HTTPRouteKey.String(url),
75+
semconv.HTTPRequestMethodKey.String(method),
76+
semconv.HTTPResponseStatusCodeKey.String(code),
77+
semconv.URLSchemeKey.String(scheme),
7778
}
7879
}
7980

core/pkg/telemetry/metrics_test.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"go.opentelemetry.io/otel/sdk/metric"
1111
"go.opentelemetry.io/otel/sdk/metric/metricdata"
1212
"go.opentelemetry.io/otel/sdk/resource"
13-
semconv "go.opentelemetry.io/otel/semconv/v1.13.0"
13+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
1414
)
1515

1616
const svcName = "mySvc"
@@ -38,9 +38,10 @@ func TestHTTPAttributes(t *testing.T) {
3838
},
3939
want: []attribute.KeyValue{
4040
semconv.ServiceNameKey.String(""),
41-
semconv.HTTPURLKey.String(""),
42-
semconv.HTTPMethodKey.String(""),
43-
semconv.HTTPStatusCodeKey.String(""),
41+
semconv.HTTPRouteKey.String(""),
42+
semconv.HTTPRequestMethodKey.String(""),
43+
semconv.HTTPResponseStatusCodeKey.String(""),
44+
semconv.URLSchemeKey.String("http"),
4445
},
4546
},
4647
{
@@ -53,9 +54,10 @@ func TestHTTPAttributes(t *testing.T) {
5354
},
5455
want: []attribute.KeyValue{
5556
semconv.ServiceNameKey.String("myService"),
56-
semconv.HTTPURLKey.String("#123"),
57-
semconv.HTTPMethodKey.String("POST"),
58-
semconv.HTTPStatusCodeKey.String("300"),
57+
semconv.HTTPRouteKey.String("#123"),
58+
semconv.HTTPRequestMethodKey.String("POST"),
59+
semconv.HTTPResponseStatusCodeKey.String("300"),
60+
semconv.URLSchemeKey.String("http"),
5961
},
6062
},
6163
{
@@ -68,16 +70,17 @@ func TestHTTPAttributes(t *testing.T) {
6870
},
6971
want: []attribute.KeyValue{
7072
semconv.ServiceNameKey.String("!@#$%^&*()_+|}{[];',./<>"),
71-
semconv.HTTPURLKey.String(""),
72-
semconv.HTTPMethodKey.String(""),
73-
semconv.HTTPStatusCodeKey.String(""),
73+
semconv.HTTPRouteKey.String(""),
74+
semconv.HTTPRequestMethodKey.String(""),
75+
semconv.HTTPResponseStatusCodeKey.String(""),
76+
semconv.URLSchemeKey.String("http"),
7477
},
7578
},
7679
}
7780
for _, tt := range tests {
7881
t.Run(tt.name, func(t *testing.T) {
7982
rec := MetricsRecorder{}
80-
res := rec.HTTPAttributes(tt.req.Service, tt.req.ID, tt.req.Method, tt.req.Code)
83+
res := rec.HTTPAttributes(tt.req.Service, tt.req.ID, tt.req.Method, tt.req.Code, "http")
8184
require.Equal(t, tt.want, res)
8285
})
8386
}
@@ -208,7 +211,7 @@ func TestMetrics(t *testing.T) {
208211
// some really simple tests just to make sure all methods are actually implemented and nothing panics
209212
func TestNoopMetricsRecorder_HTTPAttributes(t *testing.T) {
210213
no := NoopMetricsRecorder{}
211-
got := no.HTTPAttributes("", "", "", "")
214+
got := no.HTTPAttributes("", "", "", "", "")
212215
require.Empty(t, got)
213216
}
214217

core/pkg/telemetry/utils.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package telemetry
22

33
import (
44
"go.opentelemetry.io/otel/attribute"
5-
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
5+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
66
)
77

88
// utils contain common utilities to help with telemetry
@@ -14,7 +14,7 @@ const provider = "flagd"
1414
func SemConvFeatureFlagAttributes(ffKey string, ffVariant string) []attribute.KeyValue {
1515
return []attribute.KeyValue{
1616
semconv.FeatureFlagKey(ffKey),
17-
semconv.FeatureFlagVariant(ffVariant),
17+
semconv.FeatureFlagResultVariant(ffVariant),
1818
semconv.FeatureFlagProviderName(provider),
1919
}
2020
}

core/pkg/telemetry/utils_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"testing"
55

66
"github.com/stretchr/testify/require"
7-
semconv "go.opentelemetry.io/otel/semconv/v1.18.0"
7+
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
88
)
99

1010
func TestSemConvFeatureFlagAttributes(t *testing.T) {
@@ -35,7 +35,7 @@ func TestSemConvFeatureFlagAttributes(t *testing.T) {
3535
case semconv.FeatureFlagKeyKey:
3636
require.Equal(t, test.key, attribute.Value.AsString(),
3737
"expected flag key: %s, but received: %s", test.key, attribute.Value.AsString())
38-
case semconv.FeatureFlagVariantKey:
38+
case semconv.FeatureFlagResultVariantKey:
3939
require.Equal(t, test.variant, attribute.Value.AsString(),
4040
"expected flag variant: %s, but received %s", test.variant, attribute.Value.AsString())
4141
case semconv.FeatureFlagProviderNameKey:

docs/reference/monitoring.md

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,25 @@ Given below is the current implementation overview of flagd telemetry internals,
4747

4848
flagd exposes the following metrics:
4949

50-
- `http.server.duration`
51-
- `http.server.response.size`
52-
- `http.server.active_requests`
53-
- `feature_flag.flagd.impression`
54-
- `feature_flag.flagd.evaluation.reason`
50+
- `http.server.request.duration` - Measures the duration of inbound HTTP requests
51+
- `http.server.response.body.size` - Measures the size of HTTP response messages
52+
- `http.server.active_requests` - Measures the number of concurrent HTTP requests that are currently in-flight
53+
- `feature_flag.flagd.impression` - Measures the number of evaluations for a given flag
54+
- `feature_flag.flagd.result.reason` - Measures the number of evaluations for a given reason
5555

5656
> Please note that metric names may vary based on the consuming monitoring tool naming requirements.
5757
> For example, the transformation of OTLP metrics to Prometheus is described [here](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/compatibility/prometheus_and_openmetrics.md#otlp-metric-points-to-prometheus).
5858
59+
### HTTP Metric Attributes
60+
61+
flagd uses the following OpenTelemetry Semantic Conventions for HTTP metrics:
62+
63+
- `service.name` - The name of the service
64+
- `http.route` - The matched route (path template)
65+
- `http.request.method` - The HTTP request method (GET, POST, etc.)
66+
- `http.response.status_code` - The HTTP response status code
67+
- `url.scheme` - The URI scheme (http or https)
68+
5969
## Traces
6070

6171
flagd creates the following spans as part of a trace:
@@ -83,17 +93,16 @@ official [OTEL collector example](https://github.com/open-telemetry/opentelemetr
8393

8494
```yaml
8595
services:
86-
# Jaeger
87-
jaeger-all-in-one:
88-
image: jaegertracing/all-in-one:latest
96+
jaeger:
97+
image: cr.jaegertracing.io/jaegertracing/jaeger:2.8.0
8998
restart: always
9099
ports:
91100
- "16686:16686"
92101
- "14268"
93102
- "14250"
94103
# Collector
95104
otel-collector:
96-
image: otel/opentelemetry-collector:latest
105+
image: otel/opentelemetry-collector:0.129.1
97106
restart: always
98107
command: [ "--config=/etc/otel-collector-config.yaml" ]
99108
volumes:
@@ -106,10 +115,10 @@ services:
106115
- "4317:4317" # OTLP gRPC receiver
107116
- "55679:55679" # zpages extension
108117
depends_on:
109-
- jaeger-all-in-one
118+
- jaeger
110119
prometheus:
111120
container_name: prometheus
112-
image: prom/prometheus:latest
121+
image: prom/prometheus:v2.53.5
113122
restart: always
114123
volumes:
115124
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
@@ -128,10 +137,8 @@ receivers:
128137
exporters:
129138
prometheus:
130139
endpoint: "0.0.0.0:8889"
131-
const_labels:
132-
label1: value1
133140
otlp/jaeger:
134-
endpoint: jaeger-all-in-one:4317
141+
endpoint: jaeger:4317
135142
tls:
136143
insecure: true
137144
processors:
@@ -148,18 +155,17 @@ service:
148155
exporters: [ prometheus ]
149156
```
150157
151-
#### prometheus.yml
158+
#### prometheus.yaml
152159
153160
```yaml
154161
scrape_configs:
155162
- job_name: 'otel-collector'
156163
scrape_interval: 10s
157164
static_configs:
158165
- targets: [ 'otel-collector:8889' ]
159-
- targets: [ 'otel-collector:8888' ]
160166
```
161167
162-
Once, configuration files are ready, use `docker-compose up` to start the local setup. With successful startup, you can
168+
Once, configuration files are ready, use `docker compose up` to start the local setup. With successful startup, you can
163169
access metrics through [Prometheus](http://localhost:9090/graph) & traces through [Jaeger](http://localhost:16686/).
164170

165171
## Metadata

flagd/pkg/service/middleware/metrics/http_metrics.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (m Middleware) Measure(ctx context.Context, handlerID string, reporter Repo
6868
hid,
6969
reporter.Method(),
7070
code,
71+
reporter.Scheme(),
7172
)
7273

7374
m.cfg.MetricRecorder.InFlightRequestStart(ctx, httpAttrs)
@@ -112,6 +113,7 @@ type Reporter interface {
112113
URLPath() string
113114
StatusCode() int
114115
BytesWritten() int64
116+
Scheme() string
115117
}
116118

117119
type stdReporter struct {
@@ -127,6 +129,13 @@ func (s *stdReporter) StatusCode() int { return s.w.statusCode }
127129

128130
func (s *stdReporter) BytesWritten() int64 { return int64(s.w.bytesWritten) }
129131

132+
func (s *stdReporter) Scheme() string {
133+
if s.r.TLS != nil {
134+
return "https"
135+
}
136+
return "http"
137+
}
138+
130139
// responseWriterInterceptor is a simple wrapper to intercept set data on a
131140
// ResponseWriter.
132141
type responseWriterInterceptor struct {

flagd/pkg/service/middleware/metrics/http_metrics_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ func (m *MockReporter) BytesWritten() int64 {
190190
return m.Bytes
191191
}
192192

193+
func (m *MockReporter) Scheme() string {
194+
return "http"
195+
}
196+
193197
func (m *MockReporter) URLCalled() bool { return m.urlCalled }
194198
func (m *MockReporter) MethodCalled() bool { return m.methodCalled }
195199
func (m *MockReporter) StatusCalled() bool { return m.statusCalled }

0 commit comments

Comments
 (0)