Skip to content

Commit 4250db0

Browse files
committed
Add per-response access log control and suppress noisy asset 304s
1 parent 9fadf8b commit 4250db0

File tree

4 files changed

+17
-7
lines changed

4 files changed

+17
-7
lines changed

plain/plain/assets/views.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,7 @@ def get_conditional_response(self, path: str) -> NotModifiedResponse | None:
280280
Support conditional requests (HTTP 304 response) based on ETag and Last-Modified headers.
281281
"""
282282
if self.request.headers.get("If-None-Match") == self.get_etag(path):
283-
response = NotModifiedResponse()
284-
response.headers = self.update_headers(response.headers, path)
285-
return response
283+
return self._not_modified_response(path)
286284

287285
if "If-Modified-Since" in self.request.headers:
288286
if_modified_since = parsedate(self.request.headers["If-Modified-Since"])
@@ -292,11 +290,16 @@ def get_conditional_response(self, path: str) -> NotModifiedResponse | None:
292290
and last_modified
293291
and if_modified_since >= last_modified
294292
):
295-
response = NotModifiedResponse()
296-
response.headers = self.update_headers(response.headers, path)
297-
return response
293+
return self._not_modified_response(path)
298294
return None
299295

296+
def _not_modified_response(self, path: str) -> NotModifiedResponse:
297+
response = NotModifiedResponse()
298+
response.headers = self.update_headers(response.headers, path)
299+
if not settings.ASSETS_LOG_304:
300+
response.log_access = False
301+
return response
302+
300303
def get_range_response(self, path: str) -> Response | StreamingResponse | None:
301304
"""
302305
Support range requests (HTTP 206 response).

plain/plain/http/response.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ def __init__(
151151
self._reason_phrase = reason
152152
# Exception that caused this response, if any (primarily for 500 errors)
153153
self.exception: Exception | None = None
154+
# Whether the server should log this response in the access log
155+
self.log_access: bool = True
154156

155157
@property
156158
def reason_phrase(self) -> str:

plain/plain/runtime/global_settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@
168168
# Ex. "https://cdn.example.com/assets/"
169169
ASSETS_CDN_URL: str = ""
170170

171+
# Whether to log 304 Not Modified responses for assets in the access log.
172+
# Disabled by default to reduce noise from conditional requests.
173+
ASSETS_LOG_304: bool = False
174+
171175
# MARK: Server
172176

173177
SERVER_WORKERS: int = int(os.environ.get("WEB_CONCURRENCY", 0)) # 0 = auto (CPU count)

plain/plain/server/workers/thread.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ def handle_request(self, req: Any, conn: TConn) -> bool:
379379
resp.write_response(http_response)
380380
finally:
381381
request_time = datetime.now() - request_start
382-
self.log.access(resp, req, request_time)
382+
if http_response.log_access:
383+
self.log.access(resp, req, request_time)
383384
if hasattr(http_response, "close"):
384385
http_response.close()
385386

0 commit comments

Comments
 (0)