refactor(monitoring): remove django-prometheus integration

Replaced `django-prometheus` with the default Django components, including model mixins, database backends, and cache configuration. This change simplifies monitoring setup by removing unnecessary dependencies, reducing overhead, and improving compatibility.

**Details:**
- Removed Prometheus metrics endpoints and middleware.
- Updated database, cache, and model configurations to remove `django-prometheus`.
- Adjusted WSGI settings to integrate OpenTelemetry instrumentation instead of Prometheus.
- Updated dependency files and migration schemas accordingly.
This commit is contained in:
Egor Pavlovich Gorbunov 2026-02-21 23:44:15 +03:00
parent 1756c3f2b2
commit 069d416585
12 changed files with 30 additions and 77 deletions

View file

@ -1,7 +1,6 @@
import uuid
import django_extensions.db.fields
import django_prometheus.models
from django.db import migrations, models
@ -251,10 +250,7 @@ class Migration(migrations.Migration):
"verbose_name": "category tag",
"verbose_name_plural": "category tags",
},
bases=(
django_prometheus.models.ExportModelOperationsMixin("category_tag"),
models.Model,
),
bases=(models.Model,),
),
migrations.AddField(
model_name="category",

View file

@ -2,7 +2,6 @@ import uuid
import django.db.models.deletion
import django_extensions.db.fields
import django_prometheus.models
from django.db import migrations, models
@ -80,10 +79,7 @@ class Migration(migrations.Migration):
"verbose_name": "order CRM link",
"verbose_name_plural": "orders CRM links",
},
bases=(
django_prometheus.models.ExportModelOperationsMixin("crm_provider"),
models.Model,
),
bases=(models.Model,),
),
migrations.CreateModel(
name="OrderCrmLink",
@ -148,9 +144,6 @@ class Migration(migrations.Migration):
"verbose_name": "order CRM link",
"verbose_name_plural": "orders CRM links",
},
bases=(
django_prometheus.models.ExportModelOperationsMixin("order_crm_link"),
models.Model,
),
bases=(models.Model,),
),
]

View file

@ -46,7 +46,6 @@ from django.utils.functional import cached_property
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _
from django_extensions.db.fields import AutoSlugField
from django_prometheus.models import ExportModelOperationsMixin
from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel
@ -76,7 +75,7 @@ from schon.utils.misc import create_object
logger = logging.getLogger(__name__)
class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel):
class AttributeGroup(NiceModel):
__doc__ = _(
"Represents a group of attributes, which can be hierarchical."
" This class is used to manage and organize attribute groups."
@ -109,7 +108,7 @@ class AttributeGroup(ExportModelOperationsMixin("attribute_group"), NiceModel):
verbose_name_plural = _("attribute groups")
class Vendor(ExportModelOperationsMixin("vendor"), NiceModel):
class Vendor(NiceModel):
__doc__ = _(
"Represents a vendor entity capable of storing information about external vendors and their interaction requirements."
" The Vendor class is used to define and manage information related to an external vendor."
@ -193,7 +192,7 @@ class Vendor(ExportModelOperationsMixin("vendor"), NiceModel):
]
class ProductTag(ExportModelOperationsMixin("product_tag"), NiceModel):
class ProductTag(NiceModel):
__doc__ = _(
"Represents a product tag used for classifying or identifying products."
" The ProductTag class is designed to uniquely identify and classify products through a combination"
@ -225,7 +224,7 @@ class ProductTag(ExportModelOperationsMixin("product_tag"), NiceModel):
verbose_name_plural = _("product tags")
class CategoryTag(ExportModelOperationsMixin("category_tag"), NiceModel):
class CategoryTag(NiceModel):
__doc__ = _(
"Represents a category tag used for products."
" This class models a category tag that can be used to associate and classify products."
@ -256,7 +255,7 @@ class CategoryTag(ExportModelOperationsMixin("category_tag"), NiceModel):
verbose_name_plural = _("category tags")
class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel):
class Category(NiceModel, MPTTModel):
__doc__ = _(
"Represents a category entity to organize and group related items in a hierarchical structure."
" Categories may have hierarchical relationships with other categories, supporting parent-child relationships."
@ -457,7 +456,7 @@ class Category(ExportModelOperationsMixin("category"), NiceModel, MPTTModel):
ordering = ["tree_id", "lft"]
class Brand(ExportModelOperationsMixin("brand"), NiceModel):
class Brand(NiceModel):
__doc__ = _(
"Represents a Brand object in the system. "
"This class handles information and attributes related to a brand, including its name, logos, "
@ -527,7 +526,7 @@ class Brand(ExportModelOperationsMixin("brand"), NiceModel):
verbose_name_plural = _("brands")
class Stock(ExportModelOperationsMixin("stock"), NiceModel):
class Stock(NiceModel):
__doc__ = _(
"Represents the stock of a product managed in the system."
" This class provides details about the relationship between vendors, products, and their stock information, "
@ -595,7 +594,7 @@ class Stock(ExportModelOperationsMixin("stock"), NiceModel):
verbose_name_plural = _("stock entries")
class Product(ExportModelOperationsMixin("product"), NiceModel):
class Product(NiceModel):
__doc__ = _(
"Represents a product with attributes such as category, brand, tags, digital status, name, description, part number, and slug."
" Provides related utility properties to retrieve ratings, feedback counts, price, quantity, and total orders."
@ -767,7 +766,7 @@ class Product(ExportModelOperationsMixin("product"), NiceModel):
return self.images.exists()
class Attribute(ExportModelOperationsMixin("attribute"), NiceModel):
class Attribute(NiceModel):
__doc__ = _(
"Represents an attribute in the system."
" This class is used to define and manage attributes,"
@ -826,7 +825,7 @@ class Attribute(ExportModelOperationsMixin("attribute"), NiceModel):
verbose_name_plural = _("attributes")
class AttributeValue(ExportModelOperationsMixin("attribute_value"), NiceModel):
class AttributeValue(NiceModel):
__doc__ = _(
"Represents a specific value for an attribute that is linked to a product. "
"It links the 'attribute' to a unique 'value', allowing "
@ -866,7 +865,7 @@ class AttributeValue(ExportModelOperationsMixin("attribute_value"), NiceModel):
verbose_name_plural = _("attribute values")
class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel):
class ProductImage(NiceModel):
__doc__ = _(
"Represents a product image associated with a product in the system. "
"This class is designed to manage images for products, including functionality "
@ -920,7 +919,7 @@ class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel):
verbose_name_plural = _("product images")
class Promotion(ExportModelOperationsMixin("promotion"), NiceModel):
class Promotion(NiceModel):
__doc__ = _(
"Represents a promotional campaign for products with a discount. "
"This class is used to define and manage promotional campaigns that offer a "
@ -966,7 +965,7 @@ class Promotion(ExportModelOperationsMixin("promotion"), NiceModel):
return str(self.id)
class Wishlist(ExportModelOperationsMixin("wishlist"), NiceModel):
class Wishlist(NiceModel):
__doc__ = _(
"Represents a user's wishlist for storing and managing desired products. "
"The class provides functionality to manage a collection of products, "
@ -1037,7 +1036,7 @@ class Wishlist(ExportModelOperationsMixin("wishlist"), NiceModel):
return self
class Documentary(ExportModelOperationsMixin("attribute_group"), NiceModel):
class Documentary(NiceModel):
__doc__ = _(
"Represents a documentary record tied to a product. "
"This class is used to store information about documentaries related to specific "
@ -1068,7 +1067,7 @@ class Documentary(ExportModelOperationsMixin("attribute_group"), NiceModel):
return self.document.name.split(".")[-1] or _("unresolved")
class Address(ExportModelOperationsMixin("address"), NiceModel):
class Address(NiceModel):
__doc__ = _(
"Represents an address entity that includes location details and associations with a user. "
"Provides functionality for geographic and address data storage, as well "
@ -1133,7 +1132,7 @@ class Address(ExportModelOperationsMixin("address"), NiceModel):
return f"{base} for {self.user.email}" if self.user else base
class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel):
class PromoCode(NiceModel):
__doc__ = _(
"Represents a promotional code that can be used for discounts, managing its validity, "
"type of discount, and application. "
@ -1264,7 +1263,7 @@ class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel):
return promo_amount
class Order(ExportModelOperationsMixin("order"), NiceModel):
class Order(NiceModel):
__doc__ = _(
"Represents an order placed by a user."
" This class models an order within the application,"
@ -1834,7 +1833,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel):
return None
class Feedback(ExportModelOperationsMixin("feedback"), NiceModel):
class Feedback(NiceModel):
__doc__ = _(
"Manages user feedback for products. "
"This class is designed to capture and store user feedback for specific products "
@ -1883,7 +1882,7 @@ class Feedback(ExportModelOperationsMixin("feedback"), NiceModel):
verbose_name_plural = _("feedbacks")
class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel):
class OrderProduct(NiceModel):
__doc__ = _(
"Represents products associated with orders and their attributes. "
"The OrderProduct model maintains information about a product that is part of an order, "
@ -2046,9 +2045,7 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel):
return None
class CustomerRelationshipManagementProvider(
ExportModelOperationsMixin("crm_provider"), NiceModel
):
class CustomerRelationshipManagementProvider(NiceModel):
name = CharField(max_length=128, unique=True, verbose_name=_("name"))
integration_url = URLField(
blank=True, null=True, help_text=_("URL of the integration")
@ -2091,7 +2088,7 @@ class CustomerRelationshipManagementProvider(
verbose_name_plural = _("CRMs")
class OrderCrmLink(ExportModelOperationsMixin("order_crm_link"), NiceModel):
class OrderCrmLink(NiceModel):
order = ForeignKey(to=Order, on_delete=PROTECT, related_name="crm_links")
crm = ForeignKey(
to=CustomerRelationshipManagementProvider,
@ -2108,7 +2105,7 @@ class OrderCrmLink(ExportModelOperationsMixin("order_crm_link"), NiceModel):
verbose_name_plural = _("orders CRM links")
class DigitalAssetDownload(ExportModelOperationsMixin("attribute_group"), NiceModel):
class DigitalAssetDownload(NiceModel):
__doc__ = _(
"Represents the downloading functionality for digital assets associated with orders. "
"The DigitalAssetDownload class provides the ability to manage and access "

View file

@ -3,16 +3,6 @@ global:
evaluation_interval: 15s
scrape_configs:
- job_name: 'app'
metrics_path: /prometheus/metrics
scheme: http
static_configs:
- targets: [ 'app:8000' ]
- job_name: 'worker'
static_configs:
- targets: [ 'worker:8888' ]
- job_name: 'database'
static_configs:
- targets: [ 'database_exporter:9187' ]

View file

@ -29,7 +29,6 @@ dependencies = [
"django-md-field==0.1.0",
"django-modeltranslation==0.19.19",
"django-mptt==0.18.0",
"django-prometheus==2.4.1",
"django-redis==6.0.0",
"django-ratelimit==4.1.0",
"django-storages==1.14.6",

View file

@ -108,7 +108,6 @@ UNSAFE_CACHE_KEYS: list[str] = []
SITE_ID: int = 1
INSTALLED_APPS: list[str] = [
"django_prometheus",
"unfold",
"unfold.contrib.filters",
"unfold.contrib.forms",
@ -164,7 +163,6 @@ if DEBUG:
MIDDLEWARE: list[str] = [
"schon.middleware.BlockInvalidHostMiddleware",
"schon.middleware.RateLimitMiddleware",
"django_prometheus.middleware.PrometheusBeforeMiddleware",
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
@ -177,7 +175,6 @@ MIDDLEWARE: list[str] = [
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"schon.middleware.CustomLocaleMiddleware",
"schon.middleware.CamelCaseMiddleWare",
"django_prometheus.middleware.PrometheusAfterMiddleware",
]
if DEBUG:

View file

@ -5,7 +5,7 @@ from schon.settings.base import REDIS_PASSWORD
CACHES = {
"default": {
"BACKEND": "django_prometheus.cache.backends.redis.RedisCache",
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": getenv(
"CELERY_BROKER_URL", f"redis://:{REDIS_PASSWORD}@redis:6379/0"
),

View file

@ -2,7 +2,7 @@ from os import getenv
DATABASES = {
"default": {
"ENGINE": "django_prometheus.db.backends.postgis",
"ENGINE": "django.contrib.gis.db.backends.postgis",
"NAME": getenv("POSTGRES_DB"),
"USER": getenv("POSTGRES_USER"),
"PASSWORD": getenv("POSTGRES_PASSWORD"),

View file

@ -88,7 +88,6 @@ The API supports multiple response formats:
## Health & Monitoring
- Health checks: `/health/`
- Prometheus metrics: `/prometheus/metrics/`
## Version
Current API version: {version}

View file

@ -46,12 +46,6 @@ urlpatterns = [
),
name="health_check",
),
path(
r"prometheus/",
include(
"django_prometheus.urls",
),
),
path(
r"i18n/setlang/",
set_language,

View file

@ -10,7 +10,10 @@ https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
import os
from django.core.wsgi import get_wsgi_application
from opentelemetry.instrumentation.django import DjangoInstrumentor
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "schon.settings")
DjangoInstrumentor().instrument()
application = get_wsgi_application()

15
uv.lock
View file

@ -980,19 +980,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/51/9e/78aad58a90f2e4d0c898eeadd2f2b720bcae29b43676dd37c2b627c4c6c6/django_mptt-0.18.0-py3-none-any.whl", hash = "sha256:bfa3f01627e3966a1df901aeca74570a3e933e66809ebf58d9df673e63627afb", size = 120157, upload-time = "2025-08-26T09:27:02.168Z" },
]
[[package]]
name = "django-prometheus"
version = "2.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
{ name = "prometheus-client" },
]
sdist = { url = "https://files.pythonhosted.org/packages/98/f4/cb39ddd2a41e07a274c4e162c076e906ae232d63b66bbabdea0300878877/django_prometheus-2.4.1.tar.gz", hash = "sha256:073628243d2a6de6a8a8c20e5b512872dfb85d66e1b60b28bcf1eca0155dad95", size = 24464, upload-time = "2025-06-25T15:45:37.149Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/01/50/9c5e022fa92574e5d20606687f15a2aa255e10512a17d11a8216fa117f72/django_prometheus-2.4.1-py2.py3-none-any.whl", hash = "sha256:7fe5af7f7c9ad9cd8a429fe0f3f1bf651f0e244f77162147869eab7ec09cc5e7", size = 29541, upload-time = "2025-06-25T15:45:35.433Z" },
]
[[package]]
name = "django-ratelimit"
version = "4.1.0"
@ -3360,7 +3347,6 @@ dependencies = [
{ name = "django-model-utils" },
{ name = "django-modeltranslation" },
{ name = "django-mptt" },
{ name = "django-prometheus" },
{ name = "django-ratelimit" },
{ name = "django-redis" },
{ name = "django-storages" },
@ -3461,7 +3447,6 @@ requires-dist = [
{ name = "django-model-utils", specifier = "==5.0.0" },
{ name = "django-modeltranslation", specifier = "==0.19.19" },
{ name = "django-mptt", specifier = "==0.18.0" },
{ name = "django-prometheus", specifier = "==2.4.1" },
{ name = "django-ratelimit", specifier = "==4.1.0" },
{ name = "django-redis", specifier = "==6.0.0" },
{ name = "django-storages", specifier = "==1.14.6" },