Skip to content

Commit 2441ff3

Browse files
Merge branch 'main' into HLS-3903
2 parents c59631b + 1dd17ed commit 2441ff3

File tree

36 files changed

+400
-182
lines changed

36 files changed

+400
-182
lines changed

CHANGELOG.md

+17-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
11+
### Added
12+
13+
- Make Flask request span attributes available for `start_span`.
14+
([#1784](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1784))
15+
- Fix falcon instrumentation's usage of Span Status to only set the description if the status code is ERROR.
16+
([#1840](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1840))
1017
- Instrument all httpx versions >= 0.18. ([#1748](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1748))
18+
- Fix `Invalid type NoneType for attribute X (opentelemetry-instrumentation-aws-lambda)` error when some attributes do not exist
19+
([#1780](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1780))
20+
- Add metric instrumentation for celery
21+
([#1679](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1679))
1122

1223
## Version 1.18.0/0.39b0 (2023-05-10)
1324

@@ -25,9 +36,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2536
([#1778](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1778))
2637
- Add `excluded_urls` functionality to `urllib` and `urllib3` instrumentations
2738
([#1733](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1733))
28-
- Make Django request span attributes available for `start_span`.
39+
- Make Django request span attributes available for `start_span`.
2940
([#1730](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1730))
30-
- Make ASGI request span attributes available for `start_span`.
41+
- Make ASGI request span attributes available for `start_span`.
3142
([#1762](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1762))
3243
- `opentelemetry-instrumentation-celery` Add support for anonymous tasks.
3344
([#1407](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1407))
@@ -53,6 +64,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5364
- Fix Flask instrumentation to only close the span if it was created by the same request context.
5465
([#1692](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1692))
5566

67+
### Changed
68+
- Update HTTP server/client instrumentation span names to comply with spec
69+
([#1759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1759)
70+
5671
## Version 1.17.0/0.38b0 (2023-03-22)
5772

5873
### Added

instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ async def on_request_start(
179179
return
180180

181181
http_method = params.method.upper()
182-
request_span_name = f"HTTP {http_method}"
182+
request_span_name = f"{http_method}"
183183
request_url = (
184184
remove_url_credentials(trace_config_ctx.url_filter(params.url))
185185
if callable(trace_config_ctx.url_filter)

instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def test_status_codes(self):
119119
self.assert_spans(
120120
[
121121
(
122-
"HTTP GET",
122+
"GET",
123123
(span_status, None),
124124
{
125125
SpanAttributes.HTTP_METHOD: "GET",
@@ -213,7 +213,7 @@ def strip_query_params(url: yarl.URL) -> str:
213213
self.assert_spans(
214214
[
215215
(
216-
"HTTP GET",
216+
"GET",
217217
(StatusCode.UNSET, None),
218218
{
219219
SpanAttributes.HTTP_METHOD: "GET",
@@ -247,7 +247,7 @@ async def do_request(url):
247247
self.assert_spans(
248248
[
249249
(
250-
"HTTP GET",
250+
"GET",
251251
(expected_status, None),
252252
{
253253
SpanAttributes.HTTP_METHOD: "GET",
@@ -274,7 +274,7 @@ async def request_handler(request):
274274
self.assert_spans(
275275
[
276276
(
277-
"HTTP GET",
277+
"GET",
278278
(StatusCode.ERROR, None),
279279
{
280280
SpanAttributes.HTTP_METHOD: "GET",
@@ -301,7 +301,7 @@ async def request_handler(request):
301301
self.assert_spans(
302302
[
303303
(
304-
"HTTP GET",
304+
"GET",
305305
(StatusCode.ERROR, None),
306306
{
307307
SpanAttributes.HTTP_METHOD: "GET",
@@ -338,7 +338,7 @@ async def do_request(url):
338338
self.assert_spans(
339339
[
340340
(
341-
"HTTP GET",
341+
"GET",
342342
(StatusCode.UNSET, None),
343343
{
344344
SpanAttributes.HTTP_METHOD: "GET",
@@ -391,6 +391,7 @@ def test_instrument(self):
391391
self.get_default_request(), self.URL, self.default_handler
392392
)
393393
span = self.assert_spans(1)
394+
self.assertEqual("GET", span.name)
394395
self.assertEqual("GET", span.attributes[SpanAttributes.HTTP_METHOD])
395396
self.assertEqual(
396397
f"http://{host}:{port}/test-path",

instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -415,18 +415,23 @@ def set_status_code(span, status_code):
415415

416416

417417
def get_default_span_details(scope: dict) -> Tuple[str, dict]:
418-
"""Default implementation for get_default_span_details
418+
"""
419+
Default span name is the HTTP method and URL path, or just the method.
420+
https://github.com/open-telemetry/opentelemetry-specification/pull/3165
421+
https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/http/#name
422+
419423
Args:
420424
scope: the ASGI scope dictionary
421425
Returns:
422426
a tuple of the span name, and any attributes to attach to the span.
423427
"""
424-
span_name = (
425-
scope.get("path", "").strip()
426-
or f"HTTP {scope.get('method', '').strip()}"
427-
)
428-
429-
return span_name, {}
428+
path = scope.get("path", "").strip()
429+
method = scope.get("method", "").strip()
430+
if method and path: # http
431+
return f"{method} {path}", {}
432+
if path: # websocket
433+
return path, {}
434+
return method, {} # http with no path
430435

431436

432437
def _collect_target_attribute(

instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -142,25 +142,25 @@ def validate_outputs(self, outputs, error=None, modifiers=None):
142142
self.assertEqual(len(span_list), 4)
143143
expected = [
144144
{
145-
"name": "/ http receive",
145+
"name": "GET / http receive",
146146
"kind": trace_api.SpanKind.INTERNAL,
147147
"attributes": {"type": "http.request"},
148148
},
149149
{
150-
"name": "/ http send",
150+
"name": "GET / http send",
151151
"kind": trace_api.SpanKind.INTERNAL,
152152
"attributes": {
153153
SpanAttributes.HTTP_STATUS_CODE: 200,
154154
"type": "http.response.start",
155155
},
156156
},
157157
{
158-
"name": "/ http send",
158+
"name": "GET / http send",
159159
"kind": trace_api.SpanKind.INTERNAL,
160160
"attributes": {"type": "http.response.body"},
161161
},
162162
{
163-
"name": "/",
163+
"name": "GET /",
164164
"kind": trace_api.SpanKind.SERVER,
165165
"attributes": {
166166
SpanAttributes.HTTP_METHOD: "GET",
@@ -231,7 +231,7 @@ def update_expected_span_name(expected):
231231
entry["name"] = span_name
232232
else:
233233
entry["name"] = " ".join(
234-
[span_name] + entry["name"].split(" ")[1:]
234+
[span_name] + entry["name"].split(" ")[2:]
235235
)
236236
return expected
237237

@@ -493,9 +493,9 @@ def update_expected_hook_results(expected):
493493
for entry in expected:
494494
if entry["kind"] == trace_api.SpanKind.SERVER:
495495
entry["name"] = "name from server hook"
496-
elif entry["name"] == "/ http receive":
496+
elif entry["name"] == "GET / http receive":
497497
entry["name"] = "name from client request hook"
498-
elif entry["name"] == "/ http send":
498+
elif entry["name"] == "GET / http send":
499499
entry["attributes"].update({"attr-from-hook": "value"})
500500
return expected
501501

instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py

+51-43
Original file line numberDiff line numberDiff line change
@@ -201,30 +201,35 @@ def _set_api_gateway_v1_proxy_attributes(
201201
span.set_attribute(
202202
SpanAttributes.HTTP_METHOD, lambda_event.get("httpMethod")
203203
)
204-
span.set_attribute(SpanAttributes.HTTP_ROUTE, lambda_event.get("resource"))
205204

206205
if lambda_event.get("headers"):
207-
span.set_attribute(
208-
SpanAttributes.HTTP_USER_AGENT,
209-
lambda_event["headers"].get("User-Agent"),
210-
)
211-
span.set_attribute(
212-
SpanAttributes.HTTP_SCHEME,
213-
lambda_event["headers"].get("X-Forwarded-Proto"),
214-
)
215-
span.set_attribute(
216-
SpanAttributes.NET_HOST_NAME, lambda_event["headers"].get("Host")
217-
)
206+
if "User-Agent" in lambda_event["headers"]:
207+
span.set_attribute(
208+
SpanAttributes.HTTP_USER_AGENT,
209+
lambda_event["headers"]["User-Agent"],
210+
)
211+
if "X-Forwarded-Proto" in lambda_event["headers"]:
212+
span.set_attribute(
213+
SpanAttributes.HTTP_SCHEME,
214+
lambda_event["headers"]["X-Forwarded-Proto"],
215+
)
216+
if "Host" in lambda_event["headers"]:
217+
span.set_attribute(
218+
SpanAttributes.NET_HOST_NAME,
219+
lambda_event["headers"]["Host"],
220+
)
221+
if "resource" in lambda_event:
222+
span.set_attribute(SpanAttributes.HTTP_ROUTE, lambda_event["resource"])
218223

219-
if lambda_event.get("queryStringParameters"):
220-
span.set_attribute(
221-
SpanAttributes.HTTP_TARGET,
222-
f"{lambda_event.get('resource')}?{urlencode(lambda_event.get('queryStringParameters'))}",
223-
)
224-
else:
225-
span.set_attribute(
226-
SpanAttributes.HTTP_TARGET, lambda_event.get("resource")
227-
)
224+
if lambda_event.get("queryStringParameters"):
225+
span.set_attribute(
226+
SpanAttributes.HTTP_TARGET,
227+
f"{lambda_event['resource']}?{urlencode(lambda_event['queryStringParameters'])}",
228+
)
229+
else:
230+
span.set_attribute(
231+
SpanAttributes.HTTP_TARGET, lambda_event["resource"]
232+
)
228233

229234
return span
230235

@@ -237,35 +242,38 @@ def _set_api_gateway_v2_proxy_attributes(
237242
More info:
238243
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
239244
"""
240-
span.set_attribute(
241-
SpanAttributes.NET_HOST_NAME,
242-
lambda_event["requestContext"].get("domainName"),
243-
)
244-
245-
if lambda_event["requestContext"].get("http"):
245+
if "domainName" in lambda_event["requestContext"]:
246246
span.set_attribute(
247-
SpanAttributes.HTTP_METHOD,
248-
lambda_event["requestContext"]["http"].get("method"),
249-
)
250-
span.set_attribute(
251-
SpanAttributes.HTTP_USER_AGENT,
252-
lambda_event["requestContext"]["http"].get("userAgent"),
253-
)
254-
span.set_attribute(
255-
SpanAttributes.HTTP_ROUTE,
256-
lambda_event["requestContext"]["http"].get("path"),
247+
SpanAttributes.NET_HOST_NAME,
248+
lambda_event["requestContext"]["domainName"],
257249
)
258250

259-
if lambda_event.get("rawQueryString"):
251+
if lambda_event["requestContext"].get("http"):
252+
if "method" in lambda_event["requestContext"]["http"]:
260253
span.set_attribute(
261-
SpanAttributes.HTTP_TARGET,
262-
f"{lambda_event['requestContext']['http'].get('path')}?{lambda_event.get('rawQueryString')}",
254+
SpanAttributes.HTTP_METHOD,
255+
lambda_event["requestContext"]["http"]["method"],
263256
)
264-
else:
257+
if "userAgent" in lambda_event["requestContext"]["http"]:
265258
span.set_attribute(
266-
SpanAttributes.HTTP_TARGET,
267-
lambda_event["requestContext"]["http"].get("path"),
259+
SpanAttributes.HTTP_USER_AGENT,
260+
lambda_event["requestContext"]["http"]["userAgent"],
261+
)
262+
if "path" in lambda_event["requestContext"]["http"]:
263+
span.set_attribute(
264+
SpanAttributes.HTTP_ROUTE,
265+
lambda_event["requestContext"]["http"]["path"],
268266
)
267+
if lambda_event.get("rawQueryString"):
268+
span.set_attribute(
269+
SpanAttributes.HTTP_TARGET,
270+
f"{lambda_event['requestContext']['http']['path']}?{lambda_event['rawQueryString']}",
271+
)
272+
else:
273+
span.set_attribute(
274+
SpanAttributes.HTTP_TARGET,
275+
lambda_event["requestContext"]["http"]["path"],
276+
)
269277

270278
return span
271279

0 commit comments

Comments
 (0)