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.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-11-04 14:40:50 +03:00
parent 38b22704b1
commit 9898212855
28 changed files with 72 additions and 102 deletions

View file

@ -1,3 +1,3 @@
import logging
logger = logging.getLogger("django")
logger = logging.getLogger(__name__)

View file

@ -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:

View file

@ -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]

View file

@ -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

View file

@ -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]

View file

@ -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):

View file

@ -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):

View file

@ -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):

View file

@ -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]

View file

@ -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):

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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__)

View file

@ -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):

View file

@ -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)

View file

@ -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):

View file

@ -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):

View file

@ -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,
},
},
}

View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -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):

View file

@ -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):

View file

@ -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):

View file

@ -21,7 +21,7 @@ from vibes_auth.serializers import (
TokenVerifySerializer,
)
logger = logging.getLogger("django")
logger = logging.getLogger(__name__)
@extend_schema_view(**TOKEN_OBTAIN_SCHEMA)

View file

@ -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