177 lines
5.5 KiB
Python
177 lines
5.5 KiB
Python
import uuid
|
|
from datetime import datetime, timezone
|
|
|
|
from sentry_sdk.utils import format_timestamp
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from typing import Optional
|
|
from typing import Union
|
|
from typing import Any
|
|
from typing import Dict
|
|
|
|
from sentry_sdk._types import SessionStatus
|
|
|
|
|
|
def _minute_trunc(ts):
|
|
# type: (datetime) -> datetime
|
|
return ts.replace(second=0, microsecond=0)
|
|
|
|
|
|
def _make_uuid(
|
|
val, # type: Union[str, uuid.UUID]
|
|
):
|
|
# type: (...) -> uuid.UUID
|
|
if isinstance(val, uuid.UUID):
|
|
return val
|
|
return uuid.UUID(val)
|
|
|
|
|
|
class Session:
|
|
def __init__(
|
|
self,
|
|
sid=None, # type: Optional[Union[str, uuid.UUID]]
|
|
did=None, # type: Optional[str]
|
|
timestamp=None, # type: Optional[datetime]
|
|
started=None, # type: Optional[datetime]
|
|
duration=None, # type: Optional[float]
|
|
status=None, # type: Optional[SessionStatus]
|
|
release=None, # type: Optional[str]
|
|
environment=None, # type: Optional[str]
|
|
user_agent=None, # type: Optional[str]
|
|
ip_address=None, # type: Optional[str]
|
|
errors=None, # type: Optional[int]
|
|
user=None, # type: Optional[Any]
|
|
session_mode="application", # type: str
|
|
):
|
|
# type: (...) -> None
|
|
if sid is None:
|
|
sid = uuid.uuid4()
|
|
if started is None:
|
|
started = datetime.now(timezone.utc)
|
|
if status is None:
|
|
status = "ok"
|
|
self.status = status
|
|
self.did = None # type: Optional[str]
|
|
self.started = started
|
|
self.release = None # type: Optional[str]
|
|
self.environment = None # type: Optional[str]
|
|
self.duration = None # type: Optional[float]
|
|
self.user_agent = None # type: Optional[str]
|
|
self.ip_address = None # type: Optional[str]
|
|
self.session_mode = session_mode # type: str
|
|
self.errors = 0
|
|
|
|
self.update(
|
|
sid=sid,
|
|
did=did,
|
|
timestamp=timestamp,
|
|
duration=duration,
|
|
release=release,
|
|
environment=environment,
|
|
user_agent=user_agent,
|
|
ip_address=ip_address,
|
|
errors=errors,
|
|
user=user,
|
|
)
|
|
|
|
@property
|
|
def truncated_started(self):
|
|
# type: (...) -> datetime
|
|
return _minute_trunc(self.started)
|
|
|
|
def update(
|
|
self,
|
|
sid=None, # type: Optional[Union[str, uuid.UUID]]
|
|
did=None, # type: Optional[str]
|
|
timestamp=None, # type: Optional[datetime]
|
|
started=None, # type: Optional[datetime]
|
|
duration=None, # type: Optional[float]
|
|
status=None, # type: Optional[SessionStatus]
|
|
release=None, # type: Optional[str]
|
|
environment=None, # type: Optional[str]
|
|
user_agent=None, # type: Optional[str]
|
|
ip_address=None, # type: Optional[str]
|
|
errors=None, # type: Optional[int]
|
|
user=None, # type: Optional[Any]
|
|
):
|
|
# type: (...) -> None
|
|
# If a user is supplied we pull some data form it
|
|
if user:
|
|
if ip_address is None:
|
|
ip_address = user.get("ip_address")
|
|
if did is None:
|
|
did = user.get("id") or user.get("email") or user.get("username")
|
|
|
|
if sid is not None:
|
|
self.sid = _make_uuid(sid)
|
|
if did is not None:
|
|
self.did = str(did)
|
|
if timestamp is None:
|
|
timestamp = datetime.now(timezone.utc)
|
|
self.timestamp = timestamp
|
|
if started is not None:
|
|
self.started = started
|
|
if duration is not None:
|
|
self.duration = duration
|
|
if release is not None:
|
|
self.release = release
|
|
if environment is not None:
|
|
self.environment = environment
|
|
if ip_address is not None:
|
|
self.ip_address = ip_address
|
|
if user_agent is not None:
|
|
self.user_agent = user_agent
|
|
if errors is not None:
|
|
self.errors = errors
|
|
|
|
if status is not None:
|
|
self.status = status
|
|
|
|
def close(
|
|
self,
|
|
status=None, # type: Optional[SessionStatus]
|
|
):
|
|
# type: (...) -> Any
|
|
if status is None and self.status == "ok":
|
|
status = "exited"
|
|
if status is not None:
|
|
self.update(status=status)
|
|
|
|
def get_json_attrs(
|
|
self,
|
|
with_user_info=True, # type: Optional[bool]
|
|
):
|
|
# type: (...) -> Any
|
|
attrs = {}
|
|
if self.release is not None:
|
|
attrs["release"] = self.release
|
|
if self.environment is not None:
|
|
attrs["environment"] = self.environment
|
|
if with_user_info:
|
|
if self.ip_address is not None:
|
|
attrs["ip_address"] = self.ip_address
|
|
if self.user_agent is not None:
|
|
attrs["user_agent"] = self.user_agent
|
|
return attrs
|
|
|
|
def to_json(self):
|
|
# type: (...) -> Any
|
|
rv = {
|
|
"sid": str(self.sid),
|
|
"init": True,
|
|
"started": format_timestamp(self.started),
|
|
"timestamp": format_timestamp(self.timestamp),
|
|
"status": self.status,
|
|
} # type: Dict[str, Any]
|
|
if self.errors:
|
|
rv["errors"] = self.errors
|
|
if self.did is not None:
|
|
rv["did"] = self.did
|
|
if self.duration is not None:
|
|
rv["duration"] = self.duration
|
|
attrs = self.get_json_attrs()
|
|
if attrs:
|
|
rv["attrs"] = attrs
|
|
return rv
|