(feature) Add focused filtering to the service logs view

Extend the Django logs view with filters for service unit, severity, time
window, host, run id, and message text. Pass severity and time window directly
to journalctl, then apply host/run/message filtering to the returned pobsync
journal lines.

This makes failed or slow backups easier to investigate from the control panel
without needing shell access.
This commit is contained in:
2026-05-21 00:24:07 +02:00
parent 98695f9888
commit a9e40df44b
3 changed files with 86 additions and 8 deletions

View File

@@ -150,21 +150,41 @@ class ViewTests(TestCase):
completed = subprocess.CompletedProcess(
args=["journalctl"],
returncode=0,
stdout="2026-05-19 pobsync-worker.service failed backup\n2026-05-19 pobsync-web.service started\n",
stdout=(
"2026-05-19 pobsync-worker.service web-01 failed backup run 12\n"
"2026-05-19 pobsync-worker.service web-02 failed backup run 12\n"
"2026-05-19 pobsync-web.service web-01 started run 12\n"
),
stderr="",
)
with patch("pobsync_backend.views.shutil.which", return_value="/usr/bin/journalctl"), patch(
"pobsync_backend.views.subprocess.run", return_value=completed
) as run:
response = self.client.get(reverse("logs"), {"unit": "pobsync-worker.service", "priority": "0..3", "q": "failed"})
response = self.client.get(
reverse("logs"),
{
"unit": "pobsync-worker.service",
"priority": "0..3",
"window": "6h",
"host": "web-01",
"run": "12",
"q": "failed",
},
)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Logs")
self.assertContains(response, "failed backup")
self.assertContains(response, "web-01 failed backup run 12")
self.assertNotContains(response, "web-02 failed backup run 12")
self.assertNotContains(response, "started")
self.assertIn("-u", run.call_args.args[0])
self.assertIn("pobsync-worker.service", run.call_args.args[0])
command = run.call_args.args[0]
self.assertIn("-u", command)
self.assertIn("pobsync-worker.service", command)
self.assertIn("-p", command)
self.assertIn("0..3", command)
self.assertIn("--since", command)
self.assertIn("6 hours ago", command)
def test_ssh_credentials_view_creates_key(self) -> None:
self.client.force_login(self.staff_user)