Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Py27 support #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ repos:
rev: 3.7.7
hooks:
- id: flake8
# Ignore missing 'typing' lib for Python 2.7
args:
- "--ignore=F821"
language_version: python3.7

- repo: https://github.com/asottile/seed-isort-config
Expand Down
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ install: pip install -U pip tox
matrix:
fast_finish: true
include:
- name: Python 3.5 tests
python: '3.5'
script: tox -e py35
- name: Python 2.7 tests
python: '2.7'
script: tox -e py27

- name: Python 3.6 tests
python: '3.6'
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# coding=utf-8
from setuptools import find_packages, setup


Expand All @@ -19,7 +20,7 @@
author="Pavel Dedík",
author_email="[email protected]",
packages=find_packages(),
python_requires=">=3.5",
python_requires=">=2.7",
install_requires=install_requires,
tests_require=tests_require,
include_package_data=True,
Expand All @@ -29,6 +30,7 @@
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
Expand Down
33 changes: 17 additions & 16 deletions structlog_sentry/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import logging
import sys
from typing import List, Optional, Tuple, Union

from sentry_sdk import capture_event
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.utils import event_from_exception


class SentryProcessor:
class SentryProcessor(object):
"""Sentry processor for structlog.

Uses Sentry SDK to capture events in Sentry.
"""

def __init__(
self,
level: int = logging.WARNING,
active: bool = True,
as_extra: bool = True,
tag_keys: Union[List[str], str] = None,
) -> None:
self, level=logging.WARNING, active=True, as_extra=True, tag_keys=None
):
# type: (int, bool, bool, typing.Union[typing.List[str], str]) -> None
"""
:param level: events of this or higher levels will be reported to Sentry.
:param active: a flag to make this processor enabled/disabled.
Expand All @@ -34,7 +30,8 @@ def __init__(
self._as_extra = as_extra
self._original_event_dict = None

def _get_event_and_hint(self, event_dict: dict) -> Tuple[dict, Optional[str]]:
def _get_event_and_hint(self, event_dict):
# type: (dict) -> typing.Tuple[dict, typing.Optional[str]]
"""Create a sentry event and hint from structlog `event_dict` and sys.exc_info.

:param event_dict: structlog event_dict
Expand All @@ -61,15 +58,17 @@ def _get_event_and_hint(self, event_dict: dict) -> Tuple[dict, Optional[str]]:

return event, hint

def _log(self, event_dict: dict) -> str:
def _log(self, event_dict):
# type: (dict) -> str
"""Send an event to Sentry and return sentry event id.

:param event_dict: structlog event_dict
"""
event, hint = self._get_event_and_hint(event_dict)
return capture_event(event, hint=hint)

def __call__(self, logger, method, event_dict) -> dict:
def __call__(self, logger, method, event_dict):
# type: (typing.Any, str, dict) -> dict
"""A middleware to process structlog `event_dict` and send it to Sentry."""
self._original_event_dict = event_dict.copy()
sentry_skip = event_dict.pop("sentry_skip", False)
Expand All @@ -92,16 +91,18 @@ class SentryJsonProcessor(SentryProcessor):
Uses Sentry SDK to capture events in Sentry.
"""

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
def __init__(self, *args, **kwargs):
super(SentryJsonProcessor, self).__init__(*args, **kwargs)
self._is_logger_ignored = False

def __call__(self, logger, method, event_dict) -> dict:
def __call__(self, logger, method, event_dict):
# type: (typing.Any, str, dict) -> dict
if not self._is_logger_ignored:
self._ignore_logger(logger, event_dict)
return super().__call__(logger, method, event_dict)
return super(SentryJsonProcessor, self).__call__(logger, method, event_dict)

def _ignore_logger(self, logger, event_dict: dict) -> None:
def _ignore_logger(self, logger, event_dict):
# type: (typing.Any, dict) -> None
"""Tell Sentry to ignore logger.

This is temporary workaround to prevent duplication of a JSON event in Sentry.
Expand Down
1 change: 0 additions & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
coverage==4.5.3 # via pytest-cov
more-itertools==7.0.0 # via pytest
pluggy==0.9.0 # via pytest
py==1.8.0 # via pytest
pytest-cov==2.6.1
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
envlist =
lint
py{35,36,37}
py{27,35,36,37}

[testenv]
deps =
Expand Down