census-instrumentation / opencensus-python

A stats collection and distributed tracing framework
Apache License 2.0
666 stars 248 forks source link

AzureExporter creates an invalid request if SpanData contains a stacktrace of type string #1241

Open ivarec opened 4 months ago

ivarec commented 4 months ago

Describe your environment. python 3.12 opencensus 0.11.4 opencensus-context 0.1.3 opencensus-ext-azure 1.1.13 opencensus-ext-django 0.8.0 opencensus-ext-logging 0.1.1 opencensus-ext-requests 0.8.0

Steps to reproduce. I have been able to reproduce it with a simple Django application, but I can imagine that it's easily reproducible regardless of Django.

  1. Create a simple Django application
  2. Configure AppInsights integration like this:
MIDDLEWARE = [
    # ...
    "opencensus.ext.django.middleware.OpencensusMiddleware",
    # ...
]

OPENCENSUS = {
    "TRACE": {
        "SAMPLER": "opencensus.trace.samplers.ProbabilitySampler(rate=1)",
        "EXPORTER": f"""opencensus.ext.azure.trace_exporter.AzureExporter(
            connection_string="{os.getenv('APPLICATIONINSIGHTS_CONNECTION_STRING')}"
        )""",
    }
}

from opencensus.trace import config_integration

config_integration.trace_integrations(["requests", "logging", "postgresql"])

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "simple": {"format": "%(asctime)s | %(levelname)s | %(message)s"},
    },
    "handlers": {
        "stdout": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "simple",
        },
        "log_to_appinsights": {
            "level": "DEBUG",
            "class": "opencensus.ext.azure.log_exporter.AzureLogHandler",
            "connection_string": os.environ.get(
                "APPLICATIONINSIGHTS_CONNECTION_STRING"
            ),
            "formatter": "simple",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["stdout", "log_to_appinsights"],
        },
    },
}
  1. Cause an exception to be raised inside a request handled by Django

What is the expected behavior? Data point (exception trace) should be correctly posted to AppInsights

What is the actual behavior? I get the following error:

Data drop 400: 106: Field 'parsedStack' on type 'ExceptionDetails' is of incorrect type. Expected: array {<redacted>}.

Additional context.

I can see that the opencensus-ext-azure library expects the stacktrace attribute of a trace to be of type "array". Here is the relevant snippet:

https://github.com/census-instrumentation/opencensus-python/blob/2e0710bf9ef733f29607418e51f0719422155361/contrib/opencensus-ext-azure/opencensus/ext/azure/trace_exporter/__init__.py#L102-L104

And I can also see that the exporter in opencensus-ext-django prepares this attribute as a string:

https://github.com/census-instrumentation/opencensus-python/blob/2e0710bf9ef733f29607418e51f0719422155361/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py#L298-L300

I am not knowledgeable yet in OpenCensus and this library. I am not sure which side is incorrect: if it's the Django part or the Azure part. I also don't feel confident in writing a PR for this. Let me know if I can help further.