CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-raven

Legacy Python client for Sentry error monitoring service with framework integration and exception tracking capabilities.

Pending
Overview
Eval results
Files

breadcrumb-system.mddocs/

Breadcrumb System

Raven's breadcrumb system provides automatic and manual tracking of user actions and application state leading up to errors, creating a timeline of events that helps with debugging and understanding error context.

Capabilities

Breadcrumb Buffer

Core breadcrumb storage and management with size limits and processing.

from raven.breadcrumbs import BreadcrumbBuffer

class BreadcrumbBuffer:
    def __init__(self, limit=100, message_max_length=1024):
        """
        Initialize breadcrumb buffer with configurable limits.

        Parameters:
        - limit (int): Maximum number of breadcrumbs to store
        - message_max_length (int): Maximum length of breadcrumb messages
        """

    def record(self, timestamp=None, level=None, message=None, category=None, 
               data=None, type=None, processor=None):
        """
        Record a breadcrumb.

        Parameters:
        - timestamp (datetime): Breadcrumb timestamp (defaults to now)
        - level (str): Breadcrumb level ('debug', 'info', 'warning', 'error', 'critical')
        - message (str): Breadcrumb message
        - category (str): Breadcrumb category
        - data (dict): Additional breadcrumb data
        - type (str): Breadcrumb type
        - processor (callable): Custom breadcrumb processor
        """

    def clear(self):
        """Clear all breadcrumbs from buffer."""

    def get_buffer(self):
        """
        Get processed breadcrumbs for event inclusion.

        Returns:
        list: List of processed breadcrumb dictionaries
        """

    def format(self, result):
        """
        Format breadcrumb data, applying length limits.
        
        Parameters:
        - result (dict): Raw breadcrumb data
        
        Returns:
        dict: Formatted breadcrumb data
        """

Breadcrumb Deduplication

Prevent duplicate consecutive breadcrumbs.

from raven.breadcrumbs import event_payload_considered_equal

def event_payload_considered_equal(a, b):
    """
    Check if two breadcrumb payloads are considered equal for deduplication.
    
    Parameters:
    - a (dict): First breadcrumb payload
    - b (dict): Second breadcrumb payload
    
    Returns:
    bool: True if payloads are considered equal
    """

Global Breadcrumb Functions

Module-level functions for recording breadcrumbs across all active clients.

from raven.breadcrumbs import record, record_breadcrumb

def record(**kwargs):
    """
    Record breadcrumb for all active clients.

    Parameters:
    - message (str): Breadcrumb message
    - timestamp (datetime): Breadcrumb timestamp
    - level (str): Breadcrumb level
    - category (str): Breadcrumb category
    - data (dict): Additional breadcrumb data
    - type (str): Breadcrumb type
    - processor (callable): Custom breadcrumb processor
    """

def record_breadcrumb(type, **kwargs):
    """
    Legacy breadcrumb recording function.

    Parameters:
    - type (str): Breadcrumb type
    - **kwargs: Breadcrumb data
    """

Automatic Breadcrumb Collection

Functions for enabling automatic breadcrumb collection from various sources.

from raven.breadcrumbs import (
    install_logging_hook, ignore_logger, register_logging_handler, hook_libraries
)

def install_logging_hook():
    """Install logging breadcrumb hook for automatic log capture."""

def ignore_logger(name_or_logger, allow_level=None):
    """
    Ignore logger for breadcrumb collection.

    Parameters:
    - name_or_logger (str|Logger): Logger name or instance to ignore
    - allow_level (int): Optional minimum level to still capture
    """

def register_logging_handler(callback):
    """
    Register custom logging handler for breadcrumbs.

    Parameters:
    - callback (callable): Handler function for log records
    """

def hook_libraries(libraries):
    """
    Hook libraries for automatic breadcrumb collection.

    Parameters:
    - libraries (list): List of library names to hook
    """

Client Breadcrumb Methods

Client methods for breadcrumb management and recording.

# From Client class
def captureBreadcrumb(self, message=None, timestamp=None, level=None,
                     category=None, data=None, type=None, processor=None):
    """
    Record breadcrumb for this client.

    Parameters:
    - message (str): Breadcrumb message
    - timestamp (datetime): Breadcrumb timestamp
    - level (str): Breadcrumb level
    - category (str): Breadcrumb category
    - data (dict): Additional breadcrumb data
    - type (str): Breadcrumb type
    - processor (callable): Custom breadcrumb processor
    """

Usage Examples

Manual Breadcrumb Recording

from raven import Client

client = Client('https://your-dsn@sentry.io/project-id')

def process_user_order():
    # Record user action
    client.captureBreadcrumb(
        message='User started checkout process',
        category='ui.click',
        level='info',
        data={'button_id': 'checkout-btn', 'cart_items': 3}
    )
    
    # Record API call
    client.captureBreadcrumb(
        message='Calling payment API',
        category='http',
        level='info',
        data={'url': '/api/payments', 'method': 'POST'}
    )
    
    try:
        payment_result = process_payment()
        
        # Record successful operation
        client.captureBreadcrumb(
            message='Payment processed successfully',
            category='payment',
            level='info',
            data={'transaction_id': payment_result.id}
        )
        
    except PaymentError as e:
        # Record failure details
        client.captureBreadcrumb(
            message='Payment processing failed',
            category='payment',
            level='error',
            data={'error_code': e.code, 'error_message': str(e)}
        )
        
        # Exception will include all breadcrumbs
        client.captureException()
        raise

Automatic Logging Breadcrumbs

from raven import Client
from raven.breadcrumbs import install_logging_hook, ignore_logger
import logging

client = Client('https://your-dsn@sentry.io/project-id')

# Enable automatic logging breadcrumbs
install_logging_hook()

# Ignore noisy loggers
ignore_logger('urllib3')
ignore_logger('requests.packages.urllib3')

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def user_workflow():
    logger.info('User login started')
    
    try:
        authenticate_user()
        logger.info('User authenticated successfully')
        
        load_user_data()
        logger.info('User data loaded')
        
        process_request()
        logger.info('Request processed')
        
    except AuthenticationError:
        logger.error('Authentication failed')
        client.captureException()  # Includes log breadcrumbs
    except Exception:
        logger.exception('Unexpected error in user workflow')
        client.captureException()  # Includes log breadcrumbs

Web Request Breadcrumbs

from flask import Flask, request
from raven.contrib.flask import Sentry

app = Flask(__name__)
sentry = Sentry(app)

@app.before_request
def before_request():
    # Record request start
    sentry.client.captureBreadcrumb(
        message=f'{request.method} {request.path}',
        category='http.request',
        level='info',
        data={
            'method': request.method,
            'url': request.url,
            'headers': dict(request.headers),
            'query_string': request.query_string.decode()
        }
    )

@app.after_request
def after_request(response):
    # Record response
    sentry.client.captureBreadcrumb(
        message=f'Response {response.status_code}',
        category='http.response',
        level='info' if response.status_code < 400 else 'warning',
        data={
            'status_code': response.status_code,
            'content_length': response.content_length
        }
    )
    return response

@app.route('/api/users/<int:user_id>')
def get_user(user_id):
    # Record business logic steps
    sentry.client.captureBreadcrumb(
        message=f'Loading user {user_id}',
        category='db.query',
        level='info',
        data={'user_id': user_id}
    )
    
    try:
        user = User.query.get(user_id)
        if not user:
            sentry.client.captureBreadcrumb(
                message='User not found',
                category='business.logic',
                level='warning',
                data={'user_id': user_id}
            )
            return {'error': 'User not found'}, 404
            
        return user.to_dict()
        
    except DatabaseError:
        # Exception includes all request breadcrumbs
        sentry.captureException()
        return {'error': 'Database error'}, 500

Custom Breadcrumb Processors

from raven import Client
import json

def sanitize_breadcrumb_data(data):
    """Remove sensitive data from breadcrumb data."""
    if not isinstance(data, dict):
        return data
    
    sanitized = {}
    for key, value in data.items():
        if key.lower() in ('password', 'token', 'secret', 'key'):
            sanitized[key] = '[FILTERED]'
        elif isinstance(value, dict):
            sanitized[key] = sanitize_breadcrumb_data(value)
        else:
            sanitized[key] = value
    
    return sanitized

client = Client('https://your-dsn@sentry.io/project-id')

def api_call_breadcrumb(url, method, payload=None, response=None):
    """Record API call with sanitized data."""
    breadcrumb_data = {
        'url': url,
        'method': method
    }
    
    if payload:
        breadcrumb_data['payload'] = sanitize_breadcrumb_data(payload)
    
    if response:
        breadcrumb_data['response'] = {
            'status': response.get('status'),
            'size': len(str(response)) if response else 0
        }
    
    client.captureBreadcrumb(
        message=f'{method} {url}',
        category='api.call',
        level='info',
        data=breadcrumb_data,
        processor=sanitize_breadcrumb_data
    )

# Usage
api_call_breadcrumb(
    '/api/auth/login',
    'POST',
    payload={'username': 'john', 'password': 'secret123'},
    response={'status': 200, 'token': 'jwt_token_here'}
)

Database Query Breadcrumbs

from raven import Client
import time

client = Client('https://your-dsn@sentry.io/project-id')

class DatabaseLogger:
    def __init__(self, client):
        self.client = client
    
    def log_query(self, query, params=None, duration=None):
        # Sanitize query parameters
        safe_params = self._sanitize_params(params) if params else None
        
        self.client.captureBreadcrumb(
            message=f'Database query: {query[:50]}...' if len(query) > 50 else query,
            category='db.sql',
            level='info',
            data={
                'query': query,
                'params': safe_params,
                'duration_ms': duration * 1000 if duration else None
            }
        )
    
    def _sanitize_params(self, params):
        if isinstance(params, (list, tuple)):
            return [self._sanitize_value(p) for p in params]
        elif isinstance(params, dict):
            return {k: self._sanitize_value(v) for k, v in params.items()}
        return params
    
    def _sanitize_value(self, value):
        if isinstance(value, str) and len(value) > 100:
            return value[:97] + '...'
        return value

db_logger = DatabaseLogger(client)

def get_user_orders(user_id):
    start_time = time.time()
    
    query = "SELECT * FROM orders WHERE user_id = %s ORDER BY created_at DESC"
    
    try:
        cursor.execute(query, (user_id,))
        results = cursor.fetchall()
        
        duration = time.time() - start_time
        db_logger.log_query(query, (user_id,), duration)
        
        return results
        
    except DatabaseError:
        duration = time.time() - start_time
        db_logger.log_query(query, (user_id,), duration)
        client.captureException()  # Includes query breadcrumb
        raise

Breadcrumb Performance Optimization

from raven import Client
from raven.breadcrumbs import BreadcrumbBuffer

class OptimizedBreadcrumbBuffer(BreadcrumbBuffer):
    def __init__(self, max_buffer_size=100, max_data_size=1024):
        super().__init__(max_buffer_size)
        self.max_data_size = max_data_size
    
    def record(self, **kwargs):
        # Limit data size to prevent memory issues
        if 'data' in kwargs and kwargs['data']:
            kwargs['data'] = self._truncate_data(kwargs['data'])
        
        # Skip duplicate consecutive breadcrumbs
        if self._is_duplicate(kwargs):
            return
        
        super().record(**kwargs)
    
    def _truncate_data(self, data):
        if not isinstance(data, dict):
            return data
        
        truncated = {}
        total_size = 0
        
        for key, value in data.items():
            value_str = str(value)
            if total_size + len(value_str) > self.max_data_size:
                truncated[key] = value_str[:self.max_data_size - total_size - 3] + '...'
                break
            
            truncated[key] = value
            total_size += len(value_str)
        
        return truncated
    
    def _is_duplicate(self, new_breadcrumb):
        if not self.buffer:
            return False
        
        last_breadcrumb = self.buffer[-1]
        return (
            last_breadcrumb.get('message') == new_breadcrumb.get('message') and
            last_breadcrumb.get('category') == new_breadcrumb.get('category')
        )

# Use optimized buffer
client = Client('https://your-dsn@sentry.io/project-id')
client.context.breadcrumbs = OptimizedBreadcrumbBuffer(max_buffer_size=50)

Global Breadcrumb Recording

from raven.breadcrumbs import record

# Record breadcrumbs globally (affects all active clients)
def track_user_action(action, details=None):
    record(
        message=f'User action: {action}',
        category='user.action',
        level='info',
        data=details or {}
    )

def track_system_event(event, level='info', details=None):
    record(
        message=f'System event: {event}',
        category='system',
        level=level,
        data=details or {}
    )

# Usage throughout application
track_user_action('login', {'username': 'john_doe'})
track_user_action('view_product', {'product_id': 123})
track_system_event('cache_miss', 'warning', {'key': 'user_123'})
track_system_event('background_job_completed', 'info', {'job_id': 'abc123'})

Install with Tessl CLI

npx tessl i tessl/pypi-raven

docs

breadcrumb-system.md

context-management.md

core-client.md

data-processing.md

framework-integrations.md

index.md

logging-integration.md

transport-layer.md

tile.json