From 38e64140ed0e1f52a62117c4c0b0be61fd6d874f Mon Sep 17 00:00:00 2001 From: JakeBreath Date: Thu, 17 Sep 2026 21:50:20 -0500 Subject: [PATCH] Serve /health and keep 404 scanner noise out of the log file Something on the network polls /health (and /v1/models) every 30 seconds; the former now answers 200 with a database check instead of a 404, and django.request is limited to ERROR in the logging config so scanner 404s stop filling backend/logs/j621.log. Real server errors still log, and the dev server keeps printing every request to its console. --- backend/apps/core/views.py | 20 ++++++++++++++++++++ backend/config/settings.py | 10 ++++++++++ backend/config/urls.py | 5 +++++ 3 files changed, 35 insertions(+) diff --git a/backend/apps/core/views.py b/backend/apps/core/views.py index 507610a..8c34d33 100644 --- a/backend/apps/core/views.py +++ b/backend/apps/core/views.py @@ -1,6 +1,7 @@ import time from django.conf import settings +from django.db import connection from rest_framework.exceptions import PermissionDenied from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.response import Response @@ -66,3 +67,22 @@ class StatsView(APIView): "log": stats.log_tail(), } ) + + +class HealthView(APIView): + """Unauthenticated liveness probe for uptime monitors (hits /health).""" + + permission_classes = [AllowAny] + authentication_classes = [] + + def get(self, request): + database = True + try: + with connection.cursor() as cursor: + cursor.execute("SELECT 1") + except Exception: # noqa: BLE001 - report the failure, do not crash + database = False + return Response( + {"status": "ok" if database else "degraded", "database": database}, + status=200 if database else 503, + ) diff --git a/backend/config/settings.py b/backend/config/settings.py index 0579c34..5342244 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -238,6 +238,16 @@ LOGGING = { }, }, "handlers": _log_handlers, + "loggers": { + # Scanners on the network probe things like /health and /v1/models; + # their 404s are noise in the log file. Real server errors (5xx) still + # log, and the dev server keeps printing every request to the console. + "django.request": { + "handlers": _root_handlers, + "level": "ERROR", + "propagate": False, + }, + }, "root": { "handlers": _root_handlers, "level": "INFO", diff --git a/backend/config/urls.py b/backend/config/urls.py index 2a376cb..11f7b42 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -3,6 +3,8 @@ from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path +from apps.core.views import HealthView + urlpatterns = [ path("admin/", admin.site.urls), path("api/auth/", include("apps.accounts.urls")), @@ -10,6 +12,9 @@ urlpatterns = [ path("api/", include("apps.core.urls")), path("api/", include("apps.library.urls")), path("api/", include("apps.follows.urls")), + # Liveness probe for uptime monitors (no /api prefix, no auth). + path("health", HealthView.as_view(), name="health"), + path("health/", HealthView.as_view()), ] if settings.DEBUG: