|
1 | | -import json |
2 | 1 | import sys |
3 | 2 | import weakref |
4 | 3 |
|
5 | | -try: |
6 | | - from urllib.parse import parse_qsl |
7 | | -except ImportError: |
8 | | - from urlparse import parse_qsl # type: ignore |
9 | | - |
10 | 4 | from sentry_sdk.api import continue_trace |
11 | 5 | from sentry_sdk._compat import reraise |
12 | 6 | from sentry_sdk.consts import OP, SPANDATA |
13 | | -from sentry_sdk.hub import Hub, _should_send_default_pii |
| 7 | +from sentry_sdk.hub import Hub |
14 | 8 | from sentry_sdk.integrations import Integration, DidNotEnable |
15 | 9 | from sentry_sdk.integrations.logging import ignore_logger |
16 | 10 | from sentry_sdk.sessions import auto_session_tracking |
|
35 | 29 | CONTEXTVARS_ERROR_MESSAGE, |
36 | 30 | SENSITIVE_DATA_SUBSTITUTE, |
37 | 31 | AnnotatedValue, |
38 | | - SentryGraphQLClientError, |
39 | | - _get_graphql_operation_name, |
40 | | - _get_graphql_operation_type, |
41 | 32 | ) |
42 | 33 |
|
43 | 34 | try: |
44 | 35 | import asyncio |
45 | 36 |
|
46 | 37 | from aiohttp import __version__ as AIOHTTP_VERSION |
47 | | - from aiohttp import ClientSession, ContentTypeError, TraceConfig |
48 | | - from aiohttp.web import Application, HTTPException, UrlDispatcher, Response |
| 38 | + from aiohttp import ClientSession, TraceConfig |
| 39 | + from aiohttp.web import Application, HTTPException, UrlDispatcher |
49 | 40 | except ImportError: |
50 | 41 | raise DidNotEnable("AIOHTTP not installed") |
51 | 42 |
|
|
54 | 45 | if TYPE_CHECKING: |
55 | 46 | from aiohttp.web_request import Request |
56 | 47 | from aiohttp.abc import AbstractMatchInfo |
57 | | - from aiohttp import ( |
58 | | - TraceRequestStartParams, |
59 | | - TraceRequestEndParams, |
60 | | - TraceRequestChunkSentParams, |
61 | | - ) |
| 48 | + from aiohttp import TraceRequestStartParams, TraceRequestEndParams |
62 | 49 | from types import SimpleNamespace |
63 | 50 | from typing import Any |
64 | 51 | from typing import Dict |
|
77 | 64 | class AioHttpIntegration(Integration): |
78 | 65 | identifier = "aiohttp" |
79 | 66 |
|
80 | | - def __init__(self, transaction_style="handler_name", capture_graphql_errors=True): |
81 | | - # type: (str, bool) -> None |
| 67 | + def __init__(self, transaction_style="handler_name"): |
| 68 | + # type: (str) -> None |
82 | 69 | if transaction_style not in TRANSACTION_STYLE_VALUES: |
83 | 70 | raise ValueError( |
84 | 71 | "Invalid value for transaction_style: %s (must be in %s)" |
85 | 72 | % (transaction_style, TRANSACTION_STYLE_VALUES) |
86 | 73 | ) |
87 | 74 | self.transaction_style = transaction_style |
88 | 75 |
|
89 | | - self.capture_graphql_errors = capture_graphql_errors |
90 | | - |
91 | 76 | @staticmethod |
92 | 77 | def setup_once(): |
93 | 78 | # type: () -> None |
@@ -126,7 +111,7 @@ async def sentry_app_handle(self, request, *args, **kwargs): |
126 | 111 | # create a task to wrap each request. |
127 | 112 | with hub.configure_scope() as scope: |
128 | 113 | scope.clear_breadcrumbs() |
129 | | - scope.add_event_processor(_make_server_processor(weak_request)) |
| 114 | + scope.add_event_processor(_make_request_processor(weak_request)) |
130 | 115 |
|
131 | 116 | transaction = continue_trace( |
132 | 117 | request.headers, |
@@ -154,7 +139,6 @@ async def sentry_app_handle(self, request, *args, **kwargs): |
154 | 139 | reraise(*_capture_exception(hub)) |
155 | 140 |
|
156 | 141 | transaction.set_http_status(response.status) |
157 | | - |
158 | 142 | return response |
159 | 143 |
|
160 | 144 | Application._handle = sentry_app_handle |
@@ -214,8 +198,7 @@ def create_trace_config(): |
214 | 198 | async def on_request_start(session, trace_config_ctx, params): |
215 | 199 | # type: (ClientSession, SimpleNamespace, TraceRequestStartParams) -> None |
216 | 200 | hub = Hub.current |
217 | | - integration = hub.get_integration(AioHttpIntegration) |
218 | | - if integration is None: |
| 201 | + if hub.get_integration(AioHttpIntegration) is None: |
219 | 202 | return |
220 | 203 |
|
221 | 204 | method = params.method.upper() |
@@ -250,95 +233,28 @@ async def on_request_start(session, trace_config_ctx, params): |
250 | 233 | params.headers[key] = value |
251 | 234 |
|
252 | 235 | trace_config_ctx.span = span |
253 | | - trace_config_ctx.is_graphql_request = params.url.path == "/graphql" |
254 | | - |
255 | | - if integration.capture_graphql_errors and trace_config_ctx.is_graphql_request: |
256 | | - trace_config_ctx.request_headers = params.headers |
257 | | - |
258 | | - async def on_request_chunk_sent(session, trace_config_ctx, params): |
259 | | - # type: (ClientSession, SimpleNamespace, TraceRequestChunkSentParams) -> None |
260 | | - integration = Hub.current.get_integration(AioHttpIntegration) |
261 | | - if integration is None: |
262 | | - return |
263 | | - |
264 | | - if integration.capture_graphql_errors and trace_config_ctx.is_graphql_request: |
265 | | - trace_config_ctx.request_body = None |
266 | | - with capture_internal_exceptions(): |
267 | | - try: |
268 | | - trace_config_ctx.request_body = json.loads(params.chunk) |
269 | | - except json.JSONDecodeError: |
270 | | - return |
271 | 236 |
|
272 | 237 | async def on_request_end(session, trace_config_ctx, params): |
273 | 238 | # type: (ClientSession, SimpleNamespace, TraceRequestEndParams) -> None |
274 | | - hub = Hub.current |
275 | | - integration = hub.get_integration(AioHttpIntegration) |
276 | | - if integration is None: |
| 239 | + if trace_config_ctx.span is None: |
277 | 240 | return |
278 | 241 |
|
279 | | - response = params.response |
280 | | - |
281 | | - if trace_config_ctx.span is not None: |
282 | | - span = trace_config_ctx.span |
283 | | - span.set_http_status(int(response.status)) |
284 | | - span.set_data("reason", response.reason) |
285 | | - |
286 | | - if ( |
287 | | - integration.capture_graphql_errors |
288 | | - and trace_config_ctx.is_graphql_request |
289 | | - and response.method in ("GET", "POST") |
290 | | - and response.status == 200 |
291 | | - ): |
292 | | - with hub.configure_scope() as scope: |
293 | | - with capture_internal_exceptions(): |
294 | | - try: |
295 | | - response_content = await response.json() |
296 | | - except ContentTypeError: |
297 | | - pass |
298 | | - else: |
299 | | - scope.add_event_processor( |
300 | | - _make_client_processor( |
301 | | - trace_config_ctx=trace_config_ctx, |
302 | | - response=response, |
303 | | - response_content=response_content, |
304 | | - ) |
305 | | - ) |
306 | | - |
307 | | - if ( |
308 | | - response_content |
309 | | - and isinstance(response_content, dict) |
310 | | - and response_content.get("errors") |
311 | | - ): |
312 | | - try: |
313 | | - raise SentryGraphQLClientError |
314 | | - except SentryGraphQLClientError as ex: |
315 | | - event, hint = event_from_exception( |
316 | | - ex, |
317 | | - client_options=hub.client.options |
318 | | - if hub.client |
319 | | - else None, |
320 | | - mechanism={ |
321 | | - "type": AioHttpIntegration.identifier, |
322 | | - "handled": False, |
323 | | - }, |
324 | | - ) |
325 | | - hub.capture_event(event, hint=hint) |
326 | | - |
327 | | - if trace_config_ctx.span is not None: |
328 | | - span.finish() |
| 242 | + span = trace_config_ctx.span |
| 243 | + span.set_http_status(int(params.response.status)) |
| 244 | + span.set_data("reason", params.response.reason) |
| 245 | + span.finish() |
329 | 246 |
|
330 | 247 | trace_config = TraceConfig() |
331 | 248 |
|
332 | 249 | trace_config.on_request_start.append(on_request_start) |
333 | | - trace_config.on_request_chunk_sent.append(on_request_chunk_sent) |
334 | 250 | trace_config.on_request_end.append(on_request_end) |
335 | 251 |
|
336 | 252 | return trace_config |
337 | 253 |
|
338 | 254 |
|
339 | | -def _make_server_processor(weak_request): |
| 255 | +def _make_request_processor(weak_request): |
340 | 256 | # type: (Callable[[], Request]) -> EventProcessor |
341 | | - def aiohttp_server_processor( |
| 257 | + def aiohttp_processor( |
342 | 258 | event, # type: Dict[str, Any] |
343 | 259 | hint, # type: Dict[str, Tuple[type, BaseException, Any]] |
344 | 260 | ): |
@@ -370,63 +286,7 @@ def aiohttp_server_processor( |
370 | 286 |
|
371 | 287 | return event |
372 | 288 |
|
373 | | - return aiohttp_server_processor |
374 | | - |
375 | | - |
376 | | -def _make_client_processor(trace_config_ctx, response, response_content): |
377 | | - # type: (SimpleNamespace, Response, Optional[Dict[str, Any]]) -> EventProcessor |
378 | | - def aiohttp_client_processor( |
379 | | - event, # type: Dict[str, Any] |
380 | | - hint, # type: Dict[str, Tuple[type, BaseException, Any]] |
381 | | - ): |
382 | | - # type: (...) -> Dict[str, Any] |
383 | | - with capture_internal_exceptions(): |
384 | | - request_info = event.setdefault("request", {}) |
385 | | - |
386 | | - parsed_url = parse_url(str(response.url), sanitize=False) |
387 | | - request_info["url"] = parsed_url.url |
388 | | - request_info["method"] = response.method |
389 | | - |
390 | | - if getattr(trace_config_ctx, "request_headers", None): |
391 | | - request_info["headers"] = _filter_headers( |
392 | | - dict(trace_config_ctx.request_headers) |
393 | | - ) |
394 | | - |
395 | | - if _should_send_default_pii(): |
396 | | - if getattr(trace_config_ctx, "request_body", None): |
397 | | - request_info["data"] = trace_config_ctx.request_body |
398 | | - |
399 | | - request_info["query_string"] = parsed_url.query |
400 | | - |
401 | | - if response.url.path == "/graphql": |
402 | | - request_info["api_target"] = "graphql" |
403 | | - |
404 | | - query = request_info.get("data") |
405 | | - if response.method == "GET": |
406 | | - query = dict(parse_qsl(parsed_url.query)) |
407 | | - |
408 | | - if query: |
409 | | - operation_name = _get_graphql_operation_name(query) |
410 | | - operation_type = _get_graphql_operation_type(query) |
411 | | - event["fingerprint"] = [ |
412 | | - operation_name, |
413 | | - operation_type, |
414 | | - response.status, |
415 | | - ] |
416 | | - event["exception"]["values"][0][ |
417 | | - "value" |
418 | | - ] = "GraphQL request failed, name: {}, type: {}".format( |
419 | | - operation_name, operation_type |
420 | | - ) |
421 | | - |
422 | | - if _should_send_default_pii() and response_content: |
423 | | - contexts = event.setdefault("contexts", {}) |
424 | | - response_context = contexts.setdefault("response", {}) |
425 | | - response_context["data"] = response_content |
426 | | - |
427 | | - return event |
428 | | - |
429 | | - return aiohttp_client_processor |
| 289 | + return aiohttp_processor |
430 | 290 |
|
431 | 291 |
|
432 | 292 | def _capture_exception(hub): |
|
0 commit comments