From 9898212855ad2d56f4037e3c5f3174fdacee50c3 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Tue, 4 Nov 2025 14:40:50 +0300 Subject: [PATCH] Features: 1) Introduced `LoggingError` exception for invalid log level handling in `log` method; 2) Updated logging framework to dynamically initialize loggers using `__name__` instead of hardcoded "django". Fixes: 1) Fixed missing `exc_info` flag in critical and error logs to provide richer error context; 2) Addressed redundant code and unused imports in the logging logic for cleaner execution. Extra: Refactored `LOGGING` configuration for improved readability and runtime adaptability; optimized related log-handling logic throughout the codebase. --- blog/views.py | 2 +- core/crm/amo/gateway.py | 2 +- core/filters.py | 2 +- core/graphene/mutations.py | 2 +- core/graphene/object_types.py | 2 +- core/graphene/schema.py | 2 +- core/management/commands/fix_prices.py | 2 +- core/managers.py | 2 +- core/models.py | 2 +- core/serializers/detail.py | 2 +- core/signals.py | 2 +- core/utils/__init__.py | 2 +- core/utils/caching.py | 2 +- core/utils/db.py | 2 +- core/utils/vendors.py | 2 +- core/vendors/__init__.py | 31 ++++----- core/views.py | 2 +- core/viewsets.py | 2 +- evibes/middleware.py | 2 +- evibes/settings/logconfig.py | 89 +++++++++----------------- evibes/utils/misc.py | 4 ++ payments/signals.py | 2 +- payments/views.py | 2 +- vibes_auth/graphene/mutations.py | 2 +- vibes_auth/managers.py | 2 +- vibes_auth/serializers.py | 2 +- vibes_auth/views.py | 2 +- vibes_auth/viewsets.py | 2 +- 28 files changed, 72 insertions(+), 102 deletions(-) diff --git a/blog/views.py b/blog/views.py index 075719c8..eea436a3 100644 --- a/blog/views.py +++ b/blog/views.py @@ -1,3 +1,3 @@ import logging -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) diff --git a/core/crm/amo/gateway.py b/core/crm/amo/gateway.py index bb0b5e64..5edcfdcb 100644 --- a/core/crm/amo/gateway.py +++ b/core/crm/amo/gateway.py @@ -11,7 +11,7 @@ from core.crm.exceptions import CRMException from core.models import CustomerRelationshipManagementProvider, Order, OrderCrmLink from core.utils import is_status_code_success -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class AmoCRM: diff --git a/core/filters.py b/core/filters.py index 64429c99..f66bb486 100644 --- a/core/filters.py +++ b/core/filters.py @@ -39,7 +39,7 @@ from rest_framework.request import Request from core.elasticsearch import process_query from core.models import Address, Brand, Category, Feedback, Order, Product, Stock, Wishlist -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class CaseInsensitiveListFilter(BaseInFilter, CharFilter): # type: ignore [misc] diff --git a/core/graphene/mutations.py b/core/graphene/mutations.py index 77945258..000492b4 100644 --- a/core/graphene/mutations.py +++ b/core/graphene/mutations.py @@ -29,7 +29,7 @@ from core.utils.messages import permission_denied_message from core.utils.nominatim import fetch_address_suggestions from payments.graphene.object_types import TransactionType -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) # noinspection PyUnusedLocal diff --git a/core/graphene/object_types.py b/core/graphene/object_types.py index cb147101..b597f834 100644 --- a/core/graphene/object_types.py +++ b/core/graphene/object_types.py @@ -57,7 +57,7 @@ from core.utils.seo_builders import ( ) from payments.graphene.object_types import TransactionType -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class SEOMetaType(ObjectType): # type: ignore [misc] diff --git a/core/graphene/schema.py b/core/graphene/schema.py index dcb1730f..4553475f 100644 --- a/core/graphene/schema.py +++ b/core/graphene/schema.py @@ -102,7 +102,7 @@ from vibes_auth.graphene.mutations import ( from vibes_auth.graphene.object_types import UserType from vibes_auth.models import User -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class Query(ObjectType): diff --git a/core/management/commands/fix_prices.py b/core/management/commands/fix_prices.py index 420c6148..be133619 100644 --- a/core/management/commands/fix_prices.py +++ b/core/management/commands/fix_prices.py @@ -6,7 +6,7 @@ from django.core.management.base import BaseCommand from core.models import Product from core.vendors import AbstractVendor -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class Command(BaseCommand): diff --git a/core/managers.py b/core/managers.py index caf5f934..124de06a 100644 --- a/core/managers.py +++ b/core/managers.py @@ -6,7 +6,7 @@ from django.contrib.gis.geos import Point from django.db import models from modeltranslation.manager import MultilingualManager -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class AddressManager(models.Manager): diff --git a/core/models.py b/core/models.py index 83d04cec..7396b97b 100644 --- a/core/models.py +++ b/core/models.py @@ -68,7 +68,7 @@ from evibes.settings import CURRENCY_CODE from evibes.utils.misc import create_object from payments.models import Transaction -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel): # type: ignore [misc] diff --git a/core/serializers/detail.py b/core/serializers/detail.py index ad1fc9e5..3afe0476 100644 --- a/core/serializers/detail.py +++ b/core/serializers/detail.py @@ -28,7 +28,7 @@ from core.serializers.simple import CategorySimpleSerializer, ProductSimpleSeria from core.typing import FilterableAttribute from core.serializers.utility import AddressSerializer -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class AttributeGroupDetailSerializer(ModelSerializer): diff --git a/core/signals.py b/core/signals.py index 44a9d1a5..de981a31 100644 --- a/core/signals.py +++ b/core/signals.py @@ -23,7 +23,7 @@ from core.utils.emailing import send_order_created_email, send_order_finished_em from evibes.utils.misc import create_object from vibes_auth.models import User -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) # noinspection PyUnusedLocal diff --git a/core/utils/__init__.py b/core/utils/__init__.py index 596b0f55..debb76ea 100644 --- a/core/utils/__init__.py +++ b/core/utils/__init__.py @@ -17,7 +17,7 @@ from rest_framework.request import Request from evibes.settings import DEBUG, EXPOSABLE_KEYS, LANGUAGE_CODE -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) def graphene_current_lang() -> str: diff --git a/core/utils/caching.py b/core/utils/caching.py index 5827c6a7..d87bca09 100644 --- a/core/utils/caching.py +++ b/core/utils/caching.py @@ -12,7 +12,7 @@ from rest_framework.request import Request from evibes.settings import UNSAFE_CACHE_KEYS from vibes_auth.models import User -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) def is_safe_cache_key(key: str) -> bool: diff --git a/core/utils/db.py b/core/utils/db.py index 476f1c08..e3f3b364 100644 --- a/core/utils/db.py +++ b/core/utils/db.py @@ -6,7 +6,7 @@ from django.db.models.constants import LOOKUP_SEP from django_extensions.db.fields import AutoSlugField from slugify import slugify -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) def unicode_slugify_function(content: Any) -> str: diff --git a/core/utils/vendors.py b/core/utils/vendors.py index 462f2eab..5347ec9d 100644 --- a/core/utils/vendors.py +++ b/core/utils/vendors.py @@ -9,7 +9,7 @@ from core.models import Vendor from core.vendors import AbstractVendor from evibes.utils.misc import create_object -sync_logger = logging.getLogger("django") +sync_logger = logging.getLogger(__name__) async_logger = get_task_logger(__name__) diff --git a/core/vendors/__init__.py b/core/vendors/__init__.py index f83627d9..c0a676e2 100644 --- a/core/vendors/__init__.py +++ b/core/vendors/__init__.py @@ -9,8 +9,6 @@ from io import BytesIO from math import ceil, log10 from typing import Any -from celery import current_task -from celery.utils.log import get_task_logger from constance import config from django.conf import settings from django.core.files.base import ContentFile @@ -30,12 +28,11 @@ from core.models import ( Stock, Vendor, ) -from evibes.utils.misc import LogLevel +from evibes.utils.misc import LoggingError, LogLevel from payments.errors import RatesError from payments.utils import get_rates -async_logger = get_task_logger("vendors") -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class NotEnoughBalanceError(Exception): @@ -111,29 +108,25 @@ class AbstractVendor: return self.get_vendor_instance(safe=True).name if self.get_vendor_instance() else self.vendor_name def log(self, level: LogLevel, message: str) -> None: - is_celery_runtime = False - with suppress(Exception): - is_celery_runtime = bool(getattr(current_task, "request", None)) - - current_logger = async_logger if is_celery_runtime else logger - match level: case LogLevel.DEBUG: if settings.DEBUG: - current_logger.debug(message) + logger.debug(message) case LogLevel.TRACE: - if settings.DEBUG: - current_logger.debug(f"[TRACE] {message}") + logger.debug(f"[TRACE] {message}") case LogLevel.INFO: - current_logger.info(message) + logger.info(message) case LogLevel.WARNING: - current_logger.warning(message) + logger.warning(message) case LogLevel.ERROR: - current_logger.error(message) + if settings.DEBUG: + logger.error(message, exc_info=True) + else: + logger.error(message) case LogLevel.CRITICAL: - current_logger.critical(message) + logger.critical(message, exc_info=True) case _: - current_logger.info(message) + raise LoggingError("Wrong type of logging level passed: %s", level) def save_response(self, data: dict[Any, Any] | list[Any]) -> None: with suppress(Exception): diff --git a/core/views.py b/core/views.py index 88125fad..34a74ce5 100644 --- a/core/views.py +++ b/core/views.py @@ -56,7 +56,7 @@ from evibes import settings from evibes.settings import LANGUAGES from payments.serializers import TransactionProcessSerializer -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) @cache_page(60 * 60 * 12) diff --git a/core/viewsets.py b/core/viewsets.py index a2e39c02..ce8adc6b 100644 --- a/core/viewsets.py +++ b/core/viewsets.py @@ -129,7 +129,7 @@ from core.utils.seo_builders import ( ) from payments.serializers import TransactionProcessSerializer -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class EvibesViewSet(ModelViewSet): diff --git a/evibes/middleware.py b/evibes/middleware.py index b411eb05..9264dc84 100644 --- a/evibes/middleware.py +++ b/evibes/middleware.py @@ -16,7 +16,7 @@ from sentry_sdk import capture_exception from evibes.settings import DEBUG -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class CustomCommonMiddleware(CommonMiddleware): diff --git a/evibes/settings/logconfig.py b/evibes/settings/logconfig.py index 130730a2..f123b267 100644 --- a/evibes/settings/logconfig.py +++ b/evibes/settings/logconfig.py @@ -1,25 +1,22 @@ import logging -from evibes.settings.base import DEBUG +from evibes.settings.base import DEBUG, EVIBES_VERSION class SkipVariableDoesNotExistFilter(logging.Filter): def filter(self, record: logging.LogRecord) -> bool: if record.exc_info: - exc_type, exc_instance, _ = record.exc_info + exc_type, _, _ = record.exc_info try: - if exc_type is not None: - if exc_type.__name__ == "VariableDoesNotExist": - return False - else: - return True + if exc_type is not None and exc_type.__name__ == "VariableDoesNotExist": + return False except AttributeError: - return True + pass return "VariableDoesNotExist" not in record.getMessage() LOGGING = { - "version": 1, + "version": EVIBES_VERSION, "disable_existing_loggers": False, "formatters": { "color": { @@ -40,15 +37,9 @@ LOGGING = { }, }, "filters": { - "require_debug_false": { - "()": "django.utils.log.RequireDebugFalse", - }, - "require_debug_true": { - "()": "django.utils.log.RequireDebugTrue", - }, - "skip_variable_doesnotexist": { - "()": "evibes.settings.logconfig.SkipVariableDoesNotExistFilter", - }, + "require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}, + "require_debug_true": {"()": "django.utils.log.RequireDebugTrue"}, + "skip_variable_doesnotexist": {"()": "evibes.settings.logconfig.SkipVariableDoesNotExistFilter"}, }, "handlers": { "console": { @@ -61,77 +52,59 @@ LOGGING = { "class": "django.utils.log.AdminEmailHandler", }, }, + "root": { + "handlers": ["console"], + "level": "DEBUG" if DEBUG else "INFO", + }, "loggers": { "django": { - "handlers": [ - "console", - "mail_admins", - ], - "level": "DEBUG" if DEBUG else "INFO", + "level": "INFO", "propagate": True, }, + "django.request": { + "handlers": ["mail_admins"], + "level": "ERROR", + "propagate": False, + }, "django.server": { + "handlers": ["console"], "level": "INFO", "propagate": False, }, "django.db.backends": { - "handlers": [ - "console", - "mail_admins", - ], "level": "WARNING", - "propagate": False, + "propagate": True, }, "django.template": { - "handlers": [ - "console", - "mail_admins", - ], "level": "DEBUG" if DEBUG else "ERROR", - "propagate": True, "filters": ["skip_variable_doesnotexist"], + "propagate": True, }, "uvicorn.access": { - "handlers": [ - "console", - ], + "handlers": ["console"], "level": "DEBUG" if DEBUG else "INFO", "propagate": False, }, "uvicorn.error": { - "handlers": [ - "console", - ], - "level": "WARNING", - "propagate": False, - }, - "django_elasticsearch_dsl": { - "handlers": [ - "console", - ], + "handlers": ["console"], "level": "WARNING", "propagate": False, }, "celery.app.trace": { - "handlers": [ - "console", - ], "level": "DEBUG" if DEBUG else "INFO", - "propagate": False, + "propagate": True, }, "celery.worker.strategy": { - "handlers": [ - "console", - ], "level": "DEBUG" if DEBUG else "INFO", - "propagate": False, + "propagate": True, + }, + "django_elasticsearch_dsl": { + "level": "WARNING", + "propagate": True, }, "elastic_transport.transport": { - "handlers": [ - "console", - ], "level": "ERROR", - "propagate": False, + "propagate": True, }, }, } diff --git a/evibes/utils/misc.py b/evibes/utils/misc.py index de8351fa..abcdb921 100644 --- a/evibes/utils/misc.py +++ b/evibes/utils/misc.py @@ -11,6 +11,10 @@ def create_object(module_name: str, class_name: str, *args: list[Any], **kwargs: return cls(*args, **kwargs) +class LoggingError(Exception): + pass + + class LogLevel(Enum): DEBUG = "debug" INFO = "info" diff --git a/payments/signals.py b/payments/signals.py index d108edac..fd5389b2 100644 --- a/payments/signals.py +++ b/payments/signals.py @@ -9,7 +9,7 @@ from payments.models import Balance, Transaction, Gateway from payments.utils.emailing import balance_deposit_email from vibes_auth.models import User -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) # noinspection PyUnusedLocal diff --git a/payments/views.py b/payments/views.py index a151d1c1..4486f0e5 100644 --- a/payments/views.py +++ b/payments/views.py @@ -13,7 +13,7 @@ from payments.gateways import UnknownGatewayError from payments.models import Transaction from payments.serializers import DepositSerializer, TransactionProcessSerializer -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) @extend_schema_view(**DEPOSIT_SCHEMA) diff --git a/vibes_auth/graphene/mutations.py b/vibes_auth/graphene/mutations.py index aaba1d36..1a8f99a7 100644 --- a/vibes_auth/graphene/mutations.py +++ b/vibes_auth/graphene/mutations.py @@ -25,7 +25,7 @@ from vibes_auth.serializers import ( from vibes_auth.utils.emailing import send_reset_password_email_task from vibes_auth.validators import is_valid_email, is_valid_phone_number -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class CreateUser(BaseMutation): diff --git a/vibes_auth/managers.py b/vibes_auth/managers.py index c03ca824..13e607cc 100644 --- a/vibes_auth/managers.py +++ b/vibes_auth/managers.py @@ -7,7 +7,7 @@ from django.contrib.auth.hashers import make_password from core.models import Address, Order -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class UserManager(BaseUserManager): diff --git a/vibes_auth/serializers.py b/vibes_auth/serializers.py index 3fca7fcf..9fd74948 100644 --- a/vibes_auth/serializers.py +++ b/vibes_auth/serializers.py @@ -34,7 +34,7 @@ from evibes import settings from vibes_auth.models import User from vibes_auth.validators import validate_phone_number -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) class UserSerializer(ModelSerializer): diff --git a/vibes_auth/views.py b/vibes_auth/views.py index 7cd1609c..0aeafcb2 100644 --- a/vibes_auth/views.py +++ b/vibes_auth/views.py @@ -21,7 +21,7 @@ from vibes_auth.serializers import ( TokenVerifySerializer, ) -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) @extend_schema_view(**TOKEN_OBTAIN_SCHEMA) diff --git a/vibes_auth/viewsets.py b/vibes_auth/viewsets.py index cd5ffb1c..9d9967dd 100644 --- a/vibes_auth/viewsets.py +++ b/vibes_auth/viewsets.py @@ -29,7 +29,7 @@ from vibes_auth.serializers import ( ) from vibes_auth.utils.emailing import send_reset_password_email_task -logger = logging.getLogger("django") +logger = logging.getLogger(__name__) # noinspection PyUnusedLocal