-
Notifications
You must be signed in to change notification settings - Fork 614
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
Changes from 11 commits
ba9db5d
e7b5161
f050b85
4924648
ab577dc
851b0ba
239a332
6466117
8d69e7b
1471ea2
5205418
f0c3b66
7f9e04e
aeb6830
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,89 @@ | |
| return httpcore.ConnectionPool(**opts) | ||
|
|
||
|
|
||
| class _EnvelopePrinterTransport(Transport): | ||
| """Prints envelope contents to the SDK debug logger, optionally wrapping another transport.""" | ||
|
|
||
| def __init__(self, transport: "Optional[Transport]" = None) -> None: | ||
| if transport is not None: | ||
| Transport.__init__(self, options=transport.options) | ||
| self.parsed_dsn = transport.parsed_dsn | ||
| else: | ||
| Transport.__init__(self) | ||
| self._inner = transport | ||
|
|
||
| @property # type: ignore[misc] | ||
| def __class__(self) -> type: | ||
| if self._inner is not None: | ||
|
Check failure on line 1099 in sentry_sdk/transport.py
|
||
| return self._inner.__class__ | ||
| return _EnvelopePrinterTransport | ||
|
|
||
| def capture_envelope(self, envelope: "Envelope") -> None: | ||
| try: | ||
| logger.debug("--- Sentry Envelope ---") | ||
| 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.
Outdated
cursor[bot] marked this conversation as resolved.
Outdated
|
||
| 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. |
||
|
|
||
| if self._inner is not None: | ||
| self._inner.capture_envelope(envelope) | ||
|
|
||
| def flush( | ||
| self, | ||
| timeout: float, | ||
| callback: "Optional[Any]" = None, | ||
| ) -> "Any": | ||
| if self._inner is not None: | ||
| return self._inner.flush(timeout, callback) | ||
|
|
||
| def kill(self) -> "Any": | ||
| if self._inner is not None: | ||
| return self._inner.kill() | ||
|
|
||
| def record_lost_event( | ||
| self, | ||
| reason: str, | ||
| data_category: "Optional[EventDataCategory]" = None, | ||
| item: "Optional[Item]" = None, | ||
| *, | ||
| quantity: int = 1, | ||
| ) -> None: | ||
| if self._inner is not None: | ||
| self._inner.record_lost_event( | ||
| reason, data_category, item, quantity=quantity | ||
| ) | ||
|
|
||
| def is_healthy(self) -> bool: | ||
| if self._inner is not None: | ||
| return self._inner.is_healthy() | ||
| return True | ||
|
|
||
| def __getattr__(self, name: str) -> "Any": | ||
| if self._inner is not None: | ||
| return getattr(self._inner, name) | ||
| raise AttributeError(name) | ||
|
|
||
|
|
||
| class _FunctionTransport(Transport): | ||
| """ | ||
| DEPRECATED: Users wishing to provide a custom transport should subclass | ||
|
|
@@ -1147,8 +1232,10 @@ | |
| "You tried to use AsyncHttpTransport but don't have httpcore[asyncio] installed. Falling back to sync transport." | ||
| ) | ||
|
|
||
| transport = None # type: Optional[Transport] | ||
|
ericapisani marked this conversation as resolved.
Outdated
|
||
|
|
||
| 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 +1245,14 @@ | |
| 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 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 | ||
|
sentry[bot] marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| import asyncio | ||
| import logging | ||
| import pickle | ||
| import os | ||
| import pickle | ||
| import socket | ||
| import sys | ||
| import asyncio | ||
| from collections import defaultdict | ||
| from datetime import datetime, timedelta, timezone | ||
| from unittest import mock | ||
|
|
||
| import pytest | ||
|
|
||
| from tests.conftest import CapturingServer | ||
|
|
||
| try: | ||
|
|
@@ -30,23 +31,22 @@ | |
| import sentry_sdk | ||
| from sentry_sdk import ( | ||
| Client, | ||
| Hub, | ||
| add_breadcrumb, | ||
| capture_message, | ||
| isolation_scope, | ||
| get_isolation_scope, | ||
| Hub, | ||
| isolation_scope, | ||
|
Contributor
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. Probably best to remove the changes in |
||
| ) | ||
| from sentry_sdk._compat import PY37, PY38 | ||
| from sentry_sdk.envelope import Envelope, Item, parse_json, PayloadRef | ||
| from sentry_sdk.envelope import Envelope, Item, PayloadRef, parse_json | ||
| from sentry_sdk.integrations.asyncio import AsyncioIntegration | ||
| from sentry_sdk.integrations.logging import LoggingIntegration, ignore_logger | ||
| from sentry_sdk.transport import ( | ||
| KEEP_ALIVE_SOCKET_OPTIONS, | ||
| _parse_rate_limits, | ||
| AsyncHttpTransport, | ||
| HttpTransport, | ||
| _parse_rate_limits, | ||
| ) | ||
| from sentry_sdk.integrations.logging import LoggingIntegration, ignore_logger | ||
| from sentry_sdk.integrations.asyncio import AsyncioIntegration | ||
|
|
||
|
|
||
| server = None | ||
|
|
||
|
|
||


Uh oh!
There was an error while loading. Please reload this page.