loguru
loguru copied to clipboard
Use Loguru with Azure App Insights and OpenTelemetry
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_)
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={},
)
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 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)
@Delgan is my understanding that
PropagateHandleradds 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.