| from __future__ import annotations |
|
|
| import logging |
| import os |
|
|
|
|
| SCANNER_PATH_PREFIXES = ( |
| "/.env", |
| "/.git", |
| "/.streamlit", |
| "/_debug", |
| "/_profiler", |
| "/_stcore", |
| "/actuator", |
| "/admin", |
| "/api/config", |
| "/api/credentials", |
| "/api/env", |
| "/api/keys", |
| "/api/predict", |
| "/api/queue/status", |
| "/api/secrets", |
| "/api/settings", |
| "/api/v1/", |
| "/api-docs", |
| "/app.py", |
| "/backup/", |
| "/config", |
| "/debug", |
| "/docs", |
| "/elmah", |
| "/file", |
| "/graphql", |
| "/horizon", |
| "/info", |
| "/internal", |
| "/main.py", |
| "/manifest.json", |
| "/metrics", |
| "/openapi.json", |
| "/phpinfo", |
| "/proc/", |
| "/prometheus", |
| "/redoc", |
| "/run/predict", |
| "/server-", |
| "/settings", |
| "/swagger", |
| "/telescope", |
| "/trace", |
| "/upload?upload_id=", |
| "/wp-config", |
| "/__phpinfo", |
| ) |
|
|
|
|
| class ScannerNoiseFilter(logging.Filter): |
| def filter(self, record: logging.LogRecord) -> bool: |
| try: |
| path = str(record.args[2]).lower() |
| status_code = int(record.args[4]) |
| except (IndexError, TypeError, ValueError): |
| return True |
|
|
| if status_code not in {404, 405}: |
| return True |
| return not path.startswith(SCANNER_PATH_PREFIXES) |
|
|
|
|
| def install_access_log_filter() -> None: |
| enabled = os.getenv("SUPPRESS_SCANNER_ACCESS_LOGS", "true").lower() in { |
| "1", |
| "true", |
| "yes", |
| } |
| if not enabled: |
| return |
|
|
| logger = logging.getLogger("uvicorn.access") |
| if not any(isinstance(item, ScannerNoiseFilter) for item in logger.filters): |
| logger.addFilter(ScannerNoiseFilter()) |
|
|