summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgor Yurtaev <yurtaev.egor@gmail.com>2014-12-23 17:27:20 +0600
committerEgor Yurtaev <yurtaev.egor@gmail.com>2014-12-25 12:56:50 +0600
commitab6cdeb09a23452d1b15c3de8229f1217d3a9e7f (patch)
tree5bb9df605bdf766d4314690f55c9c8385601c826
parent4172b33cb10f614d2b86d09d65184350bea080c7 (diff)
downloadomaha-server-ab6cdeb09a23452d1b15c3de8229f1217d3a9e7f.zip
omaha-server-ab6cdeb09a23452d1b15c3de8229f1217d3a9e7f.tar.gz
omaha-server-ab6cdeb09a23452d1b15c3de8229f1217d3a9e7f.tar.bz2
function crash.utils.send_stacktrace_sentry
-rw-r--r--README.md1
-rw-r--r--omaha_server/crash/tests/test_utils.py135
-rw-r--r--omaha_server/crash/utils.py46
-rw-r--r--omaha_server/omaha_server/settings_prod.py2
-rw-r--r--omaha_server/omaha_server/settings_test.py4
5 files changed, 186 insertions, 2 deletions
diff --git a/README.md b/README.md
index f986b29..2d72e74 100644
--- a/README.md
+++ b/README.md
@@ -204,6 +204,7 @@ app:
| AWS_SECRET_ACCESS_KEY | AWS Secret Key | |
| AWS_STORAGE_BUCKET_NAME | S3 storage bucket | |
| RAVEN_DNS | Sentry url | |
+| RAVEN_DSN_STACKTRACE | Sentry url | RAVEN_DNS |
| REDIS_HOST | Redis host | 127.0.0.1 |
| REDIS_PORT | Redis port | 6379 |
| REDIS_DB | Redis db | 1 |
diff --git a/omaha_server/crash/tests/test_utils.py b/omaha_server/crash/tests/test_utils.py
index defe9af..a56cf4e 100644
--- a/omaha_server/crash/tests/test_utils.py
+++ b/omaha_server/crash/tests/test_utils.py
@@ -20,9 +20,20 @@ the License.
import os
+from mock import patch
+
from django import test
+from django.core.files.uploadedfile import SimpleUploadedFile
+
+from crash.utils import (
+ get_stacktrace,
+ add_signature_to_frame,
+ parse_stacktrace,
+ get_signature,
+ send_stacktrace_sentry,
+)
-from crash.utils import get_stacktrace, add_signature_to_frame, parse_stacktrace, get_signature
+from crash.models import Crash
from test_stacktrace_to_json import stacktrace
@@ -88,3 +99,125 @@ class SignatureTest(test.TestCase):
def test_get_signature(self):
self.assertEqual(get_signature(parse_stacktrace(stacktrace)), 'crashedFunc()')
+
+
+class SendStackTraceTest(test.TestCase):
+ @patch('crash.utils.client')
+ def test_send_stacktrace_sentry(self, mock_client):
+ meta = dict(
+ lang='en',
+ version='1.0.0.1',
+ )
+ crash = Crash(
+ upload_file_minidump=SimpleUploadedFile('./dump.dat', False),
+ stacktrace=stacktrace,
+ stacktrace_json=parse_stacktrace(stacktrace),
+ app_id='{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}',
+ user_id='{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}',
+ meta=meta,
+ signature='signature',
+ )
+
+ send_stacktrace_sentry(crash)
+
+ extra = {
+ 'crashdump_url': crash.upload_file_minidump.url,
+ 'lang': 'en',
+ 'version': '1.0.0.1'}
+
+ data = {
+ 'sentry.interfaces.User': {
+ 'id': '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}'
+ },
+ 'sentry.interfaces.Exception': {
+ 'values': [
+ {'stacktrace': {
+ 'frames': [
+ {'function': 'crashedFunc()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'crashedFunc',
+ 'frame': 0,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 34,
+ 'signature': 'crashedFunc()'},
+ {'function': 'deeperFunc()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'deeperFunc',
+ 'frame': 1,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 39,
+ 'signature': 'deeperFunc()'},
+ {'function': 'deepFunc()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'deepFunc',
+ 'frame': 2,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 44,
+ 'signature': 'deepFunc()'},
+ {'function': 'anotherFunc()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'anotherFunc',
+ 'frame': 3,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 49,
+ 'signature': 'anotherFunc()'},
+ {'function': 'someFunc()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'someFunc',
+ 'frame': 4,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 54,
+ 'signature': 'someFunc()'}, {
+ 'function': 'func()',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'func',
+ 'frame': 5,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 59,
+ 'signature': 'func()'},
+ {'function': 'wmain',
+ 'abs_path': 'c:\\work\x08reakpadtestapp\x08reakpadtestapp\x08reakpadtestapp.cpp',
+ 'short_signature': 'wmain',
+ 'frame': 6,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 84,
+ 'signature': 'wmain'}, {
+ 'function': '__tmainCRTStartup',
+ 'abs_path': 'f:\\dd\x0bctools\\crt_bld\\self_x86\\crt\\src\\crtexe.c',
+ 'short_signature': '__tmainCRTStartup',
+ 'frame': 7,
+ 'filename': 'BreakpadTestApp.exe',
+ 'lineno': 579,
+ 'signature': '__tmainCRTStartup'},
+ {'frame': 8,
+ 'module_offset': '0x13676',
+ 'signature': 'kernel32.dll@0x13676',
+ 'short_signature': 'kernel32.dll@0x13676',
+ 'filename': 'kernel32.dll'},
+ {'frame': 9,
+ 'module_offset': '0x39d41',
+ 'signature': 'ntdll.dll@0x39d41',
+ 'short_signature': 'ntdll.dll@0x39d41',
+ 'filename': 'ntdll.dll'}],
+ 'total_frames': 11, 'threads_index': 0},
+ 'type': 'EXCEPTION_ACCESS_VIOLATION_WRITE',
+ 'value': '0x0'}
+ ]
+ }
+ }
+
+ tags = {
+ 'cpu_arch': 'x86',
+ 'cpu_count': 4,
+ 'app_id': '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}',
+ 'cpu_info': 'GenuineIntel family 6 model 42 stepping 7',
+ 'os': 'Windows NT',
+ 'os_ver': '6.1.7600'
+ }
+
+ mock_client.capture.assert_called_once_with(
+ 'raven.events.Message', message='signature',
+ extra=extra,
+ data=data,
+ tags=tags,
+ )
diff --git a/omaha_server/crash/utils.py b/omaha_server/crash/utils.py
index 6da9e1f..77e67b7 100644
--- a/omaha_server/crash/utils.py
+++ b/omaha_server/crash/utils.py
@@ -21,12 +21,18 @@ the License.
import os
import re
+from django.conf import settings
+
from clom import clom
+from raven import Client
from settings import MINIDUMP_STACKWALK_PATH, SYMBOLS_PATH
from stacktrace_to_json import pipe_dump_to_json_dump
+client = Client(getattr(settings, 'RAVEN_DSN_STACKTRACE'))
+
+
class FileNotFoundError(Exception):
pass
@@ -75,3 +81,43 @@ def get_signature(stacktrace):
except KeyError, IndexError:
signature = 'EMPTY: no frame data available'
return signature
+
+
+def send_stacktrace_sentry(crash):
+ stacktrace = crash.stacktrace_json
+
+ exception = {
+ "values": [
+ {
+ "type": stacktrace.get('crash_info', {}).get('type', 'unknown exception'),
+ "value": stacktrace.get('crash_info', {}).get('crash_address', '0x0'),
+ "stacktrace": stacktrace['crashing_thread']
+ }
+ ]
+ }
+
+ data = {'sentry.interfaces.Exception': exception}
+
+ if crash.user_id:
+ data['sentry.interfaces.User'] = dict(id=crash.user_id)
+
+ extra = dict(
+ crashdump_url=crash.upload_file_minidump.url,
+ )
+
+ if crash.meta:
+ extra.update(crash.meta)
+
+ tags = {}
+ tags.update(stacktrace.get('system_info', {}))
+
+ if crash.app_id:
+ tags['app_id'] = crash.app_id
+
+ client.capture(
+ 'raven.events.Message',
+ message=crash.signature,
+ extra=extra,
+ tags=tags,
+ data=data
+ )
diff --git a/omaha_server/omaha_server/settings_prod.py b/omaha_server/omaha_server/settings_prod.py
index e3ba0e2..ff66fb0 100644
--- a/omaha_server/omaha_server/settings_prod.py
+++ b/omaha_server/omaha_server/settings_prod.py
@@ -28,6 +28,8 @@ RAVEN_CONFIG = {
'dsn': os.environ.get('RAVEN_DNS'),
}
+RAVEN_DSN_STACKTRACE = os.environ.get('RAVEN_DSN_STACKTRACE', RAVEN_CONFIG['dsn'])
+
INSTALLED_APPS = INSTALLED_APPS + (
'raven.contrib.django.raven_compat',
)
diff --git a/omaha_server/omaha_server/settings_test.py b/omaha_server/omaha_server/settings_test.py
index d9fe6d8..cba3356 100644
--- a/omaha_server/omaha_server/settings_test.py
+++ b/omaha_server/omaha_server/settings_test.py
@@ -55,4 +55,6 @@ CACHES['statistics'] = {
OMAHA_UID_KEY_PREFIX = 'test:uid'
CRASH_SYMBOLS_PATH = os.path.join(BASE_DIR, 'crash', 'tests', 'testdata', 'symbols')
-CRASH_S3_MOUNT_PATH = os.path.join(BASE_DIR, 'crash', 'tests', 'testdata') \ No newline at end of file
+CRASH_S3_MOUNT_PATH = os.path.join(BASE_DIR, 'crash', 'tests', 'testdata')
+
+RAVEN_DSN_STACKTRACE = 'http://c5dc6f5ab74b4ab8a567f545b00cb138:c57ee00766cf497da102b7a83d731840@127.0.0.1/1' \ No newline at end of file