|
5 | 5 |
|
6 | 6 | import environ |
7 | 7 | import sentry_sdk |
| 8 | +from corsheaders.defaults import default_headers |
8 | 9 | from csp.constants import SELF as CSP_SELF |
9 | 10 | from csp.constants import UNSAFE_INLINE as CSP_UNSAFE_INLINE |
10 | 11 | from django.core.exceptions import ImproperlyConfigured |
11 | 12 | from django.utils.translation import gettext_lazy as _ |
12 | 13 | from sentry_sdk.integrations.django import DjangoIntegration |
| 14 | +from sentry_sdk.types import SamplingContext |
13 | 15 |
|
14 | 16 | from palvelutarjotin import __version__ |
15 | 17 |
|
|
47 | 49 | MAIL_MAILGUN_DOMAIN=(str, ""), |
48 | 50 | MAIL_MAILGUN_API=(str, ""), |
49 | 51 | SENTRY_DSN=(str, ""), |
50 | | - SENTRY_ENVIRONMENT=(str, ""), |
| 52 | + SENTRY_ENVIRONMENT=(str, "local"), |
| 53 | + SENTRY_PROFILE_SESSION_SAMPLE_RATE=(float, None), |
| 54 | + SENTRY_RELEASE=(str, None), |
| 55 | + SENTRY_TRACES_SAMPLE_RATE=(float, None), |
| 56 | + SENTRY_TRACES_IGNORE_PATHS=(list, ["/healthz", "/readiness"]), |
51 | 57 | CORS_ALLOWED_ORIGINS=(list, []), |
52 | 58 | CORS_ALLOWED_ORIGIN_REGEXES=(list, []), |
53 | 59 | CORS_ALLOW_ALL_ORIGINS=(bool, False), |
|
163 | 169 |
|
164 | 170 | COMMIT_HASH = env("OPENSHIFT_BUILD_COMMIT") |
165 | 171 | VERSION = __version__ |
166 | | -sentry_sdk.init( |
167 | | - dsn=env.str("SENTRY_DSN"), |
168 | | - release=env.str("OPENSHIFT_BUILD_COMMIT", VERSION), |
169 | | - environment=env("SENTRY_ENVIRONMENT"), |
170 | | - integrations=[DjangoIntegration()], |
171 | | -) |
| 172 | + |
| 173 | +SENTRY_TRACES_SAMPLE_RATE = env("SENTRY_TRACES_SAMPLE_RATE") |
| 174 | +SENTRY_TRACES_IGNORE_PATHS = env.list("SENTRY_TRACES_IGNORE_PATHS") |
| 175 | + |
| 176 | + |
| 177 | +def sentry_traces_sampler(sampling_context: SamplingContext) -> float: |
| 178 | + # Respect parent sampling decision if one exists. Recommended by Sentry. |
| 179 | + if (parent_sampled := sampling_context.get("parent_sampled")) is not None: |
| 180 | + return float(parent_sampled) |
| 181 | + |
| 182 | + # Exclude health check endpoints from tracing |
| 183 | + path = sampling_context.get("wsgi_environ", {}).get("PATH_INFO", "") |
| 184 | + if path.rstrip("/") in SENTRY_TRACES_IGNORE_PATHS: |
| 185 | + return 0 |
| 186 | + |
| 187 | + # Use configured sample rate for all other requests |
| 188 | + return SENTRY_TRACES_SAMPLE_RATE or 0 |
| 189 | + |
| 190 | + |
| 191 | +if env("SENTRY_DSN"): |
| 192 | + sentry_sdk.init( |
| 193 | + dsn=env("SENTRY_DSN"), |
| 194 | + environment=env("SENTRY_ENVIRONMENT"), |
| 195 | + release=env("SENTRY_RELEASE"), |
| 196 | + integrations=[DjangoIntegration()], |
| 197 | + traces_sampler=sentry_traces_sampler, |
| 198 | + profile_session_sample_rate=env("SENTRY_PROFILE_SESSION_SAMPLE_RATE"), |
| 199 | + profile_lifecycle="trace", |
| 200 | + ) |
172 | 201 |
|
173 | 202 | MEDIA_ROOT = env("MEDIA_ROOT") |
174 | 203 | STATIC_ROOT = env("STATIC_ROOT") |
|
270 | 299 | CORS_ALLOWED_ORIGIN_REGEXES = env.list("CORS_ALLOWED_ORIGIN_REGEXES") |
271 | 300 | CORS_ALLOW_ALL_ORIGINS = env.bool("CORS_ALLOW_ALL_ORIGINS") |
272 | 301 |
|
| 302 | +CORS_ALLOW_HEADERS = ( |
| 303 | + *default_headers, |
| 304 | + "baggage", |
| 305 | + "sentry-trace", |
| 306 | +) |
| 307 | + |
273 | 308 | # Configure default CSP rules for different source types |
274 | 309 | CSP_BLOB = "blob:" |
275 | 310 | CSP_DATA = "data:" |
|
0 commit comments