Spaces:
Running
Running
Update hub_dashboard_service.py
Browse files- hub_dashboard_service.py +83 -20
hub_dashboard_service.py
CHANGED
|
@@ -4,11 +4,13 @@
|
|
| 4 |
β K1RL QUASAR β HUB DASHBOARD SERVICE (with Trade Log Parser) β FIXED v2.5 β
|
| 5 |
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
| 6 |
β Architecture role: READ-ONLY subscriber β serves dashboard UI β
|
| 7 |
-
β VERSION: v2.5 (PORT FIX) | 2026-04-04
|
| 8 |
β β
|
| 9 |
β FIXES APPLIED: β
|
| 10 |
-
β β
FIX v2.5: Default port
|
| 11 |
-
β β
FIX v2.5: WebSocket
|
|
|
|
|
|
|
| 12 |
β β
FIX v2.4: All /api/ranker/logs/* routes inline β no Blueprint dependency β
|
| 13 |
β β
FIX v2.4: Training KPI enrichment (_enrich_training) applied on /recent β
|
| 14 |
β β
FIX #1: Include rotated log files (*.log, *.log.1, *.log.2, etc.) β
|
|
@@ -439,16 +441,42 @@ class FileBasedLoggerAdapter:
|
|
| 439 |
|
| 440 |
def _find_files(self) -> list:
|
| 441 |
candidate_dirs = [
|
| 442 |
-
self._log_dir,
|
| 443 |
-
str(Path(__file__).parent / "ranker_logs"),
|
| 444 |
-
"./ranker_logs",
|
| 445 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 446 |
]
|
| 447 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 448 |
found = sorted(glob.glob(str(Path(cdir) / "*.log*")))
|
| 449 |
if found:
|
| 450 |
-
|
| 451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
|
| 453 |
def _read_lines(self, n_tail: int = 500) -> list:
|
| 454 |
"""Return up to n_tail most-recent lines across the 3 newest log files."""
|
|
@@ -888,17 +916,52 @@ def health():
|
|
| 888 |
return jsonify({"status": "ok", "version": "v2.5-port-fix"})
|
| 889 |
|
| 890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 891 |
if __name__ == "__main__":
|
| 892 |
-
logger.info("=== K1RL QUASAR HUB DASHBOARD SERVICE v2.5 (PORT FIX) ===")
|
| 893 |
-
logger.info(f"Dashboard
|
| 894 |
-
logger.info(f"Log directory:
|
| 895 |
logger.info("Fixes applied:")
|
| 896 |
-
logger.info(" β
FIX v2.5: Default port 8051β7860 (HF Spaces
|
| 897 |
-
logger.info(" β
FIX v2.5: WebSocket
|
| 898 |
-
logger.info(" β
FIX v2.
|
| 899 |
-
logger.info(" β
FIX v2.
|
| 900 |
-
logger.info(" β
FIX
|
| 901 |
-
logger.info("
|
| 902 |
-
logger.info(" β
FIX #4: Dedicated exit_price regex (no optional-group ambiguity)")
|
| 903 |
|
| 904 |
app.run(host="0.0.0.0", port=_DASHBOARD_PORT, debug=False, use_reloader=False)
|
|
|
|
| 4 |
β K1RL QUASAR β HUB DASHBOARD SERVICE (with Trade Log Parser) β FIXED v2.5 β
|
| 5 |
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
| 6 |
β Architecture role: READ-ONLY subscriber β serves dashboard UI β
|
| 7 |
+
β VERSION: v2.5 (PORT + LOG PATH FIX) | 2026-04-04 β
|
| 8 |
β β
|
| 9 |
β FIXES APPLIED: β
|
| 10 |
+
β β
FIX v2.5: Default port 8051β7860 (HF Spaces only exposes port 7860) β
|
| 11 |
+
β β
FIX v2.5: WebSocket ws://host:7860 β wss://host (HF Spaces TLS proxy) β
|
| 12 |
+
β β
FIX v2.5: _find_files() searches all likely HF Spaces log paths β
|
| 13 |
+
β β
FIX v2.5: Added /api/debug endpoint for live diagnostics β
|
| 14 |
β β
FIX v2.4: All /api/ranker/logs/* routes inline β no Blueprint dependency β
|
| 15 |
β β
FIX v2.4: Training KPI enrichment (_enrich_training) applied on /recent β
|
| 16 |
β β
FIX #1: Include rotated log files (*.log, *.log.1, *.log.2, etc.) β
|
|
|
|
| 441 |
|
| 442 |
def _find_files(self) -> list:
|
| 443 |
candidate_dirs = [
|
| 444 |
+
self._log_dir, # env-configured (default /app/ranker_logs)
|
| 445 |
+
str(Path(__file__).parent / "ranker_logs"), # alongside this script
|
| 446 |
+
"./ranker_logs", # cwd
|
| 447 |
+
"/app/ranker_logs", # HF Spaces default app dir
|
| 448 |
+
"/home/user/ranker_logs", # HF Spaces user home
|
| 449 |
+
"/tmp/ranker_logs", # fallback tmp
|
| 450 |
+
str(Path.home() / "ranker_logs"), # user home
|
| 451 |
+
str(Path(__file__).parent), # script dir itself (*.log*)
|
| 452 |
]
|
| 453 |
+
# Deduplicate while preserving order
|
| 454 |
+
seen = set()
|
| 455 |
+
unique_dirs = []
|
| 456 |
+
for d in candidate_dirs:
|
| 457 |
+
if d not in seen:
|
| 458 |
+
seen.add(d)
|
| 459 |
+
unique_dirs.append(d)
|
| 460 |
+
|
| 461 |
+
all_files = []
|
| 462 |
+
for cdir in unique_dirs:
|
| 463 |
found = sorted(glob.glob(str(Path(cdir) / "*.log*")))
|
| 464 |
if found:
|
| 465 |
+
all_files.extend(found)
|
| 466 |
+
# Also check for any .log* directly in /app and /home/user
|
| 467 |
+
for root_dir in ["/app", "/home/user", "."]:
|
| 468 |
+
found = sorted(glob.glob(str(Path(root_dir) / "*.log*")))
|
| 469 |
+
all_files.extend(found)
|
| 470 |
+
|
| 471 |
+
# Deduplicate file list
|
| 472 |
+
seen_files = set()
|
| 473 |
+
unique_files = []
|
| 474 |
+
for f in all_files:
|
| 475 |
+
if f not in seen_files:
|
| 476 |
+
seen_files.add(f)
|
| 477 |
+
unique_files.append(f)
|
| 478 |
+
|
| 479 |
+
return sorted(unique_files)
|
| 480 |
|
| 481 |
def _read_lines(self, n_tail: int = 500) -> list:
|
| 482 |
"""Return up to n_tail most-recent lines across the 3 newest log files."""
|
|
|
|
| 916 |
return jsonify({"status": "ok", "version": "v2.5-port-fix"})
|
| 917 |
|
| 918 |
|
| 919 |
+
@app.route("/api/debug")
|
| 920 |
+
def api_debug():
|
| 921 |
+
"""GET /api/debug β diagnostics: log files found, paths searched, env vars."""
|
| 922 |
+
import glob as _glob
|
| 923 |
+
candidate_dirs = [
|
| 924 |
+
_LOG_DIR,
|
| 925 |
+
str(Path(__file__).parent / "ranker_logs"),
|
| 926 |
+
"./ranker_logs",
|
| 927 |
+
"/app/ranker_logs",
|
| 928 |
+
"/home/user/ranker_logs",
|
| 929 |
+
"/tmp/ranker_logs",
|
| 930 |
+
str(Path.home() / "ranker_logs"),
|
| 931 |
+
str(Path(__file__).parent),
|
| 932 |
+
"/app", "/home/user", ".",
|
| 933 |
+
]
|
| 934 |
+
dir_scan = {}
|
| 935 |
+
for d in candidate_dirs:
|
| 936 |
+
files = sorted(_glob.glob(str(Path(d) / "*.log*")))
|
| 937 |
+
dir_scan[d] = {"exists": Path(d).exists(), "log_files": files}
|
| 938 |
+
|
| 939 |
+
adapter_files = _log_adapter._find_files()
|
| 940 |
+
return jsonify({
|
| 941 |
+
"version": "v2.5-port-fix",
|
| 942 |
+
"env": {
|
| 943 |
+
"DASHBOARD_PORT": os.environ.get("DASHBOARD_PORT", "(not set, using 7860)"),
|
| 944 |
+
"RANKER_LOG_DIR": os.environ.get("RANKER_LOG_DIR", "(not set, using /app/ranker_logs)"),
|
| 945 |
+
"QUASAR_HUB_HOST": os.environ.get("QUASAR_HUB_HOST", "(not set)"),
|
| 946 |
+
"cwd": str(Path.cwd()),
|
| 947 |
+
"script_dir": str(Path(__file__).parent),
|
| 948 |
+
},
|
| 949 |
+
"adapter_files_found": adapter_files,
|
| 950 |
+
"directory_scan": dir_scan,
|
| 951 |
+
"adapter_stats": _log_adapter.get_stats(),
|
| 952 |
+
})
|
| 953 |
+
|
| 954 |
+
|
| 955 |
if __name__ == "__main__":
|
| 956 |
+
logger.info("=== K1RL QUASAR HUB DASHBOARD SERVICE v2.5 (PORT + LOG PATH FIX) ===")
|
| 957 |
+
logger.info(f"Dashboard port: {_DASHBOARD_PORT} (HF Spaces public port)")
|
| 958 |
+
logger.info(f"Log directory: {_LOG_DIR}")
|
| 959 |
logger.info("Fixes applied:")
|
| 960 |
+
logger.info(" β
FIX v2.5: Default port 8051β7860 (HF Spaces only exposes 7860)")
|
| 961 |
+
logger.info(" β
FIX v2.5: WebSocket wss:// with no explicit port")
|
| 962 |
+
logger.info(" β
FIX v2.5: _find_files() scans all likely HF Spaces log paths")
|
| 963 |
+
logger.info(" β
FIX v2.5: /api/debug endpoint for live diagnostics")
|
| 964 |
+
logger.info(" β
FIX v2.4: All /api/ranker/logs/* routes inline")
|
| 965 |
+
logger.info(f" β Visit /api/debug to inspect log file discovery live")
|
|
|
|
| 966 |
|
| 967 |
app.run(host="0.0.0.0", port=_DASHBOARD_PORT, debug=False, use_reloader=False)
|