From 250bb38d7cca06d40c8af7b74494705f5b23b7c0 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 24 Feb 2015 17:40:01 +0100 Subject: [PATCH] Crash report with Sentry --- gns3server/crash_report.py | 53 ++++++++++++++++++++++ gns3server/handlers/api/version_handler.py | 3 +- gns3server/main.py | 3 +- gns3server/web/route.py | 4 ++ requirements.txt | 1 + setup.py | 3 +- 6 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 gns3server/crash_report.py diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py new file mode 100644 index 00000000..c8afca1b --- /dev/null +++ b/gns3server/crash_report.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2014 GNS3 Technologies Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import raven +import json + +from .version import __version__ +from .config import Config + +import logging +log = logging.getLogger(__name__) + + +class CrashReport: + + """ + Report crash to a third party service + """ + + DSN = "aiohttp+https://50af75d8641d4ea7a4ea6b38c7df6cf9:41d54936f8f14e558066262e2ec8bbeb@app.getsentry.com/38482" + _instance = None + + def capture_exception(self, request): + server_config = Config.instance().get_section_config("Server") + if server_config.getboolean("report_errors"): + if self._client is None: + self._client = raven.Client(CrashReport.DSN, release=__version__) + self._client.http_context({ + "method": request.method, + "url": request.path, + "data": request.json, + }) + self._client.captureException() + + @classmethod + def instance(cls): + if cls._instance is None: + cls._instance = CrashReport() + return cls._instance diff --git a/gns3server/handlers/api/version_handler.py b/gns3server/handlers/api/version_handler.py index a935e3ca..000e932a 100644 --- a/gns3server/handlers/api/version_handler.py +++ b/gns3server/handlers/api/version_handler.py @@ -43,6 +43,5 @@ class VersionHandler: }) def check_version(request, response): if request.json["version"] != __version__: - raise HTTPConflict(text="Client version {} differs with server version {}".format(request.json["version"], - __version__)) + raise HTTPConflict(text="Client version {} differs with server version {}".format(request.json["version"], __version__)) response.json({"version": __version__}) diff --git a/gns3server/main.py b/gns3server/main.py index 889078d2..056d2b62 100644 --- a/gns3server/main.py +++ b/gns3server/main.py @@ -28,7 +28,7 @@ from gns3server.web.logger import init_logger from gns3server.version import __version__ from gns3server.config import Config from gns3server.modules.project import Project - +from gns3server.crash_report import CrashReport import logging log = logging.getLogger(__name__) @@ -168,6 +168,7 @@ def main(): Project.clean_project_directory() + CrashReport.instance() host = server_config["host"] port = int(server_config["port"]) server = Server(host, port) diff --git a/gns3server/web/route.py b/gns3server/web/route.py index a26a8f8b..13344bf9 100644 --- a/gns3server/web/route.py +++ b/gns3server/web/route.py @@ -27,6 +27,7 @@ log = logging.getLogger(__name__) from ..modules.vm_error import VMError from .response import Response +from ..crash_report import CrashReport @asyncio.coroutine @@ -39,6 +40,8 @@ def parse_request(request, input_schema): request.json = json.loads(body.decode('utf-8')) except ValueError as e: raise aiohttp.web.HTTPBadRequest(text="Invalid JSON {}".format(e)) + else: + request.json = {} try: jsonschema.validate(request.json, input_schema) except jsonschema.ValidationError as e: @@ -135,6 +138,7 @@ class Route(object): log.error("Uncaught exception detected: {type}".format(type=type(e)), exc_info=1) response = Response(route=route) response.set_status(500) + CrashReport.instance().capture_exception(request) exc_type, exc_value, exc_tb = sys.exc_info() lines = traceback.format_exception(exc_type, exc_value, exc_tb) if api_version is not None: diff --git a/requirements.txt b/requirements.txt index cd8c3f8d..db4f67fd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ apache-libcloud==0.16.0 requests==2.5.0 aiohttp==0.14.4 Jinja2==2.7.3 +raven==5.2.0 diff --git a/setup.py b/setup.py index 238efc3d..4b716076 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,8 @@ dependencies = ["aiohttp==0.14.4", "jsonschema==2.4.0", "apache-libcloud==0.16.0", "requests==2.5.0", - "Jinja2==2.7.3"] + "Jinja2==2.7.3", + "raven==5.2.0"] if sys.version_info == (3, 3): dependencies.append("asyncio==3.4.2")