Skip to content
Closed
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
37 changes: 6 additions & 31 deletions src/sentry/event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import six

from datetime import datetime, timedelta
from django.conf import settings
from django.core.cache import cache
from django.db import connection, IntegrityError, router, transaction
from django.db.models import Func
Expand Down Expand Up @@ -438,34 +437,6 @@ def materialize_metadata(self):
"location": event_type.get_location(event_metadata),
}

def get_search_message(self, event_metadata=None, culprit=None):
"""This generates the internal event.message attribute which is used
for search purposes. It adds a bunch of data from the metadata and
the culprit.
"""
if event_metadata is None:
event_metadata = self.get_event_type().get_metadata(self._data)
if culprit is None:
culprit = self.get_culprit()

data = self._data
message = ""

if data.get("logentry"):
message += data["logentry"].get("formatted") or data["logentry"].get("message") or ""

if event_metadata:
for value in six.itervalues(event_metadata):
value_u = force_text(value, errors="replace")
if value_u not in message:
message = u"{} {}".format(message, value_u)

if culprit and culprit not in message:
culprit_u = force_text(culprit, errors="replace")
message = u"{} {}".format(message, culprit_u)

return trim(message.strip(), settings.SENTRY_MAX_MESSAGE_LENGTH)

def save(self, project_id, raw=False, assume_normalized=False):
"""
We re-insert events with duplicate IDs into Snuba, which is responsible
Expand Down Expand Up @@ -615,13 +586,17 @@ def save(self, project_id, raw=False, assume_normalized=False):
# however the data is dynamically overridden by Event.title and
# Event.location (See Event.as_dict)
materialized_metadata = self.materialize_metadata()
event_metadata = materialized_metadata["metadata"]
data.update(materialized_metadata)
data["culprit"] = culprit

# index components into ``Event.message``
# See GH-3248
event.message = self.get_search_message(event_metadata, culprit)
# TODO: We temporarily save the search message into the message field to
# maintain backward compatibility with the Django event model. Once
# "store.use-django-event" is turned off for good, we can just reference
# event.search_message everywhere.
event.message = event.search_message

received_timestamp = event.data.get("received") or float(event.datetime.strftime("%s"))

if not issueless_event:
Expand Down
4 changes: 2 additions & 2 deletions src/sentry/eventstore/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ def get_latest_event_id(self, event, filter):
"""
raise NotImplementedError

def create_event(self, project_id=None, event_id=None, group_id=None, message=None, data=None):
def create_event(self, project_id=None, event_id=None, group_id=None, data=None):
"""
Returns an Event from processed data
"""
return Event(
project_id=project_id, event_id=event_id, group_id=group_id, message=message, data=data
project_id=project_id, event_id=event_id, group_id=group_id, data=data
)

def bind_nodes(self, object_list, node_name="data"):
Expand Down
17 changes: 10 additions & 7 deletions src/sentry/eventstore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from sentry.models import EventCommon, EventDict
from sentry.db.models import NodeData

from sentry.snuba.events import Columns


Expand All @@ -16,13 +15,14 @@ def ref_func(x):


class Event(EventCommon):
def __init__(
self, project_id, event_id, group_id=None, message=None, data=None, snuba_data=None
):
"""
Event backed by nodestore and Snuba.
"""

def __init__(self, project_id, event_id, group_id=None, data=None, snuba_data=None):
self.project_id = project_id
self.event_id = event_id
self.group_id = group_id
self.message = message
self.data = data
self._snuba_data = snuba_data or {}
super(Event, self).__init__()
Expand Down Expand Up @@ -73,9 +73,8 @@ def platform(self):

@property
def message(self):
if self._message:
if hasattr(self, "_message"):
return self._message

column = self.__get_column_name(Columns.MESSAGE)
if column in self._snuba_data:
return self._snuba_data[column]
Expand All @@ -84,6 +83,10 @@ def message(self):

@message.setter
def message(self, value):
"""
This can be removed once Django Event is removed and we no longer need to manually
update this field in event_manager.save().
"""
self._message = value

@property
Expand Down
34 changes: 34 additions & 0 deletions src/sentry/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import string

from collections import OrderedDict
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from hashlib import md5

Expand All @@ -27,6 +29,7 @@
from sentry.utils.canonical import CanonicalKeyDict, CanonicalKeyView
from sentry.utils.safe import get_path
from sentry.utils.strings import truncatechars
from sentry.utils.safe import trim


class EventDict(CanonicalKeyDict):
Expand Down Expand Up @@ -352,6 +355,37 @@ def bind_node_data(self):
ref = self.data.get_ref(self)
self.data.bind_data(node_data, ref=ref)

@property
def search_message(self):
"""
The internal search_message attribute is only used for search purposes.
It adds a bunch of data from the metadata and the culprit.
"""
data = self.data
culprit = self.culprit

event_metadata = self.get_event_metadata()

if event_metadata is None:
event_metadata = eventtypes.get(self.get_event_type())().get_metadata(self.data)

message = ""

if data.get("logentry"):
message += data["logentry"].get("formatted") or data["logentry"].get("message") or ""

if event_metadata:
for value in six.itervalues(event_metadata):
value_u = force_text(value, errors="replace")
if value_u not in message:
message = u"{} {}".format(message, value_u)

if culprit and culprit not in message:
culprit_u = force_text(culprit, errors="replace")
message = u"{} {}".format(message, culprit_u)

return trim(message.strip(), settings.SENTRY_MAX_MESSAGE_LENGTH)


def ref_func(x):
return x.project_id or x.project.id
Expand Down
6 changes: 1 addition & 5 deletions src/sentry/tasks/unmerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
EventAttachment,
)
from sentry.similarity import features
from sentry.snuba.events import Columns
from sentry.tasks.base import instrumented_task
from six.moves import reduce

Expand Down Expand Up @@ -99,7 +98,7 @@ def _generate_culprit(event):
},
"last_seen": lambda event: event.datetime,
"level": lambda event: LOG_LEVELS_MAP.get(event.get_tag("level"), logging.ERROR),
"message": lambda event: event.message,
"message": lambda event: event.search_message,
"times_seen": lambda event: 0,
}

Expand Down Expand Up @@ -505,9 +504,6 @@ def unmerge(
filter=eventstore.Filter(
project_ids=[project_id], group_ids=[source.id], conditions=conditions
),
# We need the text-only "search message" from Snuba, not the raw message
# dict field from nodestore.
additional_columns=[Columns.MESSAGE],
limit=batch_size,
referrer="unmerge",
orderby=["-timestamp", "-event_id"],
Expand Down
8 changes: 4 additions & 4 deletions src/sentry/web/frontend/debug/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,13 @@ def get(self, request):
data = event_manager.get_data()
event_type = event_manager.get_event_type()

group.message = event_manager.get_search_message()
group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)}

event = eventstore.create_event(
event_id="a" * 32, group_id=group.id, project_id=project.id, data=data.data
)

group.message = event.search_message
group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)}

activity = Activity(group=group, project=event.project, **self.get_activity(request, event))

return render_to_response(
Expand Down Expand Up @@ -244,7 +244,7 @@ def alert(request):
event.data["timestamp"] = 1504656000.0 # datetime(2017, 9, 6, 0, 0)
event_type = event_manager.get_event_type()

group.message = event_manager.get_search_message()
group.message = event.search_message
group.data = {"type": event_type.key, "metadata": event_type.get_metadata(data)}

rule = Rule(label="An example rule")
Expand Down