Django集成OpenTelemetry至Azure Application Insights遇ProxyLogger属性错误
Django集成OpenTelemetry日志到Azure Application Insights时出现AttributeError问题
我在Django应用中集成OpenTelemetry日志功能,将日志发送至Azure Application Insights,但遇到如下错误:
AttributeError: 'ProxyLogger' object has no attribute 'resource'
相关配置
1. 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 }, }, }
2. otel_config.py中的OpenTelemetry配置
# 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")
3. 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 Application Insights,但部分场景(如在视图类定义时调用日志)会触发错误,报错栈如下:
Exception in thread django-main-thread: Traceback (most recent call last): File "/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 1016, in _bootstrap_inner self.run() File "/.pyenv/versions/3.10.12/lib/python3.10/threading.py", line 953, in run self._target(*self._args, **self._kwargs) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper fn(*args, **kwargs) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 133, in inner_run self.check(display_num_errors=True) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/core/management/base.py", line 486, in check all_issues = checks.run_checks( File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/core/checks/registry.py", line 88, in run_checks new_errors = check(app_configs=app_configs, databases=databases) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 14, in check_url_config return check_resolver(resolver) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/core/checks/urls.py", line 24, in check_resolver return check_method() File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 519, in check for pattern in self.url_patterns: File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/utils/functional.py", line 47, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 738, in url_patterns patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/utils/functional.py", line 47, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/django/urls/resolvers.py", line 731, in urlconf_module return import_module(self.urlconf_name) File "/.pyenv/versions/3.10.12/lib/python3.10/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1050, in _gcd_import File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/copilot/urls.py", line 13, in <module> import purchase_app.urls File "/purchase_app/urls.py", line 2, in <module> from purchase_app.views import user_views, admin_views File "/purchase_app/views/user_views.py", line 106, in <module> class ApplicationDetailView(APIView): File "/purchase_app/views/user_views.py", line 108, in ApplicationDetailView logger.info("This is the application detail view") File "/.pyenv/versions/3.10.12/lib/python3.10/logging/__init__.py", line 1477, in info self._log(INFO, msg, args, **kwargs) File "/.pyenv/versions/3.10.12/lib/python3.10/logging/__init__.py", line 1624, in _log self.handle(record) File "/.pyenv/versions/3.10.12/lib/python3.10/logging/__init__.py", line 1634, in handle self.callHandlers(record) File "/.pyenv/versions/3.10.12/lib/python3.10/logging/__init__.py", line 1696, in callHandlers hdlr.handle(record) File "/.pyenv/versions/3.10.12/lib/python3.10/logging/__init__.py", line 968, in handle self.emit(record) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/opentelemetry/sdk/_logs/_internal/__init__.py", line 580, in emit logger.emit(self._translate(record)) File "/Desktop/workspace/odin/venv/lib/python3.10/site-packages/opentelemetry/sdk/_logs/_internal/__init__.py", line 568, in _translate resource=logger.resource, AttributeError: 'ProxyLogger' object has no attribute 'resource'
内容的提问来源于stack exchange,提问作者Kaustuv Karki
相关产品推荐
相关产品推荐

