Django OpenTelemetry Logging Error: 'ProxyLogger' object has no attribute 'resource' Azure application insights
Я интегрирую регистрацию OpenTelemetry в свое Django-приложение для отправки журналов в Azure Application Insights, но сталкиваюсь со следующей ошибкой:
AttributeError: 'ProxyLogger' object has no attribute 'resource'
В настройках есть следующая настройка логгера copilot/settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
},
'root': {
'handlers': ['console'],
'level': 'INFO',
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'INFO',
'propagate': True,
},
'copilot': { # Parent logger for your app
'handlers': ['console'],
'level': 'INFO',
'propagate': True, # Allows child loggers to inherit handlers
},
},
}
Это copilot/otel_config.py
# otel_config.py
import os
from django.conf import settings
import logging
from dotenv import load_dotenv
from opentelemetry import trace
from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk._logs import (
LoggerProvider,
LoggingHandler,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter, AzureMonitorLogExporter
from opentelemetry.instrumentation.django import DjangoInstrumentor
from opentelemetry.instrumentation.logging import LoggingInstrumentor
def setup_opentelemetry():
# Set up the tracer provider with resource attributes
resource = Resource(attributes={
"service.name": "copilot",
})
tracer_provider = TracerProvider()
trace.set_tracer_provider(tracer_provider)
connection_string = settings.APPLICATIONINSIGHTS_CONNECTION_STRING
trace_exporter = AzureMonitorTraceExporter(
connection_string = connection_string
)
span_processor = BatchSpanProcessor(trace_exporter)
tracer_provider.add_span_processor(span_processor)
# Initialize LoggerProvider
logger_provider = LoggerProvider(resource=resource)
set_logger_provider(logger_provider)
log_exporter = AzureMonitorLogExporter(
connection_string = connection_string
)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
LoggingInstrumentor().instrument(set_logging_format=True)
\
DjangoInstrumentor().instrument()
logging.basicConfig(level=logging.INFO) # Set to INFO or DEBUG as needed
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO) # Ensure the root logger captures INFO level logs
# Remove existing handlers to avoid duplication
# for handler in root_logger.handlers[:]:
# root_logger.removeHandler(handler)
# Add Azure Monitor Log Exporter as a handler
azure_log_handler = LoggingHandler(level=logging.INFO)
root_logger.addHandler(azure_log_handler)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s [%(levelname)s] %(name)s: %(message)s'
)
console_handler.setFormatter(formatter)
root_logger.addHandler(console_handler)
# Log a test warning to verify setup
root_logger.warning("OpenTelemetry setup complete")
Это logger_utils utils/logger_utils.py
import logging
from opentelemetry.sdk._logs import LoggingHandler
from django.conf import settings
def get_logger(name: str):
logger = logging.getLogger(name)
# if settings.DJANGO_ENV == 'development':
# return logger
handler = LoggingHandler(level=logging.DEBUG)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
return logger
Я вызываю регистратор, как показано ниже в коде в представлениях и службах
from utils.logger_utils import get_logger
logger = get_logger(__name__)
logger.info("Test")
При доступе к файлам в большинстве случаев это работает и также регистрируется на azure app insights, но в некоторых случаях это не удается и выдает ошибку
В вашем коде Django неправильно настроено ведение журнала открытой телеметрии.
Ниже приводится подробное объяснение причины проблемы и пути ее решения.
Убедитесь, что открытая телеметрия инициализирована до того, как Django загрузит конфигурации ведения журнала.
Изменить wsgi.py
или manage.py
:
from otel_config import setup_opentelemetry
setup_opentelemetry()
Измените otel_config.py
, чтобы убедиться, что LoggerProvider
установлено перед вызовом LoggingInstrumentor()
:
import logging
from opentelemetry import trace
from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter, AzureMonitorLogExporter
from opentelemetry.instrumentation.django import DjangoInstrumentor
from opentelemetry.instrumentation.logging import LoggingInstrumentor
def setup_opentelemetry():
resource = Resource(attributes={"service.name": "copilot"})
tracer_provider = TracerProvider(resource=resource)
trace.set_tracer_provider(tracer_provider)
connection_string = "YOUR_AZURE_MONITOR_CONNECTION_STRING"
trace_exporter = AzureMonitorTraceExporter(connection_string=connection_string)
span_processor = BatchSpanProcessor(trace_exporter)
tracer_provider.add_span_processor(span_processor)
logger_provider = LoggerProvider(resource=resource)
set_logger_provider(logger_provider)
log_exporter = AzureMonitorLogExporter(connection_string=connection_string)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
LoggingInstrumentor().instrument(set_logging_format=True)
DjangoInstrumentor().instrument()
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)
azure_log_handler = LoggingHandler(level=logging.INFO)
root_logger.addHandler(azure_log_handler) logging.getLogger("django").info("OpenTelemetry setup complete")
Измените utils/logger_utils.py
, чтобы использовать открытый поставщик регистраторов телеметрии:
import logging
from opentelemetry._logs import get_logger_provider
def get_logger(name: str):
provider = get_logger_provider()
logger = provider.get_logger(name) # Ensures logger comes from OpenTelemetry
return logger