$43 GRAYBYTE WORDPRESS FILE MANAGER $36

SERVER : premium201.web-hosting.com #1 SMP Wed Mar 26 12:08:09 UTC 2025
SERVER IP : 104.21.15.130 | ADMIN IP 216.73.216.174
OPTIONS : CRL = ON | WGT = ON | SDO = OFF | PKEX = OFF
DEACTIVATED : NONE

/opt/hc_python/lib/python3.12/site-packages/sentry_sdk/

HOME
Current File : /opt/hc_python/lib/python3.12/site-packages/sentry_sdk//sessions.py
import os
import warnings
from threading import Thread, Lock, Event
from contextlib import contextmanager

import sentry_sdk
from sentry_sdk.envelope import Envelope
from sentry_sdk.session import Session
from sentry_sdk.utils import format_timestamp

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from typing import Any
    from typing import Callable
    from typing import Dict
    from typing import Generator
    from typing import List
    from typing import Optional
    from typing import Union


def is_auto_session_tracking_enabled(hub=None):
    # type: (Optional[sentry_sdk.Hub]) -> Union[Any, bool, None]
    """DEPRECATED: Utility function to find out if session tracking is enabled."""

    # Internal callers should use private _is_auto_session_tracking_enabled, instead.
    warnings.warn(
        "This function is deprecated and will be removed in the next major release. "
        "There is no public API replacement.",
        DeprecationWarning,
        stacklevel=2,
    )

    if hub is None:
        hub = sentry_sdk.Hub.current

    should_track = hub.scope._force_auto_session_tracking

    if should_track is None:
        client_options = hub.client.options if hub.client else {}
        should_track = client_options.get("auto_session_tracking", False)

    return should_track


@contextmanager
def auto_session_tracking(hub=None, session_mode="application"):
    # type: (Optional[sentry_sdk.Hub], str) -> Generator[None, None, None]
    """DEPRECATED: Use track_session instead
    Starts and stops a session automatically around a block.
    """
    warnings.warn(
        "This function is deprecated and will be removed in the next major release. "
        "Use track_session instead.",
        DeprecationWarning,
        stacklevel=2,
    )

    if hub is None:
        hub = sentry_sdk.Hub.current
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", DeprecationWarning)
        should_track = is_auto_session_tracking_enabled(hub)
    if should_track:
        hub.start_session(session_mode=session_mode)
    try:
        yield
    finally:
        if should_track:
            hub.end_session()


def is_auto_session_tracking_enabled_scope(scope):
    # type: (sentry_sdk.Scope) -> bool
    """
    DEPRECATED: Utility function to find out if session tracking is enabled.
    """

    warnings.warn(
        "This function is deprecated and will be removed in the next major release. "
        "There is no public API replacement.",
        DeprecationWarning,
        stacklevel=2,
    )

    # Internal callers should use private _is_auto_session_tracking_enabled, instead.
    return _is_auto_session_tracking_enabled(scope)


def _is_auto_session_tracking_enabled(scope):
    # type: (sentry_sdk.Scope) -> bool
    """
    Utility function to find out if session tracking is enabled.
    """

    should_track = scope._force_auto_session_tracking
    if should_track is None:
        client_options = sentry_sdk.get_client().options
        should_track = client_options.get("auto_session_tracking", False)

    return should_track


@contextmanager
def auto_session_tracking_scope(scope, session_mode="application"):
    # type: (sentry_sdk.Scope, str) -> Generator[None, None, None]
    """DEPRECATED: This function is a deprecated alias for track_session.
    Starts and stops a session automatically around a block.
    """

    warnings.warn(
        "This function is a deprecated alias for track_session and will be removed in the next major release.",
        DeprecationWarning,
        stacklevel=2,
    )

    with track_session(scope, session_mode=session_mode):
        yield


@contextmanager
def track_session(scope, session_mode="application"):
    # type: (sentry_sdk.Scope, str) -> Generator[None, None, None]
    """
    Start a new session in the provided scope, assuming session tracking is enabled.
    This is a no-op context manager if session tracking is not enabled.
    """

    should_track = _is_auto_session_tracking_enabled(scope)
    if should_track:
        scope.start_session(session_mode=session_mode)
    try:
        yield
    finally:
        if should_track:
            scope.end_session()


TERMINAL_SESSION_STATES = ("exited", "abnormal", "crashed")
MAX_ENVELOPE_ITEMS = 100


def make_aggregate_envelope(aggregate_states, attrs):
    # type: (Any, Any) -> Any
    return {"attrs": dict(attrs), "aggregates": list(aggregate_states.values())}


class SessionFlusher:
    def __init__(
        self,
        capture_func,  # type: Callable[[Envelope], None]
        flush_interval=60,  # type: int
    ):
        # type: (...) -> None
        self.capture_func = capture_func
        self.flush_interval = flush_interval
        self.pending_sessions = []  # type: List[Any]
        self.pending_aggregates = {}  # type: Dict[Any, Any]
        self._thread = None  # type: Optional[Thread]
        self._thread_lock = Lock()
        self._aggregate_lock = Lock()
        self._thread_for_pid = None  # type: Optional[int]
        self.__shutdown_requested = Event()

    def flush(self):
        # type: (...) -> None
        pending_sessions = self.pending_sessions
        self.pending_sessions = []

        with self._aggregate_lock:
            pending_aggregates = self.pending_aggregates
            self.pending_aggregates = {}

        envelope = Envelope()
        for session in pending_sessions:
            if len(envelope.items) == MAX_ENVELOPE_ITEMS:
                self.capture_func(envelope)
                envelope = Envelope()

            envelope.add_session(session)

        for attrs, states in pending_aggregates.items():
            if len(envelope.items) == MAX_ENVELOPE_ITEMS:
                self.capture_func(envelope)
                envelope = Envelope()

            envelope.add_sessions(make_aggregate_envelope(states, attrs))

        if len(envelope.items) > 0:
            self.capture_func(envelope)

    def _ensure_running(self):
        # type: (...) -> None
        """
        Check that we have an active thread to run in, or create one if not.

        Note that this might fail (e.g. in Python 3.12 it's not possible to
        spawn new threads at interpreter shutdown). In that case self._running
        will be False after running this function.
        """
        if self._thread_for_pid == os.getpid() and self._thread is not None:
            return None
        with self._thread_lock:
            if self._thread_for_pid == os.getpid() and self._thread is not None:
                return None

            def _thread():
                # type: (...) -> None
                running = True
                while running:
                    running = not self.__shutdown_requested.wait(self.flush_interval)
                    self.flush()

            thread = Thread(target=_thread)
            thread.daemon = True
            try:
                thread.start()
            except RuntimeError:
                # Unfortunately at this point the interpreter is in a state that no
                # longer allows us to spawn a thread and we have to bail.
                self.__shutdown_requested.set()
                return None

            self._thread = thread
            self._thread_for_pid = os.getpid()

        return None

    def add_aggregate_session(
        self,
        session,  # type: Session
    ):
        # type: (...) -> None
        # NOTE on `session.did`:
        # the protocol can deal with buckets that have a distinct-id, however
        # in practice we expect the python SDK to have an extremely high cardinality
        # here, effectively making aggregation useless, therefore we do not
        # aggregate per-did.

        # For this part we can get away with using the global interpreter lock
        with self._aggregate_lock:
            attrs = session.get_json_attrs(with_user_info=False)
            primary_key = tuple(sorted(attrs.items()))
            secondary_key = session.truncated_started  # (, session.did)
            states = self.pending_aggregates.setdefault(primary_key, {})
            state = states.setdefault(secondary_key, {})

            if "started" not in state:
                state["started"] = format_timestamp(session.truncated_started)
            # if session.did is not None:
            #     state["did"] = session.did
            if session.status == "crashed":
                state["crashed"] = state.get("crashed", 0) + 1
            elif session.status == "abnormal":
                state["abnormal"] = state.get("abnormal", 0) + 1
            elif session.errors > 0:
                state["errored"] = state.get("errored", 0) + 1
            else:
                state["exited"] = state.get("exited", 0) + 1

    def add_session(
        self,
        session,  # type: Session
    ):
        # type: (...) -> None
        if session.session_mode == "request":
            self.add_aggregate_session(session)
        else:
            self.pending_sessions.append(session.to_json())
        self._ensure_running()

    def kill(self):
        # type: (...) -> None
        self.__shutdown_requested.set()


Current_dir [ NOT WRITEABLE ] Document_root [ WRITEABLE ]


[ Back ]
NAME
SIZE
LAST TOUCH
USER
CAN-I?
FUNCTIONS
..
--
3 Dec 2025 9.30 AM
root / root
0755
__pycache__
--
3 Dec 2025 9.30 AM
root / root
0755
ai
--
3 Dec 2025 9.30 AM
root / root
0755
crons
--
3 Dec 2025 9.30 AM
root / root
0755
integrations
--
3 Dec 2025 9.30 AM
root / root
0755
profiler
--
3 Dec 2025 9.30 AM
root / root
0755
__init__.py
1.377 KB
3 Dec 2025 9.30 AM
root / root
0644
_compat.py
3.043 KB
3 Dec 2025 9.30 AM
root / root
0644
_init_implementation.py
2.499 KB
3 Dec 2025 9.30 AM
root / root
0644
_log_batcher.py
5.371 KB
3 Dec 2025 9.30 AM
root / root
0644
_lru_cache.py
1.2 KB
3 Dec 2025 9.30 AM
root / root
0644
_metrics_batcher.py
4.924 KB
3 Dec 2025 9.30 AM
root / root
0644
_queue.py
10.986 KB
3 Dec 2025 9.30 AM
root / root
0644
_types.py
10.178 KB
3 Dec 2025 9.30 AM
root / root
0644
_werkzeug.py
3.646 KB
3 Dec 2025 9.30 AM
root / root
0644
api.py
14.924 KB
3 Dec 2025 9.30 AM
root / root
0644
attachments.py
3.036 KB
3 Dec 2025 9.30 AM
root / root
0644
client.py
41.112 KB
3 Dec 2025 9.30 AM
root / root
0644
consts.py
52.474 KB
3 Dec 2025 9.30 AM
root / root
0644
debug.py
0.995 KB
3 Dec 2025 9.30 AM
root / root
0644
envelope.py
10.228 KB
3 Dec 2025 9.30 AM
root / root
0644
feature_flags.py
2.18 KB
3 Dec 2025 9.30 AM
root / root
0644
hub.py
25.145 KB
3 Dec 2025 9.30 AM
root / root
0644
logger.py
2.731 KB
3 Dec 2025 9.30 AM
root / root
0644
metrics.py
1.996 KB
3 Dec 2025 9.30 AM
root / root
0644
monitor.py
3.554 KB
3 Dec 2025 9.30 AM
root / root
0644
py.typed
0 KB
3 Dec 2025 9.30 AM
root / root
0644
scope.py
63.887 KB
3 Dec 2025 9.30 AM
root / root
0644
scrubber.py
5.922 KB
3 Dec 2025 9.30 AM
root / root
0644
serializer.py
13.217 KB
3 Dec 2025 9.30 AM
root / root
0644
session.py
5.458 KB
3 Dec 2025 9.30 AM
root / root
0644
sessions.py
8.957 KB
3 Dec 2025 9.30 AM
root / root
0644
spotlight.py
8.475 KB
3 Dec 2025 9.30 AM
root / root
0644
tracing.py
50.534 KB
3 Dec 2025 9.30 AM
root / root
0644
tracing_utils.py
39.59 KB
3 Dec 2025 9.30 AM
root / root
0644
transport.py
31.131 KB
3 Dec 2025 9.30 AM
root / root
0644
types.py
1.239 KB
3 Dec 2025 9.30 AM
root / root
0644
utils.py
62.402 KB
3 Dec 2025 9.30 AM
root / root
0644
worker.py
4.359 KB
3 Dec 2025 9.30 AM
root / root
0644

GRAYBYTE WORDPRESS FILE MANAGER @ 2025 CONTACT ME
Static GIF