mirror of https://github.com/zulip/zulip.git
webhooks/sentry: Add back support for the legacy integrations.
When the integration was originally rewritten, support for the deprecated webhook payloads was removed. We later noticed that some people using Zulip were still using versions of Sentry that required the older integration code. Thus this commit adds back the older integration code and whenever the Sentry webhook payload does not have a "data" field (which must be present in all modern payloads as per the documentation at https://docs.sentry.io/workflow/integrations/integration-platform/webhooks) we will use the older Sentry integration code. Signed-off-by: Hemanth V. Alluri <hdrive1999@gmail.com>
This commit is contained in:
parent
8411f7f884
commit
fb757e91c1
|
@ -0,0 +1,375 @@
|
|||
{
|
||||
"project": "zulip",
|
||||
"project_name": "zulip",
|
||||
"culprit": "raven.scripts.runner in main",
|
||||
"level": "error",
|
||||
"url": "https://sentry.io/zulip/zulip/issues/156699934/",
|
||||
"logger": null,
|
||||
"message": "This is an example python exception",
|
||||
"id": "156699934",
|
||||
"event": {
|
||||
"received": 1473185565.0,
|
||||
"sentry.interfaces.User": {
|
||||
"username": "getsentry",
|
||||
"id": "1671",
|
||||
"email": "foo@example.com"
|
||||
},
|
||||
"sentry.interfaces.Message": {
|
||||
"message": "This is an example python exception"
|
||||
},
|
||||
"errors": [
|
||||
],
|
||||
"extra": {
|
||||
"emptyList": [
|
||||
],
|
||||
"unauthorized": false,
|
||||
"emptyMap": {
|
||||
},
|
||||
"url": "http://example.org/foo/bar/",
|
||||
"results": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5
|
||||
],
|
||||
"length": 10837790,
|
||||
"session": {
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"fingerprint": [
|
||||
"{{ default }}"
|
||||
],
|
||||
"modules": {
|
||||
"my.package": "1.0.0"
|
||||
},
|
||||
"sentry.interfaces.Http": {
|
||||
"cookies": [
|
||||
[
|
||||
"foo",
|
||||
"bar"
|
||||
],
|
||||
[
|
||||
"biz",
|
||||
"baz"
|
||||
]
|
||||
],
|
||||
"url": "http://example.com/foo",
|
||||
"headers": [
|
||||
[
|
||||
"Content-Type",
|
||||
"application/json"
|
||||
],
|
||||
[
|
||||
"Referer",
|
||||
"http://example.com"
|
||||
],
|
||||
[
|
||||
"User-Agent",
|
||||
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"ENV": "prod"
|
||||
},
|
||||
"query_string": "foo=bar",
|
||||
"data": "{\"hello\": \"world\"}",
|
||||
"method": "GET"
|
||||
},
|
||||
"sentry.interfaces.Template": {
|
||||
"abs_path": "/srv/example/templates/debug_toolbar/base.html",
|
||||
"pre_context": [
|
||||
"{% endif %}\n",
|
||||
"<script src=\"{% static 'debug_toolbar/js/toolbar.js' %}\"></script>\n",
|
||||
"<div id=\"djDebug\" hidden=\"hidden\" dir=\"ltr\"\n"
|
||||
],
|
||||
"post_context": [
|
||||
" {{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }}>\n",
|
||||
"\t<div hidden=\"hidden\" id=\"djDebugToolbar\">\n",
|
||||
"\t\t<ul id=\"djDebugPanelList\">\n"
|
||||
],
|
||||
"filename": "debug_toolbar/base.html",
|
||||
"lineno": 14,
|
||||
"context_line": " data-store-id=\"{{ toolbar.store_id }}\" data-render-panel-url=\"{% url 'djdt:render_panel' %}\"\n"
|
||||
},
|
||||
"version": "5",
|
||||
"_ref_version": 2,
|
||||
"_ref": 77799,
|
||||
"type": "default",
|
||||
"sentry.interfaces.Stacktrace": {
|
||||
"frames": [
|
||||
{
|
||||
"function": "build_msg",
|
||||
"abs_path": "/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py",
|
||||
"pre_context": [
|
||||
" frames = stack",
|
||||
"",
|
||||
" data.update({",
|
||||
" 'sentry.interfaces.Stacktrace': {",
|
||||
" 'frames': get_stack_info(frames,"
|
||||
],
|
||||
"vars": {
|
||||
"'frames'": "<generator object iter_stack_frames at 0x107bcc3c0>",
|
||||
"'culprit'": null,
|
||||
"'event_type'": "'raven.events.Message'",
|
||||
"'handler'": "<raven.events.Message object at 0x107bd0890>",
|
||||
"'date'": "datetime.datetime(2013, 8, 13, 3, 8, 24, 880386)",
|
||||
"'extra'": {
|
||||
"'loadavg'": [
|
||||
0.37255859375,
|
||||
0.5341796875,
|
||||
0.62939453125
|
||||
],
|
||||
"'user'": "'dcramer'",
|
||||
"'go_deeper'": [
|
||||
[
|
||||
{
|
||||
"'bar'": "'\\'\\\\\\'[\"\\\\\\\\\\\\\\'baz\\\\\\\\\\\\\\'\"]\\\\\\'\\''",
|
||||
"'foo'": "'\\'\\\\\\'\"\\\\\\\\\\\\\\'bar\\\\\\\\\\\\\\'\"\\\\\\'\\''"
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"'v'": {
|
||||
"'message'": "u'This is a test message generated using ``raven test``'",
|
||||
"'params'": [
|
||||
]
|
||||
},
|
||||
"'stack'": true,
|
||||
"'event_id'": "'54a322436e1b47b88e239b78998ae742'",
|
||||
"'tags'": null,
|
||||
"'time_spent'": null,
|
||||
"'self'": "<raven.base.Client object at 0x107bb8210>",
|
||||
"'data'": {
|
||||
"'sentry.interfaces.Message'": {
|
||||
"'message'": "u'This is a test message generated using ``raven test``'",
|
||||
"'params'": [
|
||||
]
|
||||
},
|
||||
"'message'": "u'This is a test message generated using ``raven test``'"
|
||||
},
|
||||
"'result'": {
|
||||
"'sentry.interfaces.Message'": {
|
||||
"'message'": "u'This is a test message generated using ``raven test``'",
|
||||
"'params'": [
|
||||
]
|
||||
},
|
||||
"'message'": "u'This is a test message generated using ``raven test``'"
|
||||
},
|
||||
"'kwargs'": {
|
||||
"'message'": "'This is a test message generated using ``raven test``'",
|
||||
"'level'": 20
|
||||
},
|
||||
"'k'": "'sentry.interfaces.Message'",
|
||||
"'public_key'": null
|
||||
},
|
||||
"module": "raven.base",
|
||||
"filename": "raven/base.py",
|
||||
"post_context": [
|
||||
" },",
|
||||
" })",
|
||||
"",
|
||||
" if 'sentry.interfaces.Stacktrace' in data:",
|
||||
" if self.include_paths:"
|
||||
],
|
||||
"in_app": false,
|
||||
"context_line": " transformer=self.transform)",
|
||||
"lineno": 303
|
||||
},
|
||||
{
|
||||
"function": "capture",
|
||||
"abs_path": "/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py",
|
||||
"pre_context": [
|
||||
" if not self.is_enabled():",
|
||||
" return",
|
||||
"",
|
||||
" data = self.build_msg(",
|
||||
" event_type, data, date, time_spent, extra, stack, tags=tags,"
|
||||
],
|
||||
"vars": {
|
||||
"'event_type'": "'raven.events.Message'",
|
||||
"'date'": null,
|
||||
"'extra'": {
|
||||
"'loadavg'": [
|
||||
0.37255859375,
|
||||
0.5341796875,
|
||||
0.62939453125
|
||||
],
|
||||
"'user'": "'dcramer'",
|
||||
"'go_deeper'": [
|
||||
[
|
||||
{
|
||||
"'bar'": "'\\'\\\\\\'[\"\\\\\\\\\\\\\\'baz\\\\\\\\\\\\\\'\"]\\\\\\'\\''",
|
||||
"'foo'": "'\\'\\\\\\'\"\\\\\\\\\\\\\\'bar\\\\\\\\\\\\\\'\"\\\\\\'\\''"
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"'stack'": true,
|
||||
"'tags'": null,
|
||||
"'time_spent'": null,
|
||||
"'self'": "<raven.base.Client object at 0x107bb8210>",
|
||||
"'data'": null,
|
||||
"'kwargs'": {
|
||||
"'message'": "'This is a test message generated using ``raven test``'",
|
||||
"'level'": 20
|
||||
}
|
||||
},
|
||||
"module": "raven.base",
|
||||
"filename": "raven/base.py",
|
||||
"post_context": [
|
||||
"",
|
||||
" self.send(**data)",
|
||||
"",
|
||||
" return (data.get('event_id'),)",
|
||||
""
|
||||
],
|
||||
"in_app": false,
|
||||
"context_line": " **kwargs)",
|
||||
"lineno": 459
|
||||
},
|
||||
{
|
||||
"function": "captureMessage",
|
||||
"abs_path": "/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/base.py",
|
||||
"pre_context": [
|
||||
" \"\"\"",
|
||||
" Creates an event from ``message``.",
|
||||
"",
|
||||
" >>> client.captureMessage('My event just happened!')",
|
||||
" \"\"\""
|
||||
],
|
||||
"vars": {
|
||||
"'message'": "'This is a test message generated using ``raven test``'",
|
||||
"'kwargs'": {
|
||||
"'extra'": {
|
||||
"'loadavg'": [
|
||||
0.37255859375,
|
||||
0.5341796875,
|
||||
0.62939453125
|
||||
],
|
||||
"'user'": "'dcramer'",
|
||||
"'go_deeper'": [
|
||||
[
|
||||
"'\\'\\\\\\'{\"\\\\\\\\\\\\\\'bar\\\\\\\\\\\\\\'\": [\"\\\\\\\\\\\\\\'baz\\\\\\\\\\\\\\'\"], \"\\\\\\\\\\\\\\'foo\\\\\\\\\\\\\\'\": \"\\\\\\\\\\\\\\'bar\\\\\\\\\\\\\\'\"}\\\\\\'\\''"
|
||||
]
|
||||
]
|
||||
},
|
||||
"'tags'": null,
|
||||
"'data'": null,
|
||||
"'level'": 20,
|
||||
"'stack'": true
|
||||
},
|
||||
"'self'": "<raven.base.Client object at 0x107bb8210>"
|
||||
},
|
||||
"module": "raven.base",
|
||||
"filename": "raven/base.py",
|
||||
"post_context": [
|
||||
"",
|
||||
" def captureException(self, exc_info=None, **kwargs):",
|
||||
" \"\"\"",
|
||||
" Creates an event from an exception.",
|
||||
""
|
||||
],
|
||||
"in_app": false,
|
||||
"context_line": " return self.capture('raven.events.Message', message=message, **kwargs)",
|
||||
"lineno": 577
|
||||
},
|
||||
{
|
||||
"function": "send_test_message",
|
||||
"abs_path": "/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/scripts/runner.py",
|
||||
"pre_context": [
|
||||
" level=logging.INFO,",
|
||||
" stack=True,",
|
||||
" tags=options.get('tags', {}),",
|
||||
" extra={",
|
||||
" 'user': get_uid(),"
|
||||
],
|
||||
"vars": {
|
||||
"'client'": "<raven.base.Client object at 0x107bb8210>",
|
||||
"'options'": {
|
||||
"'tags'": null,
|
||||
"'data'": null
|
||||
},
|
||||
"'data'": null,
|
||||
"'k'": "'secret_key'"
|
||||
},
|
||||
"module": "raven.scripts.runner",
|
||||
"filename": "raven/scripts/runner.py",
|
||||
"post_context": [
|
||||
" },",
|
||||
" ))",
|
||||
"",
|
||||
" if client.state.did_fail():",
|
||||
" print('error!')"
|
||||
],
|
||||
"in_app": false,
|
||||
"context_line": " 'loadavg': get_loadavg(),",
|
||||
"lineno": 77
|
||||
},
|
||||
{
|
||||
"function": "main",
|
||||
"abs_path": "/home/ubuntu/.virtualenvs/getsentry/src/raven/raven/scripts/runner.py",
|
||||
"pre_context": [
|
||||
" print(\"Using DSN configuration:\")",
|
||||
" print(\" \", dsn)",
|
||||
" print()",
|
||||
"",
|
||||
" client = Client(dsn, include_paths=['raven'])"
|
||||
],
|
||||
"vars": {
|
||||
"'root'": "<logging.Logger object at 0x107ba5b10>",
|
||||
"'parser'": "<argparse.ArgumentParser instance at 0x107ba3368>",
|
||||
"'dsn'": "'https://ebc35f33e151401f9deac549978bda11:f3403f81e12e4c24942d505f086b2cad@sentry.io/1'",
|
||||
"'opts'": "<Values at 0x107ba3b00: {'data': None, 'tags': None}>",
|
||||
"'client'": "<raven.base.Client object at 0x107bb8210>",
|
||||
"'args'": [
|
||||
"'test'",
|
||||
"'https://ebc35f33e151401f9deac549978bda11:f3403f81e12e4c24942d505f086b2cad@sentry.io/1'"
|
||||
]
|
||||
},
|
||||
"module": "raven.scripts.runner",
|
||||
"filename": "raven/scripts/runner.py",
|
||||
"lineno": 112,
|
||||
"in_app": false,
|
||||
"context_line": " send_test_message(client, opts.__dict__)"
|
||||
}
|
||||
],
|
||||
"has_system_frames": false,
|
||||
"frames_omitted": null
|
||||
},
|
||||
"tags": [
|
||||
[
|
||||
"browser",
|
||||
"Chrome 28.0"
|
||||
],
|
||||
[
|
||||
"device",
|
||||
"Other"
|
||||
],
|
||||
[
|
||||
"environment",
|
||||
"production"
|
||||
],
|
||||
[
|
||||
"level",
|
||||
"error"
|
||||
],
|
||||
[
|
||||
"os",
|
||||
"Windows 8"
|
||||
],
|
||||
[
|
||||
"sentry:user",
|
||||
"id:1671"
|
||||
],
|
||||
[
|
||||
"url",
|
||||
"http://example.com/foo"
|
||||
]
|
||||
],
|
||||
"metadata": {
|
||||
"title": "This is an example python exception"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -156,3 +156,13 @@ Traceback:
|
|||
expected_topic = "Exception: program has entered an invalid state."
|
||||
expected_message = """\nIssue **Exception: program has entered an invalid state.** was marked as resolved by **Hemanth V. Alluri**."""
|
||||
self.send_and_test_stream_message('issue_resolved', expected_topic, expected_message)
|
||||
|
||||
def test_deprecated_exception_message(self) -> None:
|
||||
expected_topic = "zulip"
|
||||
expected_message = """
|
||||
New [issue](https://sentry.io/zulip/zulip/issues/156699934/) (level: ERROR):
|
||||
|
||||
``` quote
|
||||
This is an example python exception
|
||||
```"""
|
||||
self.send_and_test_stream_message('deprecated_exception_message', expected_topic, expected_message)
|
||||
|
|
|
@ -9,6 +9,14 @@ from zerver.lib.webhooks.common import UnexpectedWebhookEventType, check_send_we
|
|||
from zerver.models import UserProfile
|
||||
|
||||
|
||||
DEPRECATED_EXCEPTION_MESSAGE_TEMPLATE = """
|
||||
New [issue]({url}) (level: {level}):
|
||||
|
||||
``` quote
|
||||
{message}
|
||||
```
|
||||
"""
|
||||
|
||||
MESSAGE_EVENT_TEMPLATE = """
|
||||
**New message event:** [{title}]({web_link})
|
||||
```quote
|
||||
|
@ -194,19 +202,32 @@ def handle_issue_payload(action: str, issue: Dict[str, Any], actor: Dict[str, An
|
|||
return (subject, body)
|
||||
|
||||
|
||||
def handle_deprecated_payload(payload: Dict[str, Any]) -> Tuple[str, str]:
|
||||
subject = "{}".format(payload.get('project_name'))
|
||||
body = DEPRECATED_EXCEPTION_MESSAGE_TEMPLATE.format(
|
||||
level=payload['level'].upper(),
|
||||
url=payload.get('url'),
|
||||
message=payload.get('message')
|
||||
)
|
||||
return (subject, body)
|
||||
|
||||
|
||||
@api_key_only_webhook_view('Sentry')
|
||||
@has_request_variables
|
||||
def api_sentry_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||
payload: Dict[str, Any] = REQ(argument_type="body")) -> HttpResponse:
|
||||
data = payload["data"]
|
||||
data = payload.get("data", None)
|
||||
|
||||
# We currently support two types of payloads: events and issues.
|
||||
if data:
|
||||
if "event" in data:
|
||||
subject, body = handle_event_payload(data["event"])
|
||||
elif "issue" in data:
|
||||
subject, body = handle_issue_payload(payload["action"], data["issue"], payload["actor"])
|
||||
else:
|
||||
raise UnexpectedWebhookEventType("Sentry", str((list(data.keys()))))
|
||||
else:
|
||||
subject, body = handle_deprecated_payload(payload)
|
||||
|
||||
check_send_webhook_message(request, user_profile, subject, body)
|
||||
return json_success()
|
||||
|
|
Loading…
Reference in New Issue