Skip to content
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

feat(events tracking): add abstract class and logging implementation #80117

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 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
7 changes: 7 additions & 0 deletions src/sentry/ingest/consumer/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from sentry.utils import metrics
from sentry.utils.cache import cache_key_for_event
from sentry.utils.dates import to_datetime
from sentry.utils.event_tracker import EventStageStatus, EventTracker
from sentry.utils.sdk import set_current_event_project
from sentry.utils.snuba import RateLimitExceeded

Expand Down Expand Up @@ -200,8 +201,14 @@ def process_event(
if no_celery_mode:
cache_key = None
else:
tracker = EventTracker()
if tracker.is_tracked:
data["is_tracked"] = True
with metrics.timer("ingest_consumer._store_event"):
cache_key = processing_store.store(data)
tracker.record_event_stage_status(
event_id=data["event_id"], status=EventStageStatus.REDIS_PUT
)
save_attachments(attachments, cache_key)

try:
Expand Down
59 changes: 59 additions & 0 deletions src/sentry/utils/event_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import logging
import random
from enum import Enum


class EventStageStatus(Enum):
START = "start"
END = "end"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making the enum an integer. That would take a lot less memory in redis.

The galaxy brain version would be to create a bitmap. One bit per phase. Each event only needs 12 bits to encode all phases. https://redis.io/docs/latest/develop/data-types/bitmaps/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not writing to redis with the logging implementation but i get the idea

REDIS_PUT = "redis_put"
"""
i plan on adding the below enums for every step of the transactions pipeline
ingest_consumer_published
redis_put
save_event_started
save_event_finished
snuba_topic_put
commit_log_topic_put
ppf_topic_put
post_process_started
post_process_finished / the same as redis_deleted
"""


class EventTracker:
victoria-yining-huang marked this conversation as resolved.
Show resolved Hide resolved
"""
Logger-based implementation of EventTrackerBackend. The data will be saved in BigQuery using Google Log Sink
"""

def __init__(self, sample_rate: float = 0.01):
"""
Args:
sample_rate (float): The probability (0.0 to 1.0) that an event is recorded.
A value of 1.0 records all events, 0.1 records approximately 10% of events.
"""
self.logger = logging.getLogger("EventTracker")
victoria-yining-huang marked this conversation as resolved.
Show resolved Hide resolved
self.sample_rate = sample_rate

def is_tracked(self) -> bool:
if random.random() > self.sample_rate:
return
return True
victoria-yining-huang marked this conversation as resolved.
Show resolved Hide resolved

def record_event_stage_status(
self, event_id: str, status: EventStageStatus, is_tracked: bool = False
):
"""
Records how far an event has made it through the ingestion pipeline.
"""
if is_tracked:
extra = {"event_id": event_id, "status": status}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to do EventStageStatus.value to get the string value from the enum.

Alternatively you can use StrEnum which is probably a better approach

self.logger.info("EventTracker.recorded", extra=extra)
Loading