From d398b7a7a034058c7f82f960f37f287fc473df86 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:31:04 +0100 Subject: [PATCH 1/8] disable DisallowedHost message --- config/settings/base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/settings/base.py b/config/settings/base.py index 9ee6e531..15be65f0 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -318,12 +318,17 @@ }, "handlers": { "console": {"class": "logging.StreamHandler", "formatter": "simple"}, + "null": {"class": "logging.NullHandler"}, }, "loggers": { "django": { "handlers": ["console"], "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"), }, + "django.security.DisallowedHost": { + "handlers": ["null"], + "propagate": False, + }, "commands": { "handlers": ["console"], "level": os.getenv("COMMANDS_LOG_LEVEL", "INFO"), From 77767180a575fc62d2ca45d405268e13f0ebfa69 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:33:28 +0100 Subject: [PATCH 2/8] use logger in management commands --- .../commands/add_user_to_list_when_register.py | 7 ++++++- .../commands/send_messages_notifications.py | 11 +++++++---- .../commands/send_notifs_on_unanswered_topics.py | 7 ++++++- .../stats/management/commands/collect_django_stats.py | 9 +++++++-- .../stats/management/commands/collect_events.py | 9 ++++++--- .../management/commands/collect_matomo_forum_stats.py | 6 +++++- .../stats/management/commands/collect_matomo_stats.py | 5 ++++- .../management/commands/compute_answering_delay.py | 9 ++++++--- lacommunaute/stats/tests/tests_management_commands.py | 5 ++--- 9 files changed, 49 insertions(+), 19 deletions(-) diff --git a/lacommunaute/notification/management/commands/add_user_to_list_when_register.py b/lacommunaute/notification/management/commands/add_user_to_list_when_register.py index 6b950bca..068e5c34 100644 --- a/lacommunaute/notification/management/commands/add_user_to_list_when_register.py +++ b/lacommunaute/notification/management/commands/add_user_to_list_when_register.py @@ -1,11 +1,16 @@ +from logging import getLogger + from django.core.management.base import BaseCommand from lacommunaute.notification.tasks import add_user_to_list_when_register +logger = getLogger("commands") + + class Command(BaseCommand): help = "Ajouter un utilisateur à une liste Sendinblue quand il s'inscrit" def handle(self, *args, **options): add_user_to_list_when_register() - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/notification/management/commands/send_messages_notifications.py b/lacommunaute/notification/management/commands/send_messages_notifications.py index 68466f26..0fba8782 100644 --- a/lacommunaute/notification/management/commands/send_messages_notifications.py +++ b/lacommunaute/notification/management/commands/send_messages_notifications.py @@ -1,9 +1,14 @@ +from logging import getLogger + from django.core.management.base import BaseCommand from lacommunaute.notification.enums import NotificationDelay from lacommunaute.notification.tasks import send_messages_notifications, send_missyou_notifications +logger = getLogger("commands") + + class Command(BaseCommand): help = "Envoyer les notifications en file d'attente avec le délai paramétré" @@ -14,10 +19,8 @@ def handle(self, *args, **options): try: delay = NotificationDelay(options["delay"]) except ValueError: - self.stdout.write( - self.style.ERROR(f"le délai fournit doit être un valeuer de {str(NotificationDelay.values)}") - ) + logger.error("le délai fournit doit être un valeuer de %s", str(NotificationDelay.values)) send_messages_notifications(delay) send_missyou_notifications(delay) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/notification/management/commands/send_notifs_on_unanswered_topics.py b/lacommunaute/notification/management/commands/send_notifs_on_unanswered_topics.py index 99f2207e..65e148b4 100644 --- a/lacommunaute/notification/management/commands/send_notifs_on_unanswered_topics.py +++ b/lacommunaute/notification/management/commands/send_notifs_on_unanswered_topics.py @@ -1,11 +1,16 @@ +from logging import getLogger + from django.core.management.base import BaseCommand from lacommunaute.notification.tasks import send_notifs_on_unanswered_topics +logger = getLogger("commands") + + class Command(BaseCommand): help = "Envoyer une notification par email aux utilisateurs volontaires quand il y a des sujets sans réponse" def handle(self, *args, **options): send_notifs_on_unanswered_topics() - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/management/commands/collect_django_stats.py b/lacommunaute/stats/management/commands/collect_django_stats.py index 7774dcdc..79b6f25b 100644 --- a/lacommunaute/stats/management/commands/collect_django_stats.py +++ b/lacommunaute/stats/management/commands/collect_django_stats.py @@ -1,12 +1,17 @@ +from logging import getLogger + from django.core.management.base import BaseCommand from lacommunaute.surveys.stats import collect_dsp_stats +logger = getLogger("commands") + + class Command(BaseCommand): help = "Collecter les stats django, jusqu'à la veille de l'execution" def handle(self, *args, **options): from_date, count = collect_dsp_stats() - self.stdout.write(self.style.SUCCESS(f"Collecting DSP stats from {from_date} to yesterday: {count} new stats")) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("Collecting DSP stats from %s to yesterday: %s new stats", from_date, count) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/management/commands/collect_events.py b/lacommunaute/stats/management/commands/collect_events.py index 9973e708..2748e2bd 100644 --- a/lacommunaute/stats/management/commands/collect_events.py +++ b/lacommunaute/stats/management/commands/collect_events.py @@ -1,8 +1,8 @@ # vincenporte ~ assumed quick'n'dirty solution # TODO: refactor it code base and test it - import json from datetime import datetime +from logging import getLogger from dateutil.relativedelta import relativedelta from django.core.management.base import BaseCommand @@ -15,6 +15,9 @@ from lacommunaute.utils.matomo import get_matomo_data +logger = getLogger("commands") + + def save_to_json(stats, period): with open(f"exports/{period}ly_events.json", "w") as f: json.dump(stats, f) @@ -93,10 +96,10 @@ def handle(self, *args, **options): ("month", timezone.make_aware(datetime(2023, 1, 1), timezone.get_current_timezone())), ("week", timezone.make_aware(datetime(2023, 1, 2), timezone.get_current_timezone())), ): - self.stdout.write(f"Collecting {period}ly events from {search_date}") + logger.info("Collecting %sly events from %s", period, search_date) stats = [] stats = collect_matomo_events(period, search_date, stats) stats = collect_db_events(period, search_date, stats) save_to_json(stats, period) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/management/commands/collect_matomo_forum_stats.py b/lacommunaute/stats/management/commands/collect_matomo_forum_stats.py index 009de28d..ea41477e 100644 --- a/lacommunaute/stats/management/commands/collect_matomo_forum_stats.py +++ b/lacommunaute/stats/management/commands/collect_matomo_forum_stats.py @@ -1,4 +1,5 @@ from datetime import date +from logging import getLogger from dateutil.relativedelta import relativedelta from django.core.management.base import BaseCommand @@ -8,6 +9,9 @@ from lacommunaute.utils.matomo import collect_forum_stats_from_matomo_api +logger = getLogger("commands") + + class Command(BaseCommand): help = "Collecter les stats des forum dans matomo, jusqu'au dimanche précédent l'execution" @@ -25,4 +29,4 @@ def handle(self, *args, **options): collect_forum_stats_from_matomo_api(from_date=from_date, to_date=to_date, period=period) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/management/commands/collect_matomo_stats.py b/lacommunaute/stats/management/commands/collect_matomo_stats.py index 75da1a96..f6c81a7c 100644 --- a/lacommunaute/stats/management/commands/collect_matomo_stats.py +++ b/lacommunaute/stats/management/commands/collect_matomo_stats.py @@ -1,4 +1,5 @@ from datetime import date +from logging import getLogger from dateutil.relativedelta import relativedelta from django.core.management.base import BaseCommand @@ -7,6 +8,8 @@ from lacommunaute.utils.matomo import collect_stats_from_matomo_api +logger = getLogger("commands") + matomo_stats_names = [ "nb_uniq_visitors", "nb_uniq_visitors_returning", @@ -44,4 +47,4 @@ def handle(self, *args, **options): collect_stats_from_matomo_api(from_date=from_date, to_date=to_date, period=period) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/management/commands/compute_answering_delay.py b/lacommunaute/stats/management/commands/compute_answering_delay.py index 172c147d..b8f61cbb 100644 --- a/lacommunaute/stats/management/commands/compute_answering_delay.py +++ b/lacommunaute/stats/management/commands/compute_answering_delay.py @@ -1,7 +1,7 @@ # vincenporte ~ untested code # TODO: refactor it code base and test it - from datetime import timedelta +from logging import getLogger from typing import Dict from django.core.management.base import BaseCommand @@ -12,6 +12,9 @@ from lacommunaute.forum_conversation.models import Post, Topic +logger = getLogger("commands") + + def get_answered_topics_of_a_month(month: int, year: int) -> QuerySet: related_posts = Post.objects.filter(topic=OuterRef("pk")).order_by("created") return Topic.objects.filter( @@ -54,5 +57,5 @@ def handle(self, *args, **options): year = options["year"] values = min_median_max_values(get_answered_topics_of_a_month(month, year), "time_diff_seconds") - self.stdout.write(self.style.SUCCESS(f"{month}/{year}: {values}")) - self.stdout.write(self.style.SUCCESS("That's all, folks!")) + logger.info("%s/%s: %s", month, year, values) + logger.info("That's all, folks!") diff --git a/lacommunaute/stats/tests/tests_management_commands.py b/lacommunaute/stats/tests/tests_management_commands.py index 1457b8be..ce744339 100644 --- a/lacommunaute/stats/tests/tests_management_commands.py +++ b/lacommunaute/stats/tests/tests_management_commands.py @@ -6,12 +6,11 @@ from lacommunaute.surveys.factories import DSPFactory -def test_collect_django_stats(db, capsys): +def test_collect_django_stats(db, caplog): DSPFactory() StatFactory(for_dsp_snapshot=True) call_command("collect_django_stats") - captured = capsys.readouterr() - assert captured.out.strip() == "Collecting DSP stats from 2024-05-18 to yesterday: 1 new stats\nThat's all, folks!" + assert "Collecting DSP stats from 2024-05-18 to yesterday: 1 new stats" in caplog.text @pytest.mark.parametrize( From 31d9acc2f0775b24fa45116447dc3a886905a460 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:34:52 +0100 Subject: [PATCH 3/8] use lacommunaute logger in views --- config/settings/base.py | 4 ++++ lacommunaute/event/views.py | 4 ++-- lacommunaute/forum/views.py | 4 ++-- lacommunaute/forum_conversation/forum_polls/views.py | 4 ++-- lacommunaute/forum_conversation/views.py | 4 ++-- lacommunaute/forum_conversation/views_htmx.py | 4 ++-- lacommunaute/forum_member/views.py | 4 ++-- lacommunaute/forum_moderation/views.py | 5 +++++ lacommunaute/forum_upvote/views.py | 4 ++-- lacommunaute/openid_connect/views.py | 4 ++-- lacommunaute/pages/views.py | 4 ++-- lacommunaute/partner/views.py | 5 +++++ lacommunaute/search/views.py | 5 +++++ lacommunaute/stats/views.py | 4 ++-- lacommunaute/surveys/views.py | 5 +++++ lacommunaute/users/views.py | 4 ++-- 16 files changed, 46 insertions(+), 22 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index 15be65f0..df3c3811 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -329,6 +329,10 @@ "handlers": ["null"], "propagate": False, }, + "lacommunaute": { + "handlers": ["console"], + "level": os.getenv("LACOMMUNAUTE_LOG_LEVEL", "INFO"), + }, "commands": { "handlers": ["console"], "level": os.getenv("COMMANDS_LOG_LEVEL", "INFO"), diff --git a/lacommunaute/event/views.py b/lacommunaute/event/views.py index 91143afc..ecb6e584 100644 --- a/lacommunaute/event/views.py +++ b/lacommunaute/event/views.py @@ -1,5 +1,5 @@ -import logging from datetime import datetime +from logging import getLogger from django.contrib.auth.mixins import LoginRequiredMixin from django.core.exceptions import PermissionDenied @@ -14,7 +14,7 @@ from lacommunaute.event.models import Event -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") class SuccessUrlMixin: diff --git a/lacommunaute/forum/views.py b/lacommunaute/forum/views.py index 322336b6..5dd730e8 100644 --- a/lacommunaute/forum/views.py +++ b/lacommunaute/forum/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.conf import settings from django.contrib.auth.mixins import UserPassesTestMixin @@ -24,7 +24,7 @@ ) -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") PermissionRequiredMixin = get_class("forum_permission.viewmixins", "PermissionRequiredMixin") diff --git a/lacommunaute/forum_conversation/forum_polls/views.py b/lacommunaute/forum_conversation/forum_polls/views.py index 11b4583f..e857d153 100644 --- a/lacommunaute/forum_conversation/forum_polls/views.py +++ b/lacommunaute/forum_conversation/forum_polls/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.template.response import TemplateResponse from machina.apps.forum_conversation.forum_polls.views import TopicPollVoteView as BaseTopicPollVoteView @@ -6,7 +6,7 @@ from machina.core.loading import get_class -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") Topic = get_model("forum_conversation", "Topic") TopicPollVote = get_model("forum_polls", "TopicPollVote") diff --git a/lacommunaute/forum_conversation/views.py b/lacommunaute/forum_conversation/views.py index def06aa9..e4f4f83c 100644 --- a/lacommunaute/forum_conversation/views.py +++ b/lacommunaute/forum_conversation/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.conf import settings from django.contrib import messages @@ -15,7 +15,7 @@ from lacommunaute.notification.models import Notification -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") TrackingHandler = get_class("forum_tracking.handler", "TrackingHandler") track_handler = TrackingHandler() diff --git a/lacommunaute/forum_conversation/views_htmx.py b/lacommunaute/forum_conversation/views_htmx.py index ff228a53..45d47e71 100644 --- a/lacommunaute/forum_conversation/views_htmx.py +++ b/lacommunaute/forum_conversation/views_htmx.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.shortcuts import get_object_or_404, render from django.views import View @@ -10,7 +10,7 @@ from lacommunaute.notification.models import Notification -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") PermissionRequiredMixin = get_class("forum_permission.viewmixins", "PermissionRequiredMixin") TrackingHandler = get_class("forum_tracking.handler", "TrackingHandler") diff --git a/lacommunaute/forum_member/views.py b/lacommunaute/forum_member/views.py index 3469110e..4deeb722 100644 --- a/lacommunaute/forum_member/views.py +++ b/lacommunaute/forum_member/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.urls import reverse from django.views.generic import ListView @@ -12,7 +12,7 @@ from lacommunaute.forum_member.models import ForumProfile -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") PermissionRequiredMixin = get_class("forum_permission.viewmixins", "PermissionRequiredMixin") diff --git a/lacommunaute/forum_moderation/views.py b/lacommunaute/forum_moderation/views.py index f7c4e812..682fdaaa 100644 --- a/lacommunaute/forum_moderation/views.py +++ b/lacommunaute/forum_moderation/views.py @@ -1,3 +1,5 @@ +from logging import getLogger + from django.contrib import messages from django.urls import reverse from machina.apps.forum_moderation.views import ( @@ -9,6 +11,9 @@ from lacommunaute.forum_moderation.models import BlockedEmail, BlockedPost +logger = getLogger("lacommunaute") + + class TopicDeleteView(BaseTopicDeleteView): def get_success_url(self): messages.success(self.request, self.success_message) diff --git a/lacommunaute/forum_upvote/views.py b/lacommunaute/forum_upvote/views.py index 62249868..3d1e4f86 100644 --- a/lacommunaute/forum_upvote/views.py +++ b/lacommunaute/forum_upvote/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin @@ -13,7 +13,7 @@ from lacommunaute.forum_upvote.models import UpVote -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") PermissionRequiredMixin = get_class("forum_permission.viewmixins", "PermissionRequiredMixin") TrackingHandler = get_class("forum_tracking.handler", "TrackingHandler") diff --git a/lacommunaute/openid_connect/views.py b/lacommunaute/openid_connect/views.py index fae71fb2..07963cbf 100644 --- a/lacommunaute/openid_connect/views.py +++ b/lacommunaute/openid_connect/views.py @@ -1,5 +1,5 @@ import dataclasses -import logging +from logging import getLogger import httpx import jwt @@ -14,7 +14,7 @@ from lacommunaute.openid_connect.models import OIDConnectUserData, OpenID_State -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") @dataclasses.dataclass diff --git a/lacommunaute/pages/views.py b/lacommunaute/pages/views.py index 228a88b0..669ebd54 100644 --- a/lacommunaute/pages/views.py +++ b/lacommunaute/pages/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from typing import Any from django.contrib.auth.mixins import UserPassesTestMixin @@ -12,7 +12,7 @@ from lacommunaute.forum_conversation.models import Topic -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") class LandingPagesListView(UserPassesTestMixin, TemplateView): diff --git a/lacommunaute/partner/views.py b/lacommunaute/partner/views.py index a1cb3389..7de5e271 100644 --- a/lacommunaute/partner/views.py +++ b/lacommunaute/partner/views.py @@ -1,3 +1,5 @@ +from logging import getLogger + from django.contrib.auth.mixins import UserPassesTestMixin from django.urls import reverse from django.views.generic import CreateView, DetailView, ListView, UpdateView @@ -8,6 +10,9 @@ from lacommunaute.utils.perms import forum_visibility_content_tree_from_forums +logger = getLogger("lacommunaute") + + class PartnerListView(ListView): model = Partner template_name = "partner/list.html" diff --git a/lacommunaute/search/views.py b/lacommunaute/search/views.py index 4787f25e..7c298a37 100644 --- a/lacommunaute/search/views.py +++ b/lacommunaute/search/views.py @@ -1,3 +1,5 @@ +from logging import getLogger + from django.contrib.postgres.search import SearchHeadline, SearchQuery, SearchRank from django.db.models import F from django.views.generic import ListView @@ -9,6 +11,9 @@ from lacommunaute.search.models import CommonIndex +logger = getLogger("lacommunaute") + + class SearchView(FormMixin, ListView): model = CommonIndex form_class = SearchForm diff --git a/lacommunaute/stats/views.py b/lacommunaute/stats/views.py index 80d65f6f..46d035c6 100644 --- a/lacommunaute/stats/views.py +++ b/lacommunaute/stats/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from dateutil.relativedelta import relativedelta from django.db.models import Avg, CharField, Count, OuterRef, Subquery, Sum @@ -16,7 +16,7 @@ from lacommunaute.utils.math import percent -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") def get_daily_visits_stats(from_date, to_date): diff --git a/lacommunaute/surveys/views.py b/lacommunaute/surveys/views.py index 8682ed51..ce4cfdaa 100644 --- a/lacommunaute/surveys/views.py +++ b/lacommunaute/surveys/views.py @@ -1,3 +1,5 @@ +from logging import getLogger + from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy @@ -9,6 +11,9 @@ from lacommunaute.surveys.models import DSP +logger = getLogger("lacommunaute") + + class DSPCreateView(CreateView): model = DSP template_name = "surveys/dsp_form.html" diff --git a/lacommunaute/users/views.py b/lacommunaute/users/views.py index 7feee8ec..2659391e 100644 --- a/lacommunaute/users/views.py +++ b/lacommunaute/users/views.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from urllib.parse import urlencode from django.conf import settings @@ -24,7 +24,7 @@ from lacommunaute.utils.urls import clean_next_url -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") def send_magic_link(request, user, next_url): From f8871c6505b09f69e12eeb7bdc8f22c05b6f5eeb Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:39:24 +0100 Subject: [PATCH 4/8] strengthen management command test --- lacommunaute/stats/tests/tests_management_commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lacommunaute/stats/tests/tests_management_commands.py b/lacommunaute/stats/tests/tests_management_commands.py index ce744339..c058812a 100644 --- a/lacommunaute/stats/tests/tests_management_commands.py +++ b/lacommunaute/stats/tests/tests_management_commands.py @@ -3,6 +3,7 @@ from lacommunaute.stats.factories import StatFactory from lacommunaute.stats.management.commands.collect_matomo_stats import get_initial_from_date +from lacommunaute.stats.models import Stat from lacommunaute.surveys.factories import DSPFactory @@ -11,6 +12,7 @@ def test_collect_django_stats(db, caplog): StatFactory(for_dsp_snapshot=True) call_command("collect_django_stats") assert "Collecting DSP stats from 2024-05-18 to yesterday: 1 new stats" in caplog.text + assert Stat.objects.count() == 2 @pytest.mark.parametrize( From 7e5bf71bda33790b2ad954b651fa66339a0d5230 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:39:34 +0100 Subject: [PATCH 5/8] use lacommunaute logger in emails : method called either in views and management command --- lacommunaute/notification/emails.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lacommunaute/notification/emails.py b/lacommunaute/notification/emails.py index 67ffcc18..00a67d0c 100644 --- a/lacommunaute/notification/emails.py +++ b/lacommunaute/notification/emails.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from urllib.parse import urljoin import httpx @@ -9,7 +9,7 @@ from lacommunaute.utils.enums import Environment -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") SIB_SMTP_URL = urljoin(settings.SIB_URL, settings.SIB_SMTP_ROUTE) SIB_CONTACTS_URL = urljoin(settings.SIB_URL, settings.SIB_CONTACTS_ROUTE) From b634852afdd0ad73f13603058b71540b1311d8df Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:40:02 +0100 Subject: [PATCH 6/8] use lacommunaute logger in middleware --- lacommunaute/users/middleware.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lacommunaute/users/middleware.py b/lacommunaute/users/middleware.py index c80c31e2..b9ca2a7c 100644 --- a/lacommunaute/users/middleware.py +++ b/lacommunaute/users/middleware.py @@ -1,4 +1,4 @@ -import logging +from logging import getLogger from django.utils.deprecation import MiddlewareMixin @@ -6,7 +6,7 @@ from lacommunaute.users.models import EmailLastSeen -logger = logging.getLogger(__name__) +logger = getLogger("lacommunaute") class MarkAsSeenLoggedUserMiddleware(MiddlewareMixin): From 07e2e97472b84133a85fcce6c23d421f9157de4c Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 14:54:59 +0100 Subject: [PATCH 7/8] switch from simple formatter to json formatter --- config/settings/base.py | 8 +++----- pyproject.toml | 1 + uv.lock | 12 ++++++++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/config/settings/base.py b/config/settings/base.py index df3c3811..9bde2d49 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,6 +1,7 @@ import os from dotenv import load_dotenv +from json_log_formatter import JSONFormatter from machina import MACHINA_MAIN_STATIC_DIR, MACHINA_MAIN_TEMPLATE_DIR @@ -311,13 +312,10 @@ "version": 1, "disable_existing_loggers": False, "formatters": { - "simple": { - "format": "{levelname} {asctime} {pathname} : {message}", - "style": "{", - }, + "json": {"()": JSONFormatter}, }, "handlers": { - "console": {"class": "logging.StreamHandler", "formatter": "simple"}, + "console": {"class": "logging.StreamHandler", "formatter": "json"}, "null": {"class": "logging.NullHandler"}, }, "loggers": { diff --git a/pyproject.toml b/pyproject.toml index 84230e21..a302c46c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "django-permissions-policy>=4.24", "langdetect>=1.0.9", "pyjwt>=2.10", + "json-log-formatter>=1.1", ] [dependency-groups] diff --git a/uv.lock b/uv.lock index 79a124ff..615d4414 100644 --- a/uv.lock +++ b/uv.lock @@ -671,6 +671,12 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/69/3e/dd37e1a7223247e3ef94714abf572415b89c4e121c4af48e9e4c392e2ca0/jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24", size = 75606 } +[[package]] +name = "json-log-formatter" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/34/02eee63c3871b9f3ea340f58d0675dae8d9cc95a8a961f379f5a1b325911/json_log_formatter-1.1.tar.gz", hash = "sha256:fe8fd801c58c1234df86211720921f60149105ef8d1e2a72966bb61da9bed584", size = 5858 } + [[package]] name = "json5" version = "0.10.0" @@ -682,7 +688,7 @@ wheels = [ [[package]] name = "lacommunaute" -version = "2.20.0" +version = "2.21.0" source = { virtual = "." } dependencies = [ { name = "boto3" }, @@ -697,6 +703,7 @@ dependencies = [ { name = "django-storages" }, { name = "django-taggit" }, { name = "httpx" }, + { name = "json-log-formatter" }, { name = "langdetect" }, { name = "psycopg" }, { name = "pyjwt" }, @@ -730,7 +737,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "boto3", specifier = "==1.35.99" }, + { name = "boto3", specifier = "<1.36" }, { name = "django", specifier = ">=5.1" }, { name = "django-compressor", specifier = ">=4.5" }, { name = "django-csp", specifier = ">=3.8" }, @@ -742,6 +749,7 @@ requires-dist = [ { name = "django-storages", specifier = ">=1.14" }, { name = "django-taggit", specifier = ">=6.1" }, { name = "httpx", specifier = ">=0.28" }, + { name = "json-log-formatter", specifier = ">=1.1" }, { name = "langdetect", specifier = ">=1.0.9" }, { name = "psycopg", specifier = ">=3.2" }, { name = "pyjwt", specifier = ">=2.10" }, From 53bed8292631c668a23a24ce7d638a2e8b017771 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 25 Feb 2025 20:14:27 +0100 Subject: [PATCH 8/8] add info in views logger (tests in progress) --- config/settings/base.py | 5 +++-- lacommunaute/forum_conversation/views.py | 1 + lacommunaute/utils/loggers.py | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 lacommunaute/utils/loggers.py diff --git a/config/settings/base.py b/config/settings/base.py index 9bde2d49..4b1e5921 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,9 +1,10 @@ import os from dotenv import load_dotenv -from json_log_formatter import JSONFormatter from machina import MACHINA_MAIN_STATIC_DIR, MACHINA_MAIN_TEMPLATE_DIR +from lacommunaute.utils.loggers import CustomJsonFormatter + load_dotenv() @@ -312,7 +313,7 @@ "version": 1, "disable_existing_loggers": False, "formatters": { - "json": {"()": JSONFormatter}, + "json": {"()": CustomJsonFormatter}, }, "handlers": { "console": {"class": "logging.StreamHandler", "formatter": "json"}, diff --git a/lacommunaute/forum_conversation/views.py b/lacommunaute/forum_conversation/views.py index e4f4f83c..101d9b4e 100644 --- a/lacommunaute/forum_conversation/views.py +++ b/lacommunaute/forum_conversation/views.py @@ -26,6 +26,7 @@ def form_valid(self, *args, **kwargs): valid = super().form_valid(*args, **kwargs) track_handler.mark_topic_read(self.forum_post.topic, self.request.user) + logger.info("form is valid", extra={"context": self}) return valid diff --git a/lacommunaute/utils/loggers.py b/lacommunaute/utils/loggers.py new file mode 100644 index 00000000..7cafbdde --- /dev/null +++ b/lacommunaute/utils/loggers.py @@ -0,0 +1,19 @@ +from json_log_formatter import JSONFormatter + + +class CustomJsonFormatter(JSONFormatter): + def json_record(self, message, extra, record): + extra["logger_name"] = record.name + + if "context" in extra: + context = extra.pop("context") + if hasattr(context, "request"): + extra = extra | { + "view": context.request.resolver_match.view_name, + "kwargs": context.request.resolver_match.kwargs, + "method": context.request.method, + "user_id": context.request.user.id if context.request.user.is_authenticated else None, + "session_key": context.request.session.session_key, + } + + return super().json_record(message, extra, record)