8000 Profiler sampling context by sentrivana · Pull Request #3840 · getsentry/sentry-python · GitHub
[go: up one dir, main page]

Skip to content

Profiler sampling context #3840

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

Merged
merged 10 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions sentry_sdk/integrations/opentelemetry/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Optional, Sequence, Union
from typing import Any, Optional, Sequence, Union
from opentelemetry.context import Context
from opentelemetry.trace import Link, SpanKind
from opentelemetry.trace.span import SpanContex 8000 t
Expand Down Expand Up @@ -152,15 +152,9 @@ def should_sample(
has_traces_sampler = callable(client.options.get("traces_sampler"))

if is_root_span and has_traces_sampler:
sampling_context = {
"transaction_context": {
"name": name,
"op": attributes.get(SentrySpanAttribute.OP),
"source": attributes.get(SentrySpanAttribute.SOURCE),
},
"parent_sampled": get_parent_sampled(parent_span_context, trace_id),
}
sampling_context.update(attributes)
sampling_context = create_sampling_context(
name, attributes, parent_span_context, trace_id
)
sample_rate = client.options["traces_sampler"](sampling_context)
else:
# Check if there is a parent with a sampling decision
Expand Down Expand Up @@ -193,3 +187,19 @@ def should_sample(

def get_description(self) -> str:
return self.__class__.__name__


def create_sampling_context(name, attributes, parent_span_context, trace_id):
# type: (str, Attributes, SpanContext, str) -> dict[str, Any]
sampling_context = {
"transaction_context": {
"name": name,
"op": attributes.get(SentrySpanAttribute.OP),
"source": attributes.get(SentrySpanAttribute.SOURCE),
},
"parent_sampled": get_parent_sampled(parent_span_context, trace_id),
}

sampling_context.update(attributes)

return sampling_context
7 changes: 5 additions & 2 deletions sentry_sdk/integrations/opentelemetry/span_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
get_profiler_id,
)
from sentry_sdk.profiler.transaction_profiler import Profile
from sentry_sdk.integrations.opentelemetry.sampler import create_sampling_context
from sentry_sdk.integrations.opentelemetry.utils import (
is_sentry_span,
convert_from_otel_timestamp,
Expand Down Expand Up @@ -126,8 +127,10 @@ def _start_profile(self, span):
# unix timestamp that is on span.start_time
# setting it to 0 means the profiler will internally measure time on start
profile = Profile(sampled, 0)
# TODO-neel-potel sampling context??
profile._set_initial_sampling_decision(sampling_context={})
sampling_context = create_sampling_context(
span.name, span.attributes, span.parent, span.context.trace_id
)
profile._set_initial_sampling_decision(sampling_context)
profile.__enter__()
set_sentry_meta(span, "profile", profile)

Expand Down
4 changes: 0 additions & 4 deletions sentry_sdk/tracing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from typing import Generator
from typing import Optional
from typing import Union

from types import FrameType


Expand Down Expand Up @@ -731,6 +730,3 @@ def get_current_span(scope=None):
LOW_QUALITY_TRANSACTION_SOURCES,
SENTRY_TRACE_HEADER_NAME,
)

if TYPE_CHECKING:
from sentry_sdk.tracing import Span
21 changes: 21 additions & 0 deletions tests/tracing/test_sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,24 @@ def test_records_lost_event_only_if_traces_sampler_enabled(

# Use Counter because order of calls does not matter
assert Counter(record_lost_event_calls) == Counter(expected_record_lost_event_calls)


@pytest.mark.parametrize("parent_sampling_decision", [True, False])
def test_profiles_sampler_gets_sampling_context(sentry_init, parent_sampling_decision):
def dummy_profiles_sampler(sampling_context):
assert sampling_context["transaction_context"] == {
"name": "dogpark",
"op": "op",
"source": "custom",
}
assert sampling_context["parent_sampled"] == parent_sampling_decision
return 1.0

sentry_init(traces_sample_rate=1.0, profiles_sampler=dummy_profiles_sampler)

sentry_trace = "12312012123120121231201212312012-1121201211212012-{}".format(
int(parent_sampling_decision)
)
with sentry_sdk.continue_trace({"sentry-trace": sentry_trace}):
with sentry_sdk.start_span(name="dogpark", op="op"):
pass
Loading
0