Skip to content

Add Support for SpanAttributes.SESSION_ID in Python Azure SDK for Application Insights Integration - Bis #49019

Description

@paul-ri

Is your feature request related to a problem? Please describe.
This is the same request as #39433, which was closed due to the author having moved on, and I cannot comment there.
Monkey patching _convert_span_to_envelope to add the session tag works.

Describe the solution you'd like
Be able to see distinct sessions on an Azure Web App AppInsights. At the moment there is only ever 1 shown for all users

Describe alternatives you've considered
In a Django application (that uses social-auth-app-django to authenticate users with Entra ID), I have added the following middleware that does 2 things:

  1. Add attributes to the span:
    • The user ID attribute. This is successfully picked up by AppInsights and I can distinguish the users from the native UI Users tool
    • A session ID unique to the current user. For the purpose of this ticket, here it's just the user ID again. Without the following step (patch) there's still always just 1 session displayed on the AppInsights Sessions UI.
  2. Patch _convert_span_to_envelope in order to add the session tag manually. That does allow AppInsights to distinguish sessions
import azure.monitor.opentelemetry.exporter.export.trace._exporter as trace_exporter
from azure.monitor.opentelemetry.exporter._generated.exporter.models import ContextTagKeys
from opentelemetry import trace


class TelemetryIdentityMiddleware:
    """
    Add custom attributes to track user actions in Azure AppInsight.
    https://learn.microsoft.com/en-us/azure/azure-monitor/app/usage?tabs=users#track-user-interactions-with-custom-events
    """
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        span = trace.get_current_span()

        if span.is_recording():
            if request.user.is_authenticated:
                if social_auth := request.user.social_auth.first():
                    span.set_attribute("enduser.id", social_auth.uid)
                    span.set_attribute("enduser.pseudo.id", request.user.username)

                # Note: for the purpose of this ticket, the value is set to just the ID unique to the user
                span.set_attribute("session.id", social_auth.uid)

        return self.get_response(request)


_original_convert_span_to_envelope = trace_exporter._convert_span_to_envelope

def _patched_convert_span_to_envelope(span):
    """Attempt to handle session on AppInsights"""
    envelope = _original_convert_span_to_envelope(span)

    session_id = None
    if span.attributes:
        session_id = span.attributes.get("session.id")

    if session_id:
        envelope.tags[ContextTagKeys.AI_SESSION_ID] = str(session_id)
        envelope.tags["session.id"] = str(session_id)

    return envelope

# Apply monkey patch
trace_exporter._convert_span_to_envelope = _patched_convert_span_to_envelope

Additional context:
The .Net SDK has had similar issues / requests here. Some suggest ai.session.id attribute worked for them, it didn't when I tried.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions