Using multiple DSNs, choosing based on the logger
See original GitHub issueI’m looking to upgrade from raven-python[flask] to sentry-sdk[flask]. We previous had two DSNs for our backend: one for errors and one to log performance issues (e.g. slow requests / high DB query count).
We were previously able to configure this via:
from raven.contrib.flask import Sentry
from raven.handlers.logging import SentryHandler
performance_logger = logging.getLogger("benchling.performance")
performance_logger.setLevel(logging.WARNING)
sentry = Sentry(logging=True, level=logging.WARNING)
def init_sentry(app):
sentry.init_app(app, dsn=app.config["SENTRY_DSN_SERVER"])
performance_handler = SentryHandler(dsn=app.config["SENTRY_DSN_BACKEND_PERFORMANCE"])
performance_logger.addHandler(performance_handler)
With the new architecture, this seems hard to do since the DSN is configured once via sentry_sdk.init where the LoggingIntegration simply listens to the root logger. I was able to hack around this by monkey-patching the logging_integration’s handler as follows:
import logging
import sentry_sdk
from sentry_sdk.client import Client
from sentry_sdk.hub import Hub
from sentry_sdk.integrations.celery import CeleryIntegration
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
def register_clients_for_loggers(logger_name_to_client):
"""Monkeypatch LoggingIntegration's EventHandler to override the Client based on the record's logger"""
hub = Hub.current
logging_integration = hub.get_integration(LoggingIntegration)
if not logging_integration:
return
handler = logging_integration._handler
old_emit = handler.emit
def new_emit(record):
new_client = logger_name_to_client.get(record.name)
previous_client = hub.client
should_bind = new_client is not None
try:
if should_bind:
hub.bind_client(new_client)
old_emit(record)
finally:
if should_bind:
hub.bind_client(previous_client)
handler.emit = new_emit
def init_sentry(app):
sentry_sdk.init(
dsn=app.config["SENTRY_DSN_SERVER"],
release=app.config["SENTRY_RELEASE"],
environment=app.config["SENTRY_ENVIRONMENT"],
integrations=[
LoggingIntegration(
level=logging.WARNING, # Capture info and above as breadcrumbs
event_level=logging.WARNING, # Send warnings and errors as events
),
CeleryIntegration(),
FlaskIntegration(),
],
)
performance_logger = logging.getLogger("benchling.performance")
performance_logger.setLevel(logging.WARNING)
perf_client = Client(
dsn=app.config["SENTRY_DSN_BACKEND_PERFORMANCE"],
release=app.config["SENTRY_RELEASE"],
environment=app.config["SENTRY_ENVIRONMENT"],
)
register_clients_for_loggers({performance_logger.name: perf_client})
Two questions:
- Does this approach seem reasonable, or is there a better way to handle this?
- If there isn’t a better way, would it be possible to have
sentry_sdk.init
let you specify this mapping?
Issue Analytics
- State:
- Created 5 years ago
- Comments:22 (10 by maintainers)
Top Results From Across the Web
DNS and Domain Logging: A Bird's Eye View - DomainTools
Discover everything you need to know about log collection. In the first blog of this five-part series, we'll give an industry overview on ......
Read more >Logback to log different messages to two files - Stack Overflow
You can have as many loggers as you wish. But, it's better you have one for each package that you need to log...
Read more >DNS Logging and Diagnostics - Microsoft Learn
Enhanced DNS logging and diagnostics in Windows Server 2012 R2 and later includes DNS Audit events and DNS Analytic events. DNS audit logs...
Read more >Logger in Java - Java Logging Example - DigitalOcean
We can add multiple handlers to a java logger and whenever we log any message, every handler will process it accordingly. There are...
Read more >Choosing a routing policy - Amazon Route 53
You can use failover routing to create records in a private hosted zone. Geolocation routing policy – Use when you want to route...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
What is the easiest way to use multiple dsn nowadays? I do not need to configure somehow, I just need 2 dns supported simultaneously.
btw sorry @saifelse for the lack of response. Passing a function as a transport is only used for testing purposes. I think your approach is fine. Something we could improve is to put a
TransportMultiplexer
class into the SDK which forwards the event to all transports, and then each transport decides by itself if it wants to send.