v1.20.0.go raw
1 // Code generated by gotmpl. DO NOT MODIFY.
2 // source: internal/shared/semconv/v120.0.go.tmpl
3
4 // Copyright The OpenTelemetry Authors
5 // SPDX-License-Identifier: Apache-2.0
6
7 package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
8
9 import (
10 "errors"
11 "io"
12 "net/http"
13 "slices"
14
15 "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
16 "go.opentelemetry.io/otel/attribute"
17 "go.opentelemetry.io/otel/metric"
18 "go.opentelemetry.io/otel/metric/noop"
19 semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
20 )
21
22 type OldHTTPServer struct{}
23
24 // RequestTraceAttrs returns trace attributes for an HTTP request received by a
25 // server.
26 //
27 // The server must be the primary server name if it is known. For example this
28 // would be the ServerName directive
29 // (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
30 // server, and the server_name directive
31 // (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
32 // nginx server. More generically, the primary server name would be the host
33 // header value that matches the default virtual host of an HTTP server. It
34 // should include the host identifier and if a port is used to route to the
35 // server that port identifier should be included as an appropriate port
36 // suffix.
37 //
38 // If the primary server name is not known, server should be an empty string.
39 // The req Host will be used to determine the server instead.
40 func (o OldHTTPServer) RequestTraceAttrs(server string, req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue {
41 return semconvutil.HTTPServerRequest(server, req, semconvutil.HTTPServerRequestOptions{}, attrs)
42 }
43
44 func (o OldHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue {
45 return semconvutil.NetTransport(network)
46 }
47
48 // ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response.
49 //
50 // If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
51 func (o OldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry, attributes []attribute.KeyValue) []attribute.KeyValue {
52 if resp.ReadBytes > 0 {
53 attributes = append(attributes, semconv.HTTPRequestContentLength(int(resp.ReadBytes)))
54 }
55 if resp.ReadError != nil && !errors.Is(resp.ReadError, io.EOF) {
56 // This is not in the semantic conventions, but is historically provided
57 attributes = append(attributes, attribute.String("http.read_error", resp.ReadError.Error()))
58 }
59 if resp.WriteBytes > 0 {
60 attributes = append(attributes, semconv.HTTPResponseContentLength(int(resp.WriteBytes)))
61 }
62 if resp.StatusCode > 0 {
63 attributes = append(attributes, semconv.HTTPStatusCode(resp.StatusCode))
64 }
65 if resp.WriteError != nil && !errors.Is(resp.WriteError, io.EOF) {
66 // This is not in the semantic conventions, but is historically provided
67 attributes = append(attributes, attribute.String("http.write_error", resp.WriteError.Error()))
68 }
69
70 return attributes
71 }
72
73 // Route returns the attribute for the route.
74 func (o OldHTTPServer) Route(route string) attribute.KeyValue {
75 return semconv.HTTPRoute(route)
76 }
77
78 // HTTPStatusCode returns the attribute for the HTTP status code.
79 // This is a temporary function needed by metrics. This will be removed when MetricsRequest is added.
80 func HTTPStatusCode(status int) attribute.KeyValue {
81 return semconv.HTTPStatusCode(status)
82 }
83
84 // Server HTTP metrics.
85 const (
86 serverRequestSize = "http.server.request.size" // Incoming request bytes total
87 serverResponseSize = "http.server.response.size" // Incoming response bytes total
88 serverDuration = "http.server.duration" // Incoming end to end duration, milliseconds
89 )
90
91 func (h OldHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
92 if meter == nil {
93 return noop.Int64Counter{}, noop.Int64Counter{}, noop.Float64Histogram{}
94 }
95 var err error
96 requestBytesCounter, err := meter.Int64Counter(
97 serverRequestSize,
98 metric.WithUnit("By"),
99 metric.WithDescription("Measures the size of HTTP request messages."),
100 )
101 handleErr(err)
102
103 responseBytesCounter, err := meter.Int64Counter(
104 serverResponseSize,
105 metric.WithUnit("By"),
106 metric.WithDescription("Measures the size of HTTP response messages."),
107 )
108 handleErr(err)
109
110 serverLatencyMeasure, err := meter.Float64Histogram(
111 serverDuration,
112 metric.WithUnit("ms"),
113 metric.WithDescription("Measures the duration of inbound HTTP requests."),
114 )
115 handleErr(err)
116
117 return requestBytesCounter, responseBytesCounter, serverLatencyMeasure
118 }
119
120 func (o OldHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
121 n := len(additionalAttributes) + 3
122 var host string
123 var p int
124 if server == "" {
125 host, p = SplitHostPort(req.Host)
126 } else {
127 // Prioritize the primary server name.
128 host, p = SplitHostPort(server)
129 if p < 0 {
130 _, p = SplitHostPort(req.Host)
131 }
132 }
133 hostPort := requiredHTTPPort(req.TLS != nil, p)
134 if hostPort > 0 {
135 n++
136 }
137 protoName, protoVersion := netProtocol(req.Proto)
138 if protoName != "" {
139 n++
140 }
141 if protoVersion != "" {
142 n++
143 }
144
145 if statusCode > 0 {
146 n++
147 }
148
149 attributes := slices.Grow(additionalAttributes, n)
150 attributes = append(attributes,
151 semconv.HTTPMethod(standardizeHTTPMethod(req.Method)),
152 o.scheme(req.TLS != nil),
153 semconv.NetHostName(host))
154
155 if hostPort > 0 {
156 attributes = append(attributes, semconv.NetHostPort(hostPort))
157 }
158 if protoName != "" {
159 attributes = append(attributes, semconv.NetProtocolName(protoName))
160 }
161 if protoVersion != "" {
162 attributes = append(attributes, semconv.NetProtocolVersion(protoVersion))
163 }
164
165 if statusCode > 0 {
166 attributes = append(attributes, semconv.HTTPStatusCode(statusCode))
167 }
168 return attributes
169 }
170
171 func (o OldHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
172 if https {
173 return semconv.HTTPSchemeHTTPS
174 }
175 return semconv.HTTPSchemeHTTP
176 }
177
178 type OldHTTPClient struct{}
179
180 func (o OldHTTPClient) RequestTraceAttrs(req *http.Request, attrs []attribute.KeyValue) []attribute.KeyValue {
181 return semconvutil.HTTPClientRequest(req, attrs)
182 }
183
184 func (o OldHTTPClient) ResponseTraceAttrs(resp *http.Response, attrs []attribute.KeyValue) []attribute.KeyValue {
185 return semconvutil.HTTPClientResponse(resp, attrs)
186 }
187
188 func (o OldHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
189 /* The following semantic conventions are returned if present:
190 http.method string
191 http.status_code int
192 net.peer.name string
193 net.peer.port int
194 */
195
196 n := 2 // method, peer name.
197 var h string
198 if req.URL != nil {
199 h = req.URL.Host
200 }
201 var requestHost string
202 var requestPort int
203 for _, hostport := range []string{h, req.Header.Get("Host")} {
204 requestHost, requestPort = SplitHostPort(hostport)
205 if requestHost != "" || requestPort > 0 {
206 break
207 }
208 }
209
210 port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort)
211 if port > 0 {
212 n++
213 }
214
215 if statusCode > 0 {
216 n++
217 }
218
219 attributes := slices.Grow(additionalAttributes, n)
220 attributes = append(attributes,
221 semconv.HTTPMethod(standardizeHTTPMethod(req.Method)),
222 semconv.NetPeerName(requestHost),
223 )
224
225 if port > 0 {
226 attributes = append(attributes, semconv.NetPeerPort(port))
227 }
228
229 if statusCode > 0 {
230 attributes = append(attributes, semconv.HTTPStatusCode(statusCode))
231 }
232 return attributes
233 }
234
235 // Client HTTP metrics.
236 const (
237 clientRequestSize = "http.client.request.size" // Incoming request bytes total
238 clientResponseSize = "http.client.response.size" // Incoming response bytes total
239 clientDuration = "http.client.duration" // Incoming end to end duration, milliseconds
240 )
241
242 func (o OldHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
243 if meter == nil {
244 return noop.Int64Counter{}, noop.Int64Counter{}, noop.Float64Histogram{}
245 }
246 requestBytesCounter, err := meter.Int64Counter(
247 clientRequestSize,
248 metric.WithUnit("By"),
249 metric.WithDescription("Measures the size of HTTP request messages."),
250 )
251 handleErr(err)
252
253 responseBytesCounter, err := meter.Int64Counter(
254 clientResponseSize,
255 metric.WithUnit("By"),
256 metric.WithDescription("Measures the size of HTTP response messages."),
257 )
258 handleErr(err)
259
260 latencyMeasure, err := meter.Float64Histogram(
261 clientDuration,
262 metric.WithUnit("ms"),
263 metric.WithDescription("Measures the duration of outbound HTTP requests."),
264 )
265 handleErr(err)
266
267 return requestBytesCounter, responseBytesCounter, latencyMeasure
268 }
269
270 // TraceAttributes returns attributes for httptrace.
271 func (c OldHTTPClient) TraceAttributes(host string, attrs []attribute.KeyValue) []attribute.KeyValue {
272 return append(attrs, semconv.NetHostName(host))
273 }
274