Skip to content

Commit

Permalink
chore: set up Sentry (#1259)
Browse files Browse the repository at this point in the history
  • Loading branch information
afeld committed Feb 15, 2023
2 parents 1f960fa + 80d02de commit e11c2ff
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
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.8
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

0 comments on commit e11c2ff

Please sign in to comment.