|
20 | 20 | from typing import Tuple |
21 | 21 | from typing import Iterator |
22 | 22 |
|
23 | | - from sentry_sdk._types import SamplingContext |
| 23 | + from sentry_sdk._types import SamplingContext, MeasurementUnit |
24 | 24 |
|
25 | 25 |
|
26 | 26 | class _SpanRecorder(object): |
@@ -487,6 +487,7 @@ class Transaction(Span): |
487 | 487 | "_sentry_tracestate", |
488 | 488 | # tracestate data from other vendors, of the form `dogs=yes,cats=maybe` |
489 | 489 | "_third_party_tracestate", |
| 490 | + "_measurements", |
490 | 491 | ) |
491 | 492 |
|
492 | 493 | def __init__( |
@@ -515,6 +516,7 @@ def __init__( |
515 | 516 | # first time an event needs it for inclusion in the captured data |
516 | 517 | self._sentry_tracestate = sentry_tracestate |
517 | 518 | self._third_party_tracestate = third_party_tracestate |
| 519 | + self._measurements = {} # type: Dict[str, Any] |
518 | 520 |
|
519 | 521 | def __repr__(self): |
520 | 522 | # type: () -> str |
@@ -594,17 +596,30 @@ def finish(self, hub=None): |
594 | 596 | # to be garbage collected |
595 | 597 | self._span_recorder = None |
596 | 598 |
|
597 | | - return hub.capture_event( |
598 | | - { |
599 | | - "type": "transaction", |
600 | | - "transaction": self.name, |
601 | | - "contexts": {"trace": self.get_trace_context()}, |
602 | | - "tags": self._tags, |
603 | | - "timestamp": self.timestamp, |
604 | | - "start_timestamp": self.start_timestamp, |
605 | | - "spans": finished_spans, |
606 | | - } |
607 | | - ) |
| 599 | + event = { |
| 600 | + "type": "transaction", |
| 601 | + "transaction": self.name, |
| 602 | + "contexts": {"trace": self.get_trace_context()}, |
| 603 | + "tags": self._tags, |
| 604 | + "timestamp": self.timestamp, |
| 605 | + "start_timestamp": self.start_timestamp, |
| 606 | + "spans": finished_spans, |
| 607 | + } |
| 608 | + |
| 609 | + if has_custom_measurements_enabled(): |
| 610 | + event["measurements"] = self._measurements |
| 611 | + |
| 612 | + return hub.capture_event(event) |
| 613 | + |
| 614 | + def set_measurement(self, name, value, unit=""): |
| 615 | + # type: (str, float, MeasurementUnit) -> None |
| 616 | + if not has_custom_measurements_enabled(): |
| 617 | + logger.debug( |
| 618 | + "[Tracing] Experimental custom_measurements feature is disabled" |
| 619 | + ) |
| 620 | + return |
| 621 | + |
| 622 | + self._measurements[name] = {"value": value, "unit": unit} |
608 | 623 |
|
609 | 624 | def to_json(self): |
610 | 625 | # type: () -> Dict[str, Any] |
@@ -727,4 +742,5 @@ def _set_initial_sampling_decision(self, sampling_context): |
727 | 742 | has_tracing_enabled, |
728 | 743 | is_valid_sample_rate, |
729 | 744 | maybe_create_breadcrumbs_from_span, |
| 745 | + has_custom_measurements_enabled, |
730 | 746 | ) |
0 commit comments