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

chore: set up Sentry #1259

Merged
merged 8 commits into from
Feb 15, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions appcontainer/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ eligibility-api==2023.01.1
opencensus-ext-azure==1.1.6
opencensus-ext-django==0.8.0
requests==2.28.2
sentry-sdk==1.15.0
six==1.16.0
59 changes: 59 additions & 0 deletions benefits/sentry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from benefits import VERSION
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
import shutil
import os
import subprocess


SENTRY_ENVIRONMENT = os.environ.get("SENTRY_ENVIRONMENT", "local")


def git_available():
return bool(shutil.which("git"))


# https://stackoverflow.com/a/21901260/358804
def get_git_revision_hash():
return subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii").strip()


def get_sha_path():
current_file = os.path.dirname(os.path.abspath(__file__))
return os.path.join(current_file, "..", "static", "sha.txt")


def get_release() -> str:
"""Returns the first available: the SHA from Git, the value from sha.txt, or the VERSION."""

if git_available():
return get_git_revision_hash()
else:
sha_path = get_sha_path()
if os.path.isfile(sha_path):
with open(sha_path) as f:
return f.read().strip()
else:
# one of the above *should* always be available, but including this just in case
return VERSION


def configure():
SENTRY_DSN = os.environ.get("SENTRY_DSN")
if SENTRY_DSN:
release = get_release()
print(f"Enabling Sentry for environment '{SENTRY_ENVIRONMENT}', release '{release}'...")

# https://docs.sentry.io/platforms/python/configuration/
sentry_sdk.init(
dsn=SENTRY_DSN,
integrations=[
DjangoIntegration(),
],
traces_sample_rate=1.0,
environment=SENTRY_ENVIRONMENT,
release=release,
in_app_include=["benefits"],
)
else:
print("SENTRY_DSN not set, so won't send events")
3 changes: 3 additions & 0 deletions benefits/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Django settings for benefits project.
"""
import os
from benefits import sentry
import benefits.logging


Expand Down Expand Up @@ -227,6 +228,8 @@ def _filter_empty(ls):
LOG_LEVEL = os.environ.get("DJANGO_LOG_LEVEL", "DEBUG" if DEBUG else "WARNING")
LOGGING = benefits.logging.get_config(LOG_LEVEL, enable_azure=ENABLE_AZURE_INSIGHTS)

sentry.configure()

# Analytics configuration

ANALYTICS_KEY = os.environ.get("ANALYTICS_KEY")
Expand Down
9 changes: 9 additions & 0 deletions benefits/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
path("oauth/", include("benefits.oauth.urls")),
]

if settings.DEBUG:
# based on
# https://docs.sentry.io/platforms/python/guides/django/#verify

def trigger_error(request):
raise RuntimeError("Test error")

urlpatterns.append(path("error/", trigger_error))

if settings.ADMIN:
from django.contrib import admin

Expand Down
18 changes: 18 additions & 0 deletions docs/configuration/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,21 @@ Enables [log collection](../../deployment/troubleshooting/#logs). Set the value
[app-service-config]: https://docs.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal
[benefits-secrets]: https://github.com/cal-itp/benefits-secrets
[getting-started_create-env]: ../getting-started/README.md#create-an-environment-file

## Sentry

### `SENTRY_DSN`

!!! tldr "Sentry docs"

[Data Source Name (DSN)](https://docs.sentry.io/product/sentry-basics/dsn-explainer/)

Enables [sending events to Sentry](../../deployment/troubleshooting/#error-monitoring).

### `SENTRY_ENVIRONMENT`

!!! tldr "Sentry docs"

[`environment` config value](https://docs.sentry.io/platforms/python/configuration/options/#environment)

Segments errors by which deployment they occur in. This defaults to `local`, and can be set to match one of the [environment names](../../deployment/infrastructure/#environments).
8 changes: 8 additions & 0 deletions docs/deployment/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ az webapp log tail --resource-group RG-CDT-PUB-VIP-CALITP-P-001 --name AS-CDT-PU

<https://as-cdt-pub-vip-calitp-p-001-dev.scm.azurewebsites.net/api/logs/docker>

### Sentry

Cal-ITP's Sentry instance collects both [errors ("Issues")](https://sentry.calitp.org/organizations/sentry/issues/?project=3) and app [performance info](https://sentry.calitp.org/organizations/sentry/performance/?project=3).

[Alerts are sent to #benefits-notify in Slack.](https://sentry.calitp.org/organizations/sentry/alerts/rules/benefits/9/details/) [Others can be configured.](https://sentry.calitp.org/organizations/sentry/alerts/rules/)

You can troubleshoot Sentry itself by [turning on debug mode](../../configuration/environment-variables/#django_debug) and visiting `/error/`.

## Specific issues

This section serves as the [runbook](https://www.pagerduty.com/resources/learn/what-is-a-runbook/) for Benefits.
Expand Down