Reduce polling request log noise
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.32.1 - 2026-05-17
|
||||||
|
|
||||||
|
- Suppressed stdout request logging for routine polling endpoints such as `/api/queue` and `/api/watchlist/refresh-status`, reducing noisy access-log spam during normal browser use.
|
||||||
|
|
||||||
## 0.32.0 - 2026-05-17
|
## 0.32.0 - 2026-05-17
|
||||||
|
|
||||||
- Changed bulk `Refresh All` processing to pace requests with a configurable delay between shows, reducing the chance of flooding upstream episode sources on large watchlists.
|
- Changed bulk `Refresh All` processing to pace requests with a configurable delay between shows, reducing the chance of flooding upstream episode sources on large watchlists.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
A local web UI for a system-wide `ani-cli` install.
|
A local web UI for a system-wide `ani-cli` install.
|
||||||
|
|
||||||
Current version: `0.32.0`
|
Current version: `0.32.1`
|
||||||
|
|
||||||
## Project Layout
|
## Project Layout
|
||||||
|
|
||||||
@@ -159,6 +159,7 @@ The app currently includes:
|
|||||||
- Background `Refresh All` execution with status polling, no inline thumbnail downloads during the bulk job, and a configurable delay between shows to reduce upstream request bursts.
|
- Background `Refresh All` execution with status polling, no inline thumbnail downloads during the bulk job, and a configurable delay between shows to reduce upstream request bursts.
|
||||||
- Optional scheduled background watchlist refreshes with Config page controls for enable/disable and refresh period.
|
- Optional scheduled background watchlist refreshes with Config page controls for enable/disable and refresh period.
|
||||||
- Scheduled background refresh runs now log queue, start, and completion status to stdout so container logs show whether they finished successfully, with errors, or failed.
|
- Scheduled background refresh runs now log queue, start, and completion status to stdout so container logs show whether they finished successfully, with errors, or failed.
|
||||||
|
- Routine browser polling endpoints such as the search-page queue poll and watchlist refresh-status poll now stay quiet in stdout request logs to reduce log spam.
|
||||||
- Search and Watchlist polling now use a shared serial browser polling helper so slow responses do not cause overlapping poll requests to pile up in the background.
|
- Search and Watchlist polling now use a shared serial browser polling helper so slow responses do not cause overlapping poll requests to pile up in the background.
|
||||||
- That shared browser polling helper now also tears itself down on page unload and uses chained `setTimeout` scheduling instead of a bare repeating interval.
|
- That shared browser polling helper now also tears itself down on page unload and uses chained `setTimeout` scheduling instead of a bare repeating interval.
|
||||||
- Controlled shutdown and runtime reset now cancel active download workers when waiting for teardown, reducing the chance of orphaned background downloads outliving the web process.
|
- Controlled shutdown and runtime reset now cancel active download workers when waiting for teardown, reducing the chance of orphaned background downloads outliving the web process.
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ from uuid import uuid4
|
|||||||
PROJECT_ROOT = Path(__file__).resolve().parent
|
PROJECT_ROOT = Path(__file__).resolve().parent
|
||||||
ANI_CLI = os.environ.get("ANI_CLI_BIN") or shutil.which("ani-cli") or "ani-cli"
|
ANI_CLI = os.environ.get("ANI_CLI_BIN") or shutil.which("ani-cli") or "ani-cli"
|
||||||
APP_NAME = "ani-cli-web"
|
APP_NAME = "ani-cli-web"
|
||||||
VERSION = "0.32.0"
|
VERSION = "0.32.1"
|
||||||
ALLANIME_BASE = "allanime.day"
|
ALLANIME_BASE = "allanime.day"
|
||||||
ALLANIME_API = f"https://api.{ALLANIME_BASE}"
|
ALLANIME_API = f"https://api.{ALLANIME_BASE}"
|
||||||
ALLANIME_REFERER = "https://allmanga.to"
|
ALLANIME_REFERER = "https://allmanga.to"
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ def dependency_status():
|
|||||||
class Handler(BaseHTTPRequestHandler):
|
class Handler(BaseHTTPRequestHandler):
|
||||||
server_version = "AniCliWeb/1.0"
|
server_version = "AniCliWeb/1.0"
|
||||||
remote_token_cookie_name = "ani_cli_web_token"
|
remote_token_cookie_name = "ani_cli_web_token"
|
||||||
|
quiet_poll_paths = {"/api/queue", "/api/watchlist/refresh-status"}
|
||||||
|
|
||||||
def _context(self):
|
def _context(self):
|
||||||
context = getattr(self, "handler_context", None) or getattr(type(self), "handler_context", None)
|
context = getattr(self, "handler_context", None) or getattr(type(self), "handler_context", None)
|
||||||
@@ -467,6 +468,9 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
self.error(HTTPStatus.INTERNAL_SERVER_ERROR, "Internal server error.")
|
self.error(HTTPStatus.INTERNAL_SERVER_ERROR, "Internal server error.")
|
||||||
|
|
||||||
def log_message(self, fmt, *args):
|
def log_message(self, fmt, *args):
|
||||||
|
parsed = urlparse(getattr(self, "path", "") or "")
|
||||||
|
if self.command == "GET" and parsed.path in Handler.quiet_poll_paths:
|
||||||
|
return
|
||||||
print(f"{self.address_string()} - {fmt % args}")
|
print(f"{self.address_string()} - {fmt % args}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+22
@@ -1408,6 +1408,28 @@ class HandlerRouteTests(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TemplateHelperTests(unittest.TestCase):
|
class TemplateHelperTests(unittest.TestCase):
|
||||||
|
def test_log_message_skips_queue_poll_requests(self):
|
||||||
|
handler = object.__new__(APP.Handler)
|
||||||
|
handler.path = "/api/queue?page=1&per_page=10"
|
||||||
|
handler.command = "GET"
|
||||||
|
handler.address_string = lambda: "127.0.0.1"
|
||||||
|
|
||||||
|
with mock.patch("builtins.print") as print_mock:
|
||||||
|
APP.Handler.log_message(handler, '"GET /api/queue?page=1&per_page=10 HTTP/1.1" %s -', 200)
|
||||||
|
|
||||||
|
print_mock.assert_not_called()
|
||||||
|
|
||||||
|
def test_log_message_keeps_non_poll_requests(self):
|
||||||
|
handler = object.__new__(APP.Handler)
|
||||||
|
handler.path = "/api/config"
|
||||||
|
handler.command = "GET"
|
||||||
|
handler.address_string = lambda: "127.0.0.1"
|
||||||
|
|
||||||
|
with mock.patch("builtins.print") as print_mock:
|
||||||
|
APP.Handler.log_message(handler, '"GET /api/config HTTP/1.1" %s -', 200)
|
||||||
|
|
||||||
|
print_mock.assert_called_once()
|
||||||
|
|
||||||
def test_page_links_marks_active_page(self):
|
def test_page_links_marks_active_page(self):
|
||||||
markup = APP.render_page_links("config")
|
markup = APP.render_page_links("config")
|
||||||
self.assertIn('class="page-link active" href="/config"', markup)
|
self.assertIn('class="page-link active" href="/config"', markup)
|
||||||
|
|||||||
Reference in New Issue
Block a user