Sentry Integration¶
LogXide provides seamless integration with Sentry for automatic error tracking and monitoring. When Sentry is configured in your application, LogXide automatically detects it and sends WARNING, ERROR, and CRITICAL level logs to Sentry.
Installation¶
To use Sentry integration, install LogXide with the sentry extra:
Quick Start¶
Automatic Integration (Recommended)¶
LogXide automatically detects and integrates with Sentry when you configure it:
# 1. Configure Sentry as usual
import sentry_sdk
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/project-id",
environment="production",
traces_sample_rate=1.0,
)
# 2. Use LogXide - Sentry integration is automatic!
from logxide import logging
logger = logging.getLogger(__name__)
# These will automatically go to Sentry
logger.warning("This warning will appear in Sentry")
logger.error("This error will be tracked in Sentry")
logger.critical("Critical issues are sent to Sentry")
# These won't go to Sentry (below WARNING level)
logger.info("Info messages are not sent to Sentry")
logger.debug("Debug messages are not sent to Sentry")
That's it! No additional configuration needed.
Detection requires a configured SDK
Auto-detection attaches a Sentry handler only when the Sentry SDK is already configured — that is, sentry_sdk.init() (or the equivalent environment variables) has run before you use LogXide. Merely having sentry-sdk installed but never initialized does not attach a Sentry handler. As of 0.2.1, importing an unconfigured Sentry SDK also no longer forces process-global caller-frame collection onto unrelated handlers, so logs whose format string does not need caller info stay on the fast path.
Manual Handler Configuration¶
For more control, you can manually configure the Sentry handler:
from logxide import logging, SentryHandler
# Create a logger
logger = logging.getLogger('myapp')
# Create and configure Sentry handler
sentry_handler = SentryHandler(
level=logging.ERROR, # Only send ERROR and above
with_breadcrumbs=False # Disable breadcrumbs
)
# Add handler to logger
logger.addHandler(sentry_handler)
Features¶
Automatic Level Filtering¶
By default, LogXide sends only WARNING level and above to Sentry to avoid noise:
- DEBUG: Not sent to Sentry
- INFO: Not sent to Sentry
- WARNING: Sent to Sentry
- ERROR: Sent to Sentry
- CRITICAL: Sent to Sentry
Exception Tracking¶
Exceptions are automatically captured with full stack traces:
logger = logging.getLogger(__name__)
try:
1 / 0
except ZeroDivisionError:
# This sends the exception to Sentry with stack trace
logger.exception("Division by zero occurred")
Rich Context¶
LogXide automatically includes rich context in Sentry events:
# Context is automatically included
logger.error("Database connection failed", extra={
"database": "production",
"host": "db.example.com",
"retry_count": 3
})
The following context is automatically captured: - Logger name - Thread and process information - Source code location (file, line, function) - Timestamp - Custom extra data
Structured Logging with Sentry¶
Use Sentry's scope for additional context:
import sentry_sdk
# Add user context
with sentry_sdk.configure_scope() as scope:
scope.user = {"id": "123", "username": "alice"}
logger.error("User action failed") # Includes user context
# Add custom tags
with sentry_sdk.configure_scope() as scope:
scope.set_tag("module", "payment")
scope.set_tag("action", "process_order")
logger.error("Payment processing failed")
# Add breadcrumbs for debugging
sentry_sdk.add_breadcrumb(
message="User clicked checkout",
category="ui",
level="info"
)
logger.error("Checkout failed") # Breadcrumb trail included
Configuration Options¶
Control Sentry Integration¶
Configure the SDK before constructing a handler: availability is checked at
handler creation, not again for every log. Attach the handler with addHandler,
not basicConfig(handlers=...), which this adapter does not support. This
dedicated logger uses the direct LogXide getLogger API and does not propagate
to the automatically configured root handler, avoiding duplicate events.
import sentry_sdk
sentry_sdk.init(dsn="your-dsn")
from logxide import SentryHandler, getLogger, logging
logger = getLogger("myapp.sentry")
logger.setLevel(logging.WARNING)
logger.propagate = False
sentry_handler = SentryHandler()
logger.addHandler(sentry_handler)
if sentry_handler.is_available:
print("Sentry is configured and ready")
Environment Variables¶
LogXide respects standard Sentry environment variables:
export SENTRY_DSN="https://your-dsn@sentry.io/project-id"
export SENTRY_ENVIRONMENT="production"
export SENTRY_RELEASE="myapp@1.0.0"
Custom Filtering¶
After configuring the SDK, use a dedicated logger with a handler-level filter.
Python handler filters receive a LogRecord with getMessage(); raw LogXide
logger filters receive a dictionary instead, so do not attach this filter with
logger.addFilter. Disable propagation so an unfiltered root Sentry handler
cannot forward the same message.
from logxide import SentryHandler, getLogger, logging
class SensitiveDataFilter(logging.Filter):
def filter(self, record):
# Check the rendered message, including %-format arguments.
return 'password' not in record.getMessage().lower()
logger = getLogger("myapp.sentry.filtered")
logger.setLevel(logging.WARNING)
logger.propagate = False
sentry_handler = SentryHandler()
sentry_handler.addFilter(SensitiveDataFilter())
logger.addHandler(sentry_handler)
This example drops matching messages only on this logger's Sentry route. It is
not general data scrubbing: it does not inspect extra, exception contents,
other loggers, or events captured by Sentry framework integrations. Never log
secrets; configure SDK event scrubbing separately for those other paths.
Best Practices¶
1. Use Appropriate Log Levels¶
# Good practices
logger.debug("Detailed debug info") # Development only
logger.info("User logged in") # Normal operations
logger.warning("API rate limit approaching") # Warnings to Sentry
logger.error("Failed to process payment") # Errors to Sentry
logger.critical("Database connection lost") # Critical to Sentry
2. Include Helpful Context¶
# Include relevant context
logger.error("Order processing failed", extra={
"order_id": order.id,
"user_id": user.id,
"payment_method": order.payment_method,
"error_code": "PAYMENT_DECLINED"
})
3. Use Exception Logging¶
try:
process_order(order)
except ProcessingError as e:
# Use exception() to include stack trace
logger.exception("Order processing failed: %s", e, extra={
"order_id": order.id
})
4. Group Related Errors¶
# Use consistent messages for grouping in Sentry
logger.error("Database query timeout", extra={
"query": str(query),
"duration": query_time,
"table": "orders"
})
Performance Considerations¶
Asynchronous Sending¶
LogXide and Sentry both use asynchronous sending to avoid blocking:
# This returns immediately
logger.error("Error message") # Sent async to Sentry
# Force synchronous flush if needed
import sentry_sdk
sentry_sdk.flush() # Wait for all events to be sent
Rate Limiting¶
Sentry has built-in rate limiting. For high-volume applications:
# Configure sampling
sentry_sdk.init(
dsn="...",
sample_rate=0.25, # Send 25% of events
traces_sample_rate=0.1, # 10% of performance data
)
Disable in Development¶
import os
# Only enable Sentry in production
if os.getenv("ENVIRONMENT") == "production":
sentry_sdk.init(dsn="...")
from logxide import logging # Auto-detects Sentry config
Troubleshooting¶
Sentry Not Receiving Events¶
-
Check Sentry Configuration:
-
Verify Handler is Active:
-
Check Log Levels:
-
Force Flush:
Testing Sentry Integration¶
# Test script
import sentry_sdk
sentry_sdk.init(dsn="your-dsn")
from logxide import logging
logger = logging.getLogger("test")
# Test different levels
logger.warning("Test warning")
logger.error("Test error")
try:
raise ValueError("Test exception")
except ValueError:
logger.exception("Test exception logging")
# Ensure delivery
logging.flush()
sentry_sdk.flush(timeout=2.0)
print("Check your Sentry dashboard!")
Integration with Frameworks¶
Flask¶
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
sentry_sdk.init(
dsn="your-dsn",
integrations=[FlaskIntegration()]
)
from flask import Flask
from logxide import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
@app.errorhandler(500)
def handle_error(error):
logger.error("Internal server error", exc_info=error)
return "Internal Server Error", 500
Django¶
# settings.py
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="your-dsn",
integrations=[DjangoIntegration()]
)
# Use LogXide in your views
from logxide import logging
logger = logging.getLogger(__name__)
def my_view(request):
logger.info("View accessed") # Not sent to Sentry
logger.error("View error") # Sent to Sentry
FastAPI¶
import sentry_sdk
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
sentry_sdk.init(dsn="your-dsn")
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from logxide import logging
app = FastAPI()
app.add_middleware(SentryAsgiMiddleware)
logger = logging.getLogger(__name__)
@app.exception_handler(Exception)
async def exception_handler(request, exc):
logger.exception("Unhandled exception", exc_info=exc)
return JSONResponse(
status_code=500,
content={"error": "Internal server error"}
)
Advanced Usage¶
Custom Event Processors¶
def process_event(event, hint):
# Modify event before sending to Sentry
if 'user' in event:
# Anonymize user data
event['user']['id'] = hash(event['user'].get('id', ''))
return event
sentry_sdk.init(
dsn="your-dsn",
before_send=process_event
)
Performance Monitoring¶
import sentry_sdk
# Enable performance monitoring
sentry_sdk.init(
dsn="your-dsn",
traces_sample_rate=1.0,
profiles_sample_rate=1.0,
)
# LogXide will include timing information
with sentry_sdk.start_transaction(op="process", name="order_processing"):
logger.info("Processing order")
# ... processing logic ...
logger.info("Order processed")
Security Considerations¶
Filtering Sensitive Data¶
# Don't log sensitive information
logger.error("Login failed for user", extra={
"username": user.username,
# Don't include: "password": user.password
})
# Use Sentry's data scrubbing
sentry_sdk.init(
dsn="your-dsn",
send_default_pii=False, # Don't send personally identifiable info
)
Compliance¶
For GDPR and privacy compliance:
sentry_sdk.init(
dsn="your-dsn",
attach_stacktrace=False, # Don't attach stack traces
send_default_pii=False, # Don't send PII
request_bodies="never", # Never send request bodies
)
Summary¶
LogXide's Sentry integration provides:
- Automatic integration once the Sentry SDK is configured
- Smart filtering of log levels
- Rich context capture
- Security-conscious defaults
- High performance with async sending
- Full control when needed
Just install, configure Sentry as usual, and LogXide handles the rest!