Skip to content

Commit ed01c12

Browse files
committed
Fix for issue - #2808: Invalid type WSGIRequest for attribute 'request' value opentelemetry
1 parent 5ddb8e7 commit ed01c12

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
## Unreleased
1414

15+
- opentelemetry-sdk: Added request filter which fixes invalid type at WSGI request headers and attributes
1516
- docs: Added sqlcommenter example
1617
([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734))
1718
- build: bump ruff to 0.14.1

opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131
ReadableLogRecord,
3232
ReadWriteLogRecord,
3333
)
34-
from opentelemetry.sdk._shared_internal import BatchProcessor, DuplicateFilter
34+
from opentelemetry.sdk._shared_internal import (
35+
BatchProcessor,
36+
DuplicateFilter,
37+
RequestFilter,
38+
)
3539
from opentelemetry.sdk.environment_variables import (
3640
OTEL_BLRP_EXPORT_TIMEOUT,
3741
OTEL_BLRP_MAX_EXPORT_BATCH_SIZE,
@@ -49,6 +53,8 @@
4953
)
5054
_logger = logging.getLogger(__name__)
5155
_logger.addFilter(DuplicateFilter())
56+
_wsgi_request_logger = logging.getLogger("django.request")
57+
_wsgi_request_logger.addFilter(RequestFilter())
5258

5359

5460
class LogExportResult(enum.Enum):

opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ def filter(self, record):
6262
return False
6363

6464

65+
class RequestFilter(logging.Filter):
66+
def filter(self, record: logging.LogRecord) -> bool:
67+
request = getattr(record, "request", None)
68+
record.request = str(request)
69+
return True
70+
71+
6572
class BatchExportStrategy(enum.Enum):
6673
EXPORT_ALL = 0
6774
EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD = 1
@@ -113,6 +120,8 @@ def __init__(
113120
)
114121
self._logger = logging.getLogger(__name__)
115122
self._logger.addFilter(DuplicateFilter())
123+
self._wsgi_request_logger = logging.getLogger("django.request")
124+
self._wsgi_request_logger.addFilter(RequestFilter())
116125
self._exporting = exporting
117126

118127
self._shutdown = False

opentelemetry-sdk/tests/shared_internal/test_batch_processor.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
)
3939
from opentelemetry.sdk._shared_internal import (
4040
DuplicateFilter,
41+
RequestFilter,
4142
)
4243
from opentelemetry.sdk.trace import ReadableSpan
4344
from opentelemetry.sdk.trace.export import BatchSpanProcessor
@@ -264,3 +265,49 @@ def test_duplicate_logs_filter_works(self):
264265
test_logger.info("message")
265266
test_logger.info("message")
266267
self.assertEqual(len(cm.output), 1)
268+
269+
270+
class TestRequestFilter(unittest.TestCase):
271+
def test_converts_http_request_to_string(self):
272+
class DummyRequest:
273+
def __str__(self):
274+
return "<DummyRequest method=GET path=/example/>"
275+
276+
request = DummyRequest()
277+
278+
record = logging.LogRecord(
279+
name="django.request",
280+
level=logging.ERROR,
281+
pathname=__file__,
282+
lineno=0,
283+
msg="test message",
284+
args=(),
285+
exc_info=None,
286+
)
287+
record.request = request
288+
289+
expected_repr = str(request)
290+
291+
request_filter = RequestFilter()
292+
result = request_filter.filter(record)
293+
294+
self.assertTrue(result)
295+
self.assertEqual(getattr(record, "request", None), expected_repr)
296+
self.assertIsInstance(getattr(record, "request", None), str)
297+
298+
def test_handles_missing_request_attribute(self):
299+
record = logging.LogRecord(
300+
name="django.request",
301+
level=logging.INFO,
302+
pathname=__file__,
303+
lineno=0,
304+
msg="no request",
305+
args=(),
306+
exc_info=None,
307+
)
308+
309+
request_filter = RequestFilter()
310+
result = request_filter.filter(record)
311+
312+
self.assertTrue(result)
313+
self.assertEqual(getattr(record, "request", None), "None")

0 commit comments

Comments
 (0)