Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sentry support on openedx #1

Merged
merged 7 commits into from
Jul 11, 2024
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
5 changes: 2 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ name: Run tests

on:
pull_request:
branches: [master]

jobs:
tests:
Expand All @@ -12,10 +11,10 @@ jobs:
python-version: ['3.8', '3.12']
steps:
- uses: actions/checkout@v3
- name: Set up Python {{ '${{ matrix.python-version }}' }}
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: {{ '${{ matrix.python-version }}' }}
python-version: ${{ matrix.python-version }}
- name: Upgrade pip
run: python -m pip install --upgrade pip
- name: Install dependencies
Expand Down
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Celery plugin for [Tutor](https://docs.tutor.edly.io)

A tutor plugin to integration Open edX with Sentry.

## Installation

```shell
pip install git+https://github.com/eduNEXT/tutor-contrib-sentry
```

## Usage

```shell
tutor plugins enable sentry
```

## Configuration

This plugin supports the following settings:

- `SENTRY_DSN`: The sentry DSN used for ingestion.
- `SENTRY_IGNORED_ERRORS`: A list of rules with exceptions types to ignore, optionally
you can ignore only specific exceptions that matches a list of regex.

```yaml
SENTRY_IGNORED_ERRORS:
# Ignore all AuthFailedError exceptions
- exc_class: AuthFailedError
# Ignore all exceptions that match a regex
- exc_text:
- .*Email or password is incorrect
# Ignore all exceptions of type AuthFailedError that matches: .*Email or password is incorrect
- exc_class: AuthFailedError
exc_text:
- .*Email or password is incorrect
```

- `SENTRY_ENVIRONMENT`: The sentry environment. Defaults to `production`.
- `SENTRY_EXTRA_ARGS`: A dictionary with extra arguments for the sentry SDK. e.g:

```yaml
SENTRY_EXTRA_ARGS:
traces_sample_rate: 1.0
profiles_sample_rate: 0.0
```

### Recommendations

On production we recommend adjusting both `traces_sample_rate` and `profiles_sample_rate` as those
can impact performance. See the [sentry configuration options](https://docs.sentry.io/platforms/python/configuration/options/) for more information.


### License

This software is licensed under the terms of the AGPLv3.
23 changes: 0 additions & 23 deletions README.rst

This file was deleted.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


def load_readme():
with io.open(os.path.join(HERE, "README.rst"), "rt", encoding="utf8") as f:
with io.open(os.path.join(HERE, "README.md"), "rt", encoding="utf8") as f:
return f.read()


Expand Down
68 changes: 68 additions & 0 deletions tutorsentry/patches/openedx-common-settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import re
import logging

logger = logging.getLogger(__file__)

SENTRY_IGNORED_ERRORS = {{SENTRY_IGNORED_ERRORS}}

def validate_exc(method, value, exc_value, exc_class_name):
if method == 'exc_class':
# exc_class_name = value
return exc_class_name == value

elif method == 'exc_text':
exc_text_expr = value
for expr in exc_text_expr:
if re.search(expr, exc_value):
return True

return False


def should_ignore_by_rule(rule, exc_value, exc_class_name):
"""
Validates if a given ignored exception rule matches the current exception
"""
for method, value in rule.items():
result = validate_exc(method, value, exc_value, exc_class_name)
if not result:
return False
return True

def exception_filter_hook(event, hint):
"""
Calls the proper method to verify which exceptions are ignored
for sentry
"""
exc_text = ''
exc_value = None

if 'log_record' in hint:
exc_text = hint['log_record'].message
if 'exc_info' in hint:
_exc_type, exc_value, _tb = hint['exc_info']
exc_class_name = _exc_type.__name__
exc_text += str(exc_value)

for rule in SENTRY_IGNORED_ERRORS:
ignore_event = should_ignore_by_rule(rule, exc_text, exc_class_name)
if ignore_event:
return None

return event

try:
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

sentry_sdk.init(
dsn="{{SENTRY_DSN}}",
integrations=[
DjangoIntegration(),
],
before_send=exception_filter_hook,
send_default_pii=True,
**{{SENTRY_EXTRA_ARGS}},
)
except ImportError:
logger.error("Sentry SDK is not installed.")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
RUN --mount=type=cache,target=/openedx/.cache/pip,sharing=shared \
pip install "sentry-sdk==2.8.0"
3 changes: 3 additions & 0 deletions tutorsentry/patches/uwsgi-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ignore-sigpipe
ignore-write-errors
disable-write-exception
9 changes: 9 additions & 0 deletions tutorsentry/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
# Each new setting is a pair: (setting_name, default_value).
# Prefix your setting names with 'SENTRY_'.
("SENTRY_VERSION", __version__),
("SENTRY_DSN", ""),
# The setting SENTRY_IGNORED_ERRORS is a list of rules that defines which exceptions to ignore.
# An example below:
# SENTRY_IGNORED_ERRORS = ['AuthFailedError']
# Every rule support only 2 keys for now:
("SENTRY_IGNORED_ERRORS", []),
("SENTRY_ENVIRONMENT", "production"),
# Extra initialization options for sentry
("SENTRY_EXTRA_ARGS", {"traces_sample_rate": 0.0, "profiles_sample_rate": 0.0}),
]
)

Expand Down
Loading