Skip to content

Commit

Permalink
Skeletons for new components
Browse files Browse the repository at this point in the history
  • Loading branch information
sl0thentr0py committed Jun 10, 2024
1 parent c62d515 commit 0afad75
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
11 changes: 11 additions & 0 deletions sentry_sdk/integrations/opentelemetry/contextvars_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from opentelemetry.context.contextvars_context import ContextVarsRuntimeContext


class SentryContextVarsRuntimeContext(ContextVarsRuntimeContext):
def attach(self, context):
# TODO-neel-potel do scope management
super().attach(context)

def detach(self, token):
# TODO-neel-potel not sure if we need anything here, see later
super().detach(token)
15 changes: 13 additions & 2 deletions sentry_sdk/integrations/opentelemetry/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
from importlib import import_module

from sentry_sdk.integrations import DidNotEnable, Integration
from sentry_sdk.integrations.opentelemetry.span_processor import SentrySpanProcessor
from sentry_sdk.integrations.opentelemetry.potel_span_processor import (
PotelSentrySpanProcessor,
)
from sentry_sdk.integrations.opentelemetry.contextvars_context import (
SentryContextVarsRuntimeContext,
)
from sentry_sdk.integrations.opentelemetry.propagator import SentryPropagator
from sentry_sdk.utils import logger, _get_installed_modules
from sentry_sdk._types import TYPE_CHECKING
Expand All @@ -21,6 +26,7 @@
)
from opentelemetry.propagate import set_global_textmap # type: ignore
from opentelemetry.sdk.trace import TracerProvider # type: ignore
from opentelemetry import context
except ImportError:
raise DidNotEnable("opentelemetry not installed")

Expand Down Expand Up @@ -165,9 +171,14 @@ def _import_by_path(path):

def _setup_sentry_tracing():
# type: () -> None

# TODO-neel-potel make sure lifecycle is correct
# TODO-neel-potel contribute upstream so this is not necessary
context._RUNTIME_CONTEXT = SentryContextVarsRuntimeContext()

provider = TracerProvider()

provider.add_span_processor(SentrySpanProcessor())
provider.add_span_processor(PotelSentrySpanProcessor())

trace.set_tracer_provider(provider)

Expand Down
19 changes: 19 additions & 0 deletions sentry_sdk/integrations/opentelemetry/potel_span_exporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from opentelemetry.trace import Span


class PotelSentrySpanExporter:
"""
A Sentry-specific exporter that converts OpenTelemetry Spans to Sentry Spans & Transactions.
"""

def __init__(self):
# type: () -> None
pass

def export(self, span):
# type: (Span) -> None
pass

def flush(self, timeout_millis):
# type: (int) -> bool
return True
47 changes: 47 additions & 0 deletions sentry_sdk/integrations/opentelemetry/potel_span_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from opentelemetry.sdk.trace import SpanProcessor # type: ignore
from opentelemetry.context import Context # type: ignore
from opentelemetry.trace import Span

from sentry_sdk.integrations.opentelemetry.potel_span_exporter import (
PotelSentrySpanExporter,
)
from sentry_sdk._types import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Optional


class PotelSentrySpanProcessor(SpanProcessor): # type: ignore
"""
Converts OTel spans into Sentry spans so they can be sent to the Sentry backend.
"""

def __new__(cls):
# type: () -> PotelSentrySpanProcessor
if not hasattr(cls, "instance"):
cls.instance = super().__new__(cls)

return cls.instance

def __init__(self):
# type: () -> None
self._exporter = PotelSentrySpanExporter()

def on_start(self, span, parent_context=None):
# type: (Span, Optional[Context]) -> None
pass

def on_end(self, span):
# type: (Span) -> None
self._exporter.export(span)

# TODO-neel-potel not sure we need a clear like JS
def shutdown(self):
# type () -> None
pass

# TODO-neel-potel change default? this is 30 sec
# TODO-neel-potel call this in client.flush
def force_flush(self, timeout_millis=30000):
# type (int) -> bool
self._exporter.flush(timeout_millis)

0 comments on commit 0afad75

Please sign in to comment.