-
Notifications
You must be signed in to change notification settings - Fork 612
feat(transport): Add EnvelopePrinterTransport for debug logging #6181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ba9db5d
e7b5161
f050b85
4924648
ab577dc
851b0ba
239a332
6466117
8d69e7b
1471ea2
5205418
f0c3b66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| from abc import ABC, abstractmethod | ||
| import asyncio | ||
| import gzip | ||
| import io | ||
| import json | ||
| import os | ||
| import gzip | ||
| import socket | ||
| import ssl | ||
| import time | ||
| import warnings | ||
| from datetime import datetime, timedelta, timezone | ||
| from abc import ABC, abstractmethod | ||
| from collections import defaultdict | ||
| from datetime import datetime, timedelta, timezone | ||
| from urllib.request import getproxies | ||
|
|
||
| try: | ||
|
|
@@ -35,36 +36,37 @@ | |
| except ImportError: | ||
| ASYNC_TRANSPORT_AVAILABLE = False | ||
|
|
||
| import urllib3 | ||
| from typing import TYPE_CHECKING, Dict, List, cast | ||
|
|
||
| import certifi | ||
| import urllib3 | ||
|
|
||
| import sentry_sdk | ||
| from sentry_sdk.consts import EndpointType | ||
| from sentry_sdk.envelope import Envelope, Item, PayloadRef | ||
| from sentry_sdk.utils import ( | ||
| Dsn, | ||
| logger, | ||
| capture_internal_exceptions, | ||
| logger, | ||
| mark_sentry_task_internal, | ||
| ) | ||
| from sentry_sdk.worker import BackgroundWorker, Worker, AsyncWorker | ||
| from sentry_sdk.envelope import Envelope, Item, PayloadRef | ||
|
|
||
| from typing import TYPE_CHECKING, cast, List, Dict | ||
| from sentry_sdk.worker import AsyncWorker, BackgroundWorker, Worker | ||
|
|
||
| if TYPE_CHECKING: | ||
| from typing import Any | ||
| from typing import Callable | ||
| from typing import DefaultDict | ||
| from typing import Iterable | ||
| from typing import Mapping | ||
| from typing import Optional | ||
| from typing import Self | ||
| from typing import Tuple | ||
| from typing import Type | ||
| from typing import Union | ||
|
|
||
| from urllib3.poolmanager import PoolManager | ||
| from urllib3.poolmanager import ProxyManager | ||
| from typing import ( | ||
| Any, | ||
| Callable, | ||
| DefaultDict, | ||
| Iterable, | ||
| Mapping, | ||
| Optional, | ||
| Self, | ||
| Tuple, | ||
| Type, | ||
| Union, | ||
| ) | ||
|
|
||
| from urllib3.poolmanager import PoolManager, ProxyManager | ||
|
|
||
| from sentry_sdk._types import Event, EventDataCategory | ||
|
|
||
|
|
@@ -1081,6 +1083,74 @@ def _make_pool( | |
| return httpcore.ConnectionPool(**opts) | ||
|
|
||
|
|
||
| class _EnvelopePrinterTransport(Transport): | ||
| """Wraps another transport, printing envelope contents to the SDK debug logger before sending.""" | ||
|
|
||
| def __init__(self, transport: "Transport") -> None: | ||
| Transport.__init__(self, options=transport.options) | ||
| self._inner = transport | ||
| self.parsed_dsn = transport.parsed_dsn | ||
|
|
||
| @property # type: ignore[misc] | ||
| def __class__(self) -> type: | ||
| return self._inner.__class__ | ||
|
|
||
| def capture_envelope(self, envelope: "Envelope") -> None: | ||
| try: | ||
| logger.debug("--- Sentry Envelope ---") | ||
|
alexander-alderman-webb marked this conversation as resolved.
|
||
| logger.debug( | ||
| "Headers: %s", json.dumps(envelope.headers, indent=2, default=str) | ||
| ) | ||
| for item in envelope.items: | ||
| logger.debug(" Item type: %s", item.type) | ||
| logger.debug( | ||
| " Item headers: %s", | ||
| json.dumps(item.headers, indent=2, default=str), | ||
| ) | ||
| try: | ||
| payload = json.loads(item.get_bytes()) | ||
| logger.debug( | ||
| " Payload:\n%s", | ||
| json.dumps(payload, indent=2, default=str), | ||
| ) | ||
| except (ValueError, TypeError): | ||
| logger.debug( | ||
| " Payload: <binary %d bytes>", | ||
| len(item.get_bytes()), | ||
| ) | ||
|
sentry[bot] marked this conversation as resolved.
|
||
| logger.debug("--- End Envelope ---") | ||
|
sentry-warden[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Envelope printing uses debug level, invisible without debug=TrueMedium Severity All logging in Reviewed by Cursor Bugbot for commit 1471ea2. Configure here. |
||
| except Exception: | ||
| pass | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Silent exception swallowing hides debug tool failuresLow Severity The bare Reviewed by Cursor Bugbot for commit 8d69e7b. Configure here. |
||
|
|
||
| self._inner.capture_envelope(envelope) | ||
|
|
||
| def flush( | ||
| self, | ||
| timeout: float, | ||
| callback: "Optional[Any]" = None, | ||
| ) -> "Any": | ||
| return self._inner.flush(timeout, callback) | ||
|
|
||
| def kill(self) -> "Any": | ||
| return self._inner.kill() | ||
|
|
||
| def record_lost_event( | ||
| self, | ||
| reason: str, | ||
| data_category: "Optional[EventDataCategory]" = None, | ||
| item: "Optional[Item]" = None, | ||
| *, | ||
| quantity: int = 1, | ||
| ) -> None: | ||
| self._inner.record_lost_event(reason, data_category, item, quantity=quantity) | ||
|
|
||
| def is_healthy(self) -> bool: | ||
| return self._inner.is_healthy() | ||
|
|
||
| def __getattr__(self, name: str) -> "Any": | ||
| return getattr(self._inner, name) | ||
|
|
||
|
|
||
| class _FunctionTransport(Transport): | ||
| """ | ||
| DEPRECATED: Users wishing to provide a custom transport should subclass | ||
|
|
@@ -1147,8 +1217,10 @@ def make_transport(options: "Dict[str, Any]") -> "Optional[Transport]": | |
| "You tried to use AsyncHttpTransport but don't have httpcore[asyncio] installed. Falling back to sync transport." | ||
| ) | ||
|
|
||
| transport = None # type: Optional[Transport] | ||
|
|
||
| if isinstance(ref_transport, Transport): | ||
| return ref_transport | ||
| transport = ref_transport | ||
| elif isinstance(ref_transport, type) and issubclass(ref_transport, Transport): | ||
| transport_cls = ref_transport | ||
| elif callable(ref_transport): | ||
|
|
@@ -1158,11 +1230,16 @@ def make_transport(options: "Dict[str, Any]") -> "Optional[Transport]": | |
| DeprecationWarning, | ||
| stacklevel=2, | ||
| ) | ||
| return _FunctionTransport(ref_transport) | ||
| transport = _FunctionTransport(ref_transport) | ||
|
|
||
| # if a transport class is given only instantiate it if the dsn is not | ||
| # empty or None | ||
|
ericapisani marked this conversation as resolved.
|
||
| if options["dsn"]: | ||
| return transport_cls(options) | ||
| if transport is None and options["dsn"]: | ||
| transport = transport_cls(options) | ||
|
|
||
| if transport is not None and os.environ.get( | ||
| "SENTRY_PRINT_ENVELOPES", "" | ||
| ).lower() in ("1", "true", "yes"): | ||
| transport = _EnvelopePrinterTransport(transport) | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| return None | ||
| return transport | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.