Skip to content
Merged
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
11 changes: 10 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ Error Tracker

**Full featured error tracking module for Python apps supports Flask and Django**

.. image:: https://img.shields.io/pypi/v/error-tracker.svg?color=dark-green
:target: https://pypi.org/project/error-tracker

.. image:: https://img.shields.io/pypi/pyversions/error-tracker.svg?color=dark-green
:target: https://pypi.org/project/error-tracker

.. image:: https://img.shields.io/github/license/sonus21/error-tracker.svg?color=dark-green
:target: https://github.com/sonus21/error-tracker/blob/master/LICENSE.txt

.. image:: https://travis-ci.org/sonus21/error-tracker.svg?branch=master
:target: https://travis-ci.org/sonus21/error-tracker

.. image:: https://coveralls.io/repos/github/sonus21/error-tracker/badge.svg
.. image:: https://coveralls.io/repos/github/sonus21/error-tracker/badge.svg?color=dark-green
:target: https://coveralls.io/github/sonus21/error-tracker

Introduction
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ We need to update settings.py file as
.. [1] This should be added at the end so that it can process exception 1st in the middleware call stack.

.. note::
Exception listing page is only enable for admin by default.
Exception listing page is only enable for super users by default.
You can enable for others by providing a custom implementation of ViewPermissionMixin.
This class must return True/False based on the current request, False means not authorized, True means authorized.

Expand All @@ -155,7 +155,7 @@ We need to update settings.py file as
APP_ERROR_RECIPIENT_EMAIL = ('example@example.com',)
APP_ERROR_SUBJECT_PREFIX = "Server Error"
APP_ERROR_EMAIL_SENDER = 'user@example.com'
# optional setting otherwise it's enabled for admin only
# optional setting otherwise it's enabled for super users only
APP_ERROR_VIEW_PERMISSION = 'permission.ErrorViewPermission'

INSTALLED_APPS = [
Expand Down
2 changes: 1 addition & 1 deletion error_tracker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# :license: BSD-3-Clause
#

__version__ = '1.1.3'
__version__ = '1.1.5'
__author__ = 'Sonu Kumar'
__email__ = 'sonunitw12@gmail.com'

Expand Down
56 changes: 25 additions & 31 deletions error_tracker/django/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
from django.http import RawPostDataException

from error_tracker.libs.mixins import ContextBuilderMixin, NotificationMixin, ViewPermissionMixin
from error_tracker.libs.utils import get_context_dict
from django.core.mail import send_mail


# noinspection PyMethodMayBeStatic
class DefaultDjangoContextBuilder(ContextBuilderMixin):
"""
Default request builder, this records, form data, header and URL parameters and mask them if necessary
"""

def _get_form_data(self, request):
@staticmethod
def _get_form_data(request):
form = {}
if request is None:
return form
post = request.POST
if post is None or len(post) == 0:
body = None
Expand All @@ -46,37 +49,28 @@ def _get_form_data(self, request):
form = post.dict()
return form

def _get_headers(self, request):
try:
headers = request.headers.dict()
except AttributeError:
regex = re.compile('^HTTP_')
headers = dict((regex.sub('', header), value) for (header, value)
in request.META.items() if header.startswith('HTTP_'))
return headers
@staticmethod
def _get_headers(request):
if request is not None:
try:
headers = request.headers.dict()
except AttributeError:
regex = re.compile('^HTTP_')
headers = dict((regex.sub('', header), value) for (header, value)
in request.META.items() if header.startswith('HTTP_'))
return headers

def get_context(self, request, masking=None, additional_context=None):
request_data = dict()
if additional_context is not None and len(additional_context) != 0:
request_data['context'] = additional_context
@staticmethod
def _get_args(request):
if request is not None:
form = self._get_form_data(request)
headers = self._get_headers(request)
if masking:
for key in form:
masked, value = masking(key)
if masked:
form[key] = value
for key in headers:
masked, value = masking(key)
if masked:
headers[key] = value
request_data.update({
'headers': headers,
'args': request.GET.dict(),
'form': form,
})
return str(request_data)
return request.GET.dict()

def get_context(self, request, masking=None, additional_context=None):
return str(get_context_dict(headers=self._get_headers(request),
form=self._get_form_data(request),
args=self._get_args(request),
context=additional_context,
masking=masking))


class DjangoNotification(NotificationMixin):
Expand Down
26 changes: 26 additions & 0 deletions error_tracker/libs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,29 @@ def get_class_instance(module_path, mixin, default, message_prefix, *args):
message = "Default " + message_prefix + " module will be used"
warnings.warn(message)
return default(*args)


def get_context_dict(headers=None, context=None, form=None, args=None, masking=None):
request_data = dict()
form = form or {}
headers = headers or {}
args = args or {}
context = context or {}
if len(context) != 0:
request_data['context'] = context
if masking:
for key in form:
masked, value = masking(key)
if masked:
form[key] = value
for key in headers:
masked, value = masking(key)
if masked:
headers[key] = value
if len(headers) != 0:
request_data['headers'] = headers
if len(args) != 0:
request_data['args'] = args
if len(form) != 0:
request_data['form'] = form
return request_data
10 changes: 5 additions & 5 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Flask==1.1.1
Flask-Mail==0.9.1
Flask-SQLAlchemy==2.4.1
pyquery==1.4.1
Django==1.11.26
Flask
Flask-Mail
Flask-SQLAlchemy
pyquery
Django
six
coveralls
djangorestframework
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
six
Flask==1.1.1
Flask-SQLAlchemy==2.4.1
Django==1.11.26
Flask
Flask-SQLAlchemy
Django
djangorestframework