# How Tos

These are code snippets on how to achieve some specific use cases.

Warning

Be aware they are untested. Please open an issue if there are bugs in these examples or if you want to share some great examples that should be there.

## Bind `request_id` to response’s header

You can add the `request_id` to a custom response header `X-Request-ID` in order to trace the request by the caller.

Origin: #231

    from django.dispatch import receiver
    from django_structlog import signals
    import structlog

    @receiver(signals.update_failure_response)
    @receiver(signals.bind_extra_request_finished_metadata)
    def add_request_id_to_response(response, logger, **kwargs):
        context = structlog.contextvars.get_merged_contextvars(logger)
        response['X-Request-ID'] = context["request_id"]

## Bind `rest_framework_simplejwt` token’s user id

Bind token’s user_id from rest_framework_simplejwt to the request.

It is a workaround for `restframework`’s non-standard authentication system. It prevents access of the user in middlewares, therefore `django-structlog` cannot bind the `user_id` by default.

    import structlog
    from django.dispatch import receiver
    from django_structlog.signals import bind_extra_request_metadata
    from rest_framework_simplejwt.tokens import UntypedToken

    @receiver(bind_extra_request_metadata)
    def bind_token_user_id(request, logger, **kwargs):
        try:
            header = request.META.get("HTTP_AUTHORIZATION")
            if header:
                raw_token = header.split()[1]
                token = UntypedToken(raw_token)
                user_id = token["user_id"]
                structlog.contextvars.bind_contextvars(user_id=user_id)
        except Exception:
            pass

## Bind AWS’s `X-Amzn-Trace-Id`

See Request tracing for your Application Load Balancer

Origin: #324

    from django.dispatch import receiver
    from django_structlog import signals
    from django_structlog.middlewares.request import get_request_header
    import structlog

    @receiver(signals.bind_extra_request_metadata)
    def bind_trace_id(request, logger, **kwargs):
        trace_id = get_request_header(
             request, "x-amzn-trace-id", "HTTP_X_AMZN_TRACE_ID"
        )
        if trace_id:
            structlog.contextvars.bind_contextvars(trace_id=trace_id)

## Filter logs from being recorded

You can add a custom filter to prevent some specific logs from being recorded, based on your criteria

See Django logging documentation

Origin: #412

    # your_project/logging/filters.py

    import logging

    class ExcludeEventsFilter(logging.Filter):
        def __init__(self, excluded_event_type=None):
            super().__init__()
            self.excluded_event_type = excluded_event_type

        def filter(self, record):
            if not isinstance(record.msg, dict) or self.excluded_event_type is None:
                return True  # Include the log message if msg is not a dictionary or excluded_event_type is not provided

            if record.msg.get('event') in self.excluded_event_type:
                return False  # Exclude the log message
            return True  # Include the log message

    # in your settings.py

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'filters': ['exclude_request_started']
            },
        },
        'filters': {
            'exclude_request_started': {
                '()': 'your_project.logging.filters.ExcludeEventsFilter',
                'excluded_event_type': ['request_started']  # Example excluding request_started event
            },
        },
        'loggers': {
            'django': {
                'handlers': ['console'],
                'level': 'DEBUG',
            },
        },
    }