Skip to content

Commit fd6fdeb

Browse files
authored
Merge branch 'main' into emptyroute
2 parents 0ea524b + 256d8ce commit fd6fdeb

File tree

7 files changed

+162
-126
lines changed

7 files changed

+162
-126
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## Unreleased
9+
- `opentelemetry-instrumentation-asgi` Add `http.server.request.size` metric
10+
([#1867](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1867))
911

1012
### Fixed
1113

@@ -27,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2729
([#1679](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1679))
2830
- `opentelemetry-instrumentation-asgi` Add `http.server.response.size` metric
2931
([#1789](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1789))
32+
- `opentelemetry-instrumentation-grpc` Allow gRPC connections via Unix socket
33+
([#1833](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1833))
3034

3135
## Version 1.18.0/0.39b0 (2023-05-10)
3236

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,11 @@ def __init__(
511511
unit="By",
512512
description="measures the size of HTTP response messages (compressed).",
513513
)
514+
self.server_request_size_histogram = self.meter.create_histogram(
515+
name=MetricInstruments.HTTP_SERVER_REQUEST_SIZE,
516+
unit="By",
517+
description="Measures the size of HTTP request messages (compressed).",
518+
)
514519
self.active_requests_counter = self.meter.create_up_down_counter(
515520
name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS,
516521
unit="requests",
@@ -603,6 +608,16 @@ async def __call__(self, scope, receive, send):
603608
self.server_response_size_histogram.record(
604609
self.content_length_header, duration_attrs
605610
)
611+
request_size = asgi_getter.get(scope, "content-length")
612+
if request_size:
613+
try:
614+
request_size_amount = int(request_size[0])
615+
except ValueError:
616+
pass
617+
else:
618+
self.server_request_size_histogram.record(
619+
request_size_amount, duration_attrs
620+
)
606621
if token:
607622
context.detach(token)
608623

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,19 @@
4747
"http.server.active_requests",
4848
"http.server.duration",
4949
"http.server.response.size",
50+
"http.server.request.size",
5051
]
5152
_recommended_attrs = {
5253
"http.server.active_requests": _active_requests_count_attrs,
5354
"http.server.duration": _duration_attrs,
5455
"http.server.response.size": _duration_attrs,
56+
"http.server.request.size": _duration_attrs,
5557
}
5658

5759

5860
async def http_app(scope, receive, send):
5961
message = await receive()
62+
scope["headers"] = [(b"content-length", b"128")]
6063
assert scope["type"] == "http"
6164
if message.get("type") == "http.request":
6265
await send(
@@ -99,6 +102,7 @@ async def error_asgi(scope, receive, send):
99102
assert isinstance(scope, dict)
100103
assert scope["type"] == "http"
101104
message = await receive()
105+
scope["headers"] = [(b"content-length", b"128")]
102106
if message.get("type") == "http.request":
103107
try:
104108
raise ValueError
@@ -592,6 +596,8 @@ def test_basic_metric_success(self):
592596
)
593597
elif metric.name == "http.server.response.size":
594598
self.assertEqual(1024, point.sum)
599+
elif metric.name == "http.server.request.size":
600+
self.assertEqual(128, point.sum)
595601
elif isinstance(point, NumberDataPoint):
596602
self.assertDictEqual(
597603
expected_requests_count_attributes,
@@ -630,7 +636,7 @@ async def target_asgi(scope, receive, send):
630636
expected_target,
631637
)
632638
assertions += 1
633-
self.assertEqual(assertions, 2)
639+
self.assertEqual(assertions, 3)
634640

635641
def test_no_metric_for_websockets(self):
636642
self.scope = {

instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"http.server.active_requests",
4646
"http.server.duration",
4747
"http.server.response.size",
48+
"http.server.request.size",
4849
]
4950
_recommended_attrs = {
5051
"http.server.active_requests": _active_requests_count_attrs,
@@ -53,6 +54,10 @@
5354
*_duration_attrs,
5455
SpanAttributes.HTTP_TARGET,
5556
},
57+
"http.server.request.size": {
58+
*_duration_attrs,
59+
SpanAttributes.HTTP_TARGET,
60+
},
5661
}
5762

5863

@@ -251,16 +256,26 @@ def test_basic_metric_success(self):
251256

252257
def test_basic_post_request_metric_success(self):
253258
start = default_timer()
254-
self._client.post("/foobar")
259+
response = self._client.post(
260+
"/foobar",
261+
json={"foo": "bar"},
262+
)
255263
duration = max(round((default_timer() - start) * 1000), 0)
264+
response_size = int(response.headers.get("content-length"))
265+
request_size = int(response.request.headers.get("content-length"))
256266
metrics_list = self.memory_metrics_reader.get_metrics_data()
257267
for metric in (
258268
metrics_list.resource_metrics[0].scope_metrics[0].metrics
259269
):
260270
for point in list(metric.data.data_points):
261271
if isinstance(point, HistogramDataPoint):
262272
self.assertEqual(point.count, 1)
263-
self.assertAlmostEqual(duration, point.sum, delta=30)
273+
if metric.name == "http.server.duration":
274+
self.assertAlmostEqual(duration, point.sum, delta=30)
275+
elif metric.name == "http.server.response.size":
276+
self.assertEqual(response_size, point.sum)
277+
elif metric.name == "http.server.request.size":
278+
self.assertEqual(request_size, point.sum)
264279
if isinstance(point, NumberDataPoint):
265280
self.assertEqual(point.value, 0)
266281

instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -250,24 +250,30 @@ def _start_span(
250250
# * ipv4:127.0.0.1:57284
251251
# * ipv4:10.2.1.1:57284,127.0.0.1:57284
252252
#
253-
try:
254-
ip, port = (
255-
context.peer().split(",")[0].split(":", 1)[1].rsplit(":", 1)
256-
)
257-
ip = unquote(ip)
258-
attributes.update(
259-
{
260-
SpanAttributes.NET_PEER_IP: ip,
261-
SpanAttributes.NET_PEER_PORT: port,
262-
}
263-
)
253+
if context.peer() != "unix:":
254+
try:
255+
ip, port = (
256+
context.peer()
257+
.split(",")[0]
258+
.split(":", 1)[1]
259+
.rsplit(":", 1)
260+
)
261+
ip = unquote(ip)
262+
attributes.update(
263+
{
264+
SpanAttributes.NET_PEER_IP: ip,
265+
SpanAttributes.NET_PEER_PORT: port,
266+
}
267+
)
264268

265-
# other telemetry sources add this, so we will too
266-
if ip in ("[::1]", "127.0.0.1"):
267-
attributes[SpanAttributes.NET_PEER_NAME] = "localhost"
269+
# other telemetry sources add this, so we will too
270+
if ip in ("[::1]", "127.0.0.1"):
271+
attributes[SpanAttributes.NET_PEER_NAME] = "localhost"
268272

269-
except IndexError:
270-
logger.warning("Failed to parse peer address '%s'", context.peer())
273+
except IndexError:
274+
logger.warning(
275+
"Failed to parse peer address '%s'", context.peer()
276+
)
271277

272278
return self._tracer.start_as_current_span(
273279
name=handler_call_details.method,

0 commit comments

Comments
 (0)