loguru icon indicating copy to clipboard operation
loguru copied to clipboard

Use Loguru with Azure App Insights and OpenTelemetry

Open bbaabemhp opened this issue 1 year ago • 4 comments

I wanted to know if there is some way to save the logs from Loguru in Azure App Insights? I know that logs are written automatically to App Insights when using the standard logging library, but I couldn't see any way to do with loguru. When going to the Azure Portal and look into the Logs, I can not see any logs I used in my code, regardless of the log level.

Thanks! :)

For context, my code to initialize loguru (used the code from another issue):

import sys

from loguru import logger
from opentelemetry.trace import (
    INVALID_SPAN,
    INVALID_SPAN_CONTEXT,
    get_current_span,
    get_tracer_provider,
)

def instrument_loguru():
    provider = get_tracer_provider()
    service_name = None

    def add_trace_context(record):
        record["extra"]["otelSpanID"] = "0"
        record["extra"]["otelTraceID"] = "0"
        record["extra"]["otelTraceSampled"] = False

        nonlocal service_name
        if service_name is None:
            resource = getattr(provider, "resource", None)
            if resource:
                service_name = resource.attributes.get("service.name") or ""
            else:
                service_name = ""

        record["extra"]["otelServiceName"] = service_name

        span = get_current_span()
        if span != INVALID_SPAN:
            ctx = span.get_span_context()
            if ctx != INVALID_SPAN_CONTEXT:
                record["extra"]["otelSpanID"] = format(ctx.span_id, "016x")
                record["extra"]["otelTraceID"] = format(ctx.trace_id, "032x")
                record["extra"]["otelTraceSampled"] = ctx.trace_flags.sampled

    logger.configure(patcher=add_trace_context)
    logger.remove()
    format_ = "{time:YYYY-MM-DD HH:MM:SS.sss} {level} [{name}] [{file}:{line} [trace_id={extra[otelTraceID]} span_id={extra[otelSpanID]} resource.service.name={extra[otelServiceName]} trace_sampled={extra[otelTraceSampled]}] - {message}"
    logger.add(sys.stderr, format=format_)

bbaabemhp avatar Oct 17 '24 15:10 bbaabemhp

i'm using SINKs as destinations target and converting the record to logging

based on this https://github.com/Delgan/loguru/blob/3b66fb5b2ff38909dbeb817cb50e24f27677db8e/loguru/_simple_sinks.py#L43-L60

something like:

import logging
import os
from loguru import logger

APP_ENV = os.getenv("APP_ENV", "dev")

logger.remove()

def sink_json(loguru_message):
    # code to log as json
    pass

def sink_azure_app_insights(loguru_message):
    record = loguru_message.record
    exc = record["exception"]

    logging_logger = logging.getLogger("my-awesome-app")
    logging_record = logging_logger.makeRecord(
        f"{record['file'].name}:{record['line']}",
        record["level"].no,
        record["file"].path,
        record["line"],
        record["message"],
        (),
        (exc.type, exc.value, exc.traceback) if exc else None,
        record["function"],
        record["extra"],
    )

    if exc:
        logging_record.exc_text = "\n"

    logging_logger.handle(logging_record)

logger.configure(
    handlers=[
        {
            "backtrace": False,
            "diagnose": False,
            "level": "DEBUG",
            "serialize": True,
            "sink": azure_app_insights if APP_ENV == "prod" else sink_json,
        }
    ],
    extra={},
)

oieduardorabelo avatar Oct 18 '24 05:10 oieduardorabelo

Would you be able to use the PropagateHandler snippet from the docs?

It should automatically propagate messagges to loggers of the standard logging library.

Delgan avatar Oct 20 '24 13:10 Delgan

@Delgan is my understanding that PropagateHandler adds a new sink (using .add) and the approach I suggested above is similar, but toggling the sinks instead? (i'm asking to solidify some assumptions i have about loguru)

oieduardorabelo avatar Oct 21 '24 01:10 oieduardorabelo

@Delgan is my understanding that PropagateHandler adds a new sink (using .add) and the approach I suggested above is similar, but toggling the sinks instead? (i'm asking to solidify some assumptions i have about loguru)

@oieduardorabelo Yes, this is correct. While using logger.configure(), you're basically wiping out the existing configuration and replacing it with a new one. In particular, that will replace the default sink (sys.stderr) with the ones in the handlers argument.

Delgan avatar Oct 23 '24 18:10 Delgan