Browse Source

Add support for event message

David Burke 4 years ago
parent
commit
cd82fe6f26

+ 5 - 1
event_store/serializers.py

@@ -5,7 +5,7 @@ from django.db import transaction, connection
 from rest_framework import serializers
 from sentry.eventtypes.error import ErrorEvent
 from sentry.eventtypes.base import DefaultEvent
-from issues.models import EventType, Event, Issue, EventTagKey, EventTag
+from issues.models import EventType, Event, Issue, EventTagKey
 from .event_tag_processors import TAG_PROCESSORS
 from .event_context_processors import EVENT_CONTEXT_PROCESSORS
 
@@ -117,6 +117,9 @@ class StoreDefaultSerializer(serializers.Serializer):
                     contexts[processor.name] = processor_contexts
         return contexts
 
+    def get_message(self, data):
+        return data.get("logentry", {}).get("message", "")
+
     def create(self, project_id: int, data):
         eventtype = self.get_eventtype()
         metadata = eventtype.get_metadata(data)
@@ -149,6 +152,7 @@ class StoreDefaultSerializer(serializers.Serializer):
                     "culprit": culprit,
                     "exception": exception,
                     "metadata": metadata,
+                    "message": self.get_message(data),
                     "modules": data.get("modules"),
                     "platform": data["platform"],
                     "request": request,

+ 3 - 1
event_store/test_data/incoming_events/sentry_cli_send_event_no_level.json

@@ -1,6 +1,8 @@
 {
   "event_id": "142a8bb0193f447a9508180d1904f614",
-  "logentry": { "message": "hello there!" },
+  "logentry": {
+    "message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+  },
   "platform": "native",
   "timestamp": 1596820277.125992,
   "server_name": "pop-os",

+ 13 - 4
event_store/test_data/oss_sentry_events/sentry_cli_send_event_no_level.json

@@ -4,17 +4,19 @@
   "userReport": null,
   "projectID": "22",
   "previousEventID": null,
-  "message": "hello there!",
+  "message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
   "id": "2985",
   "size": 2971,
   "errors": [],
   "culprit": "",
-  "title": "hello there!",
+  "title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labo...",
   "platform": "native",
   "location": null,
   "nextEventID": null,
   "type": "default",
-  "metadata": { "title": "hello there!" },
+  "metadata": {
+    "title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labo..."
+  },
   "groupingConfig": { "id": "legacy:2019-03-12" },
   "crashFile": null,
   "tags": [
@@ -38,7 +40,14 @@
     "data": {},
     "id": null
   },
-  "entries": [{ "type": "message", "data": { "formatted": "hello there!" } }],
+  "entries": [
+    {
+      "type": "message",
+      "data": {
+        "formatted": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+      }
+    }
+  ],
   "packages": {},
   "sdk": {
     "version": "1.55.1",

+ 8 - 4
event_store/test_data/oss_sentry_json/sentry_cli_send_event_no_level.json

@@ -4,7 +4,7 @@
   "release": null,
   "dist": null,
   "platform": "native",
-  "message": "hello there!",
+  "message": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
   "datetime": "2020-08-07T17:11:17.126000Z",
   "time_spent": null,
   "tags": [
@@ -77,13 +77,17 @@
   "key_id": "22",
   "level": "error",
   "location": null,
-  "logentry": { "formatted": "hello there!" },
+  "logentry": {
+    "formatted": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+  },
   "logger": "",
-  "metadata": { "title": "hello there!" },
+  "metadata": {
+    "title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labo..."
+  },
   "received": 1596821236.23,
   "sdk": { "version": "1.55.1", "name": "sentry-cli" },
   "timestamp": 1596820277.126,
-  "title": "hello there!",
+  "title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labo...",
   "type": "default",
   "use_rust_normalize": true,
   "user": { "username": "user", "ip_address": "173.75.141.54" },

+ 4 - 0
issues/models.py

@@ -170,6 +170,10 @@ class Event(models.Model):
     def culprit(self):
         return self.data.get("culprit")
 
+    @property
+    def message(self):
+        return self.data.get("message")
+
     @property
     def user_report(self):
         return UserReport.objects.filter(event_id=self.pk).first()

+ 3 - 1
issues/serializers.py

@@ -33,7 +33,7 @@ class EventSerializer(serializers.ModelSerializer):
             "entries",
             # "errors",
             # "location",
-            # "message",
+            "message",
             "metadata",
             "packages",
             "platform",
@@ -46,12 +46,14 @@ class EventSerializer(serializers.ModelSerializer):
 
 
 class EventDetailSerializer(EventSerializer):
+    projectID = serializers.IntegerField(source="issue.project_id")
     userReport = UserReportSerializer(source="user_report")
     nextEventID = serializers.SerializerMethodField()
     previousEventID = serializers.SerializerMethodField()
 
     class Meta(EventSerializer.Meta):
         fields = EventSerializer.Meta.fields + (
+            "projectID",
             "userReport",
             "nextEventID",
             "previousEventID",

+ 45 - 2
issues/tests/test_sentry_api_compat.py

@@ -33,11 +33,34 @@ class SentryAPICompatTestCase(GlitchTipTestCase):
             reverse("csp_store", args=[self.project.id]) + "?sentry_key=" + key.hex
         )
 
+    # Upgrade functions handle intentional differences between GlitchTip and Sentry OSS
+    def upgrade_title(self, value: str):
+        """ Sentry OSS uses ... while GlitchTip uses unicode …"""
+        if value[-1] == "…":
+            return value[:-4]
+        return value.strip("...")
+
+    def upgrade_metadata(self, value: dict):
+        value["title"] = self.upgrade_title(value.get("title"))
+        return value
+
     def assertCompareData(self, data1: Dict, data2: Dict, fields: List[str]):
         """ Compare data of two dict objects. Compare only provided fields list """
         for field in fields:
+            field_value1 = data1.get(field)
+            field_value2 = data2.get(field)
+            if field == "title" and isinstance(field_value1, str):
+                field_value1 = self.upgrade_title(field_value1)
+                field_value2 = self.upgrade_title(field_value2)
+            if (
+                field == "metadata"
+                and isinstance(field_value1, dict)
+                and field_value1.get("title")
+            ):
+                field_value1 = self.upgrade_metadata(field_value1)
+                field_value2 = self.upgrade_metadata(field_value2)
             self.assertEqual(
-                data1.get(field), data2.get(field), f"Failed for field '{field}'",
+                field_value1, field_value2, f"Failed for field '{field}'",
             )
 
     def get_json_test_data(self, name: str):
@@ -327,4 +350,24 @@ class SentryAPICompatTestCase(GlitchTipTestCase):
         res = self.client.post(self.event_store_url, sdk_error, format="json")
         event = Event.objects.get(pk=res.data["id"])
         event_json = event.event_json()
-        self.assertEqual(event_json["title"], sentry_json["title"])
+        self.assertCompareData(event_json, sentry_json, ["title", "message"])
+        self.assertEqual(event_json["project"], event.issue.project_id)
+
+        url = self.get_project_events_detail(event.pk)
+        res = self.client.get(url)
+        self.assertCompareData(
+            res.data,
+            sentry_data,
+            [
+                "userReport",
+                "title",
+                "culprit",
+                "type",
+                "metadata",
+                "message",
+                "platform",
+                "previousEventID",
+            ],
+        )
+        self.assertEqual(res.data["projectID"], event.issue.project_id)
+

+ 10 - 10
poetry.lock

@@ -111,10 +111,10 @@ description = "The AWS SDK for Python"
 name = "boto3"
 optional = false
 python-versions = "*"
-version = "1.14.39"
+version = "1.14.41"
 
 [package.dependencies]
-botocore = ">=1.17.39,<1.18.0"
+botocore = ">=1.17.41,<1.18.0"
 jmespath = ">=0.7.1,<1.0.0"
 s3transfer = ">=0.3.0,<0.4.0"
 
@@ -124,7 +124,7 @@ description = "Low-level, data-driven core of boto 3."
 name = "botocore"
 optional = false
 python-versions = "*"
-version = "1.17.39"
+version = "1.17.41"
 
 [package.dependencies]
 docutils = ">=0.10,<0.16"
@@ -389,7 +389,7 @@ description = "Django Content Security Policy support."
 name = "django-csp"
 optional = false
 python-versions = "*"
-version = "3.6"
+version = "3.7"
 
 [package.dependencies]
 Django = ">=1.8"
@@ -1507,12 +1507,12 @@ black = [
     {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"},
 ]
 boto3 = [
-    {file = "boto3-1.14.39-py2.py3-none-any.whl", hash = "sha256:7f7bc03201dc3a97093aa8346578e3048d13665f39cfb501be31c557ed306470"},
-    {file = "boto3-1.14.39.tar.gz", hash = "sha256:b81e5f672ba66e85a0037baae8c73fcc8fca90b94a0bd591cc9e6dc25a1364fe"},
+    {file = "boto3-1.14.41-py2.py3-none-any.whl", hash = "sha256:e9a5efddf7492719ec3d4024e67170fc71a874125d37eb5211b242f23c242dac"},
+    {file = "boto3-1.14.41.tar.gz", hash = "sha256:26f76c7780470de54dfe816bcbeed57a05f53a0bec7c9ae9e8ad7b61ac4c74cc"},
 ]
 botocore = [
-    {file = "botocore-1.17.39-py2.py3-none-any.whl", hash = "sha256:b869be5ca327bdf64d4e203f3bb6036cc9700e1cb55c8633779f74e0658d5d06"},
-    {file = "botocore-1.17.39.tar.gz", hash = "sha256:fd1c42436a4271fbcc8bc53357171ff01d9a1bea8efc4c8a00e58a531efdcb31"},
+    {file = "botocore-1.17.41-py2.py3-none-any.whl", hash = "sha256:329ca6d6d5e91e97569ecd7f328cd3d627e918ce0703943f93d0b9de6af9aab2"},
+    {file = "botocore-1.17.41.tar.gz", hash = "sha256:519fcccf9c41634d2aba9dc769b0ac6aa14034f20a60882b0e098ae2e07cab55"},
 ]
 celery = [
     {file = "celery-4.4.7-py2.py3-none-any.whl", hash = "sha256:a92e1d56e650781fb747032a3997d16236d037c8199eacd5217d1a72893bca45"},
@@ -1610,8 +1610,8 @@ django-cors-headers = [
     {file = "django_cors_headers-3.4.0-py3-none-any.whl", hash = "sha256:5240062ef0b16668ce8a5f43324c388d65f5439e1a30e22c38684d5ddaff0d15"},
 ]
 django-csp = [
-    {file = "django_csp-3.6-py2.py3-none-any.whl", hash = "sha256:d9ee5a8c6442aa54854e8de627c2826786208ed38fb4ea8ced08c42332673eb1"},
-    {file = "django_csp-3.6.tar.gz", hash = "sha256:0a38aa9618c675cbf5f5e517e20d5846a3e100ef7b307e32e7fb18c58aa47723"},
+    {file = "django_csp-3.7-py2.py3-none-any.whl", hash = "sha256:01443a07723f9a479d498bd7bb63571aaa771e690f64bde515db6cdb76e8041a"},
+    {file = "django_csp-3.7.tar.gz", hash = "sha256:01eda02ad3f10261c74131cdc0b5a6a62b7c7ad4fd017fbefb7a14776e0a9727"},
 ]
 django-debug-toolbar = [
     {file = "django-debug-toolbar-2.2.tar.gz", hash = "sha256:eabbefe89881bbe4ca7c980ff102e3c35c8e8ad6eb725041f538988f2f39a943"},