PLUS: логи запросов и диагностика
Browse files- plus/diag.py +76 -9
plus/diag.py
CHANGED
|
@@ -8,6 +8,7 @@ import argparse
|
|
| 8 |
import io
|
| 9 |
import json
|
| 10 |
import math
|
|
|
|
| 11 |
import struct
|
| 12 |
import sys
|
| 13 |
import time
|
|
@@ -16,6 +17,45 @@ import urllib.request
|
|
| 16 |
import uuid
|
| 17 |
import wave
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
BYPASS = {"serveo-skip-browser-warning": "true"}
|
| 20 |
|
| 21 |
|
|
@@ -83,17 +123,25 @@ def post(base, audio, timeout=300):
|
|
| 83 |
|
| 84 |
def main():
|
| 85 |
parser = argparse.ArgumentParser(description="Диагностика POST /transcribe через туннель")
|
| 86 |
-
parser.add_argument("--url", default="", help="публичная ссылка
|
| 87 |
-
parser.add_argument("--proxy", type=int, default=
|
|
|
|
| 88 |
parser.add_argument("--seconds", type=float, default=2.0)
|
| 89 |
args = parser.parse_args()
|
| 90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
audio = probe_wav(args.seconds)
|
| 92 |
-
print("проба: %.0f КБ WAV
|
|
|
|
| 93 |
|
| 94 |
-
targets = [("локально :%d" %
|
| 95 |
-
if
|
| 96 |
-
targets.insert(0, ("через туннель",
|
| 97 |
|
| 98 |
verdict = {}
|
| 99 |
for label, base in targets:
|
|
@@ -104,12 +152,16 @@ def main():
|
|
| 104 |
print(" дошло и ответило: первый байт %s с | всего %.1f с | нот %d | пульсов %d"
|
| 105 |
% (round(result["first"], 2) if result["first"] else "-",
|
| 106 |
result["total"], result["notes"], result["pings"]))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
else:
|
| 108 |
print(" ОШИБКА за %.1f с: %s" % (result["total"], result.get("error")))
|
| 109 |
|
| 110 |
-
if
|
| 111 |
remote = verdict["через туннель"]
|
| 112 |
-
local = verdict["локально :%d" %
|
| 113 |
print("\nвывод:")
|
| 114 |
if local["ok"] and not remote["ok"]:
|
| 115 |
print(" локально работает, снаружи нет → рвёт туннель, не сервер")
|
|
@@ -119,7 +171,22 @@ def main():
|
|
| 119 |
elif local["ok"] and remote["ok"]:
|
| 120 |
print(" и локально, и снаружи работает: туннель держит POST")
|
| 121 |
elif not local["ok"]:
|
| 122 |
-
print(" локально тоже ошибка
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
return 0
|
| 124 |
|
| 125 |
|
|
|
|
| 8 |
import io
|
| 9 |
import json
|
| 10 |
import math
|
| 11 |
+
import pathlib
|
| 12 |
import struct
|
| 13 |
import sys
|
| 14 |
import time
|
|
|
|
| 17 |
import uuid
|
| 18 |
import wave
|
| 19 |
|
| 20 |
+
LINKS = "muscriptor_links.txt"
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def read_link() -> tuple[str, int, int]:
|
| 24 |
+
"""Достать ссылку и порты из файла, который пишет пускач."""
|
| 25 |
+
path = pathlib.Path(LINKS)
|
| 26 |
+
if not path.exists():
|
| 27 |
+
return "", 8222, 8223
|
| 28 |
+
url, server, proxy = "", 8222, 8223
|
| 29 |
+
for line in path.read_text(encoding="utf-8").splitlines():
|
| 30 |
+
low = line.lower()
|
| 31 |
+
if low.startswith("ссылка:"):
|
| 32 |
+
url = line.split(":", 1)[1].strip()
|
| 33 |
+
elif low.startswith("локально через прокси:") or low.startswith("локально:"):
|
| 34 |
+
tail = line.rsplit(":", 1)[-1].strip()
|
| 35 |
+
if tail.isdigit():
|
| 36 |
+
if "прокси" in low:
|
| 37 |
+
proxy = int(tail)
|
| 38 |
+
else:
|
| 39 |
+
server = int(tail)
|
| 40 |
+
return url, server, proxy
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def clean_url(value: str) -> str:
|
| 44 |
+
"""Проверить адрес: пустой, кириллица и заглушки отсекаются."""
|
| 45 |
+
text = (value or "").strip()
|
| 46 |
+
if not text:
|
| 47 |
+
return ""
|
| 48 |
+
if not text.isascii():
|
| 49 |
+
print("! в адресе не-латинские символы: %r — это заглушка, отбрасываю" % text)
|
| 50 |
+
return ""
|
| 51 |
+
if "твоя" in text or "link" in text.replace(".serveo.net", "").replace(".life", ""):
|
| 52 |
+
return ""
|
| 53 |
+
if not text.startswith(("http://", "https://")):
|
| 54 |
+
print("! адрес должен начинаться с http:// или https://")
|
| 55 |
+
return ""
|
| 56 |
+
return text
|
| 57 |
+
|
| 58 |
+
|
| 59 |
BYPASS = {"serveo-skip-browser-warning": "true"}
|
| 60 |
|
| 61 |
|
|
|
|
| 123 |
|
| 124 |
def main():
|
| 125 |
parser = argparse.ArgumentParser(description="Диагностика POST /transcribe через туннель")
|
| 126 |
+
parser.add_argument("--url", default="", help="публичная ссылка; иначе беру из " + LINKS)
|
| 127 |
+
parser.add_argument("--proxy", type=int, default=0, help="порт прокси; 0 = из файла")
|
| 128 |
+
parser.add_argument("--server", type=int, default=0, help="порт сервера; 0 = из файла")
|
| 129 |
parser.add_argument("--seconds", type=float, default=2.0)
|
| 130 |
args = parser.parse_args()
|
| 131 |
|
| 132 |
+
url_from_file, server_port, proxy_port = read_link()
|
| 133 |
+
url = clean_url(args.url) or clean_url(url_from_file)
|
| 134 |
+
proxy_port = args.proxy or proxy_port
|
| 135 |
+
if not url and not args.url:
|
| 136 |
+
print("адрес не задан и в %s его нет — проверю только локально" % LINKS)
|
| 137 |
+
|
| 138 |
audio = probe_wav(args.seconds)
|
| 139 |
+
print("проба: %.0f КБ WAV" % (len(audio) / 1024))
|
| 140 |
+
print("цели: туннель %s | локальный прокси :%d\n" % (url or "нет", proxy_port))
|
| 141 |
|
| 142 |
+
targets = [("локально :%d" % proxy_port, "http://127.0.0.1:%d" % proxy_port)]
|
| 143 |
+
if url:
|
| 144 |
+
targets.insert(0, ("через туннель", url))
|
| 145 |
|
| 146 |
verdict = {}
|
| 147 |
for label, base in targets:
|
|
|
|
| 152 |
print(" дошло и ответило: первый байт %s с | всего %.1f с | нот %d | пульсов %d"
|
| 153 |
% (round(result["first"], 2) if result["first"] else "-",
|
| 154 |
result["total"], result["notes"], result["pings"]))
|
| 155 |
+
if result["events"] == 0:
|
| 156 |
+
print(" но событий SSE нет: похоже, ответила заглушка провайдера,"
|
| 157 |
+
" а не MuScriptor")
|
| 158 |
+
result["ok"] = False
|
| 159 |
else:
|
| 160 |
print(" ОШИБКА за %.1f с: %s" % (result["total"], result.get("error")))
|
| 161 |
|
| 162 |
+
if url and "локально :%d" % proxy_port in verdict:
|
| 163 |
remote = verdict["через туннель"]
|
| 164 |
+
local = verdict["локально :%d" % proxy_port]
|
| 165 |
print("\nвывод:")
|
| 166 |
if local["ok"] and not remote["ok"]:
|
| 167 |
print(" локально работает, снаружи нет → рвёт туннель, не сервер")
|
|
|
|
| 171 |
elif local["ok"] and remote["ok"]:
|
| 172 |
print(" и локально, и снаружи работает: туннель держит POST")
|
| 173 |
elif not local["ok"]:
|
| 174 |
+
print(" локально тоже ошибка: скорее всего пускач не работает в этом ядре")
|
| 175 |
+
print(" проверь, что ячейка запуска жива и на :%d кто-то слушает" % proxy_port)
|
| 176 |
+
print(" если портов нет, запусти пускач заново — он перезапишет %s" % LINKS)
|
| 177 |
+
if not url and verdict:
|
| 178 |
+
only = list(verdict.values())[0]
|
| 179 |
+
if not only["ok"]:
|
| 180 |
+
print("\nвывод:")
|
| 181 |
+
print(" локальный прокси не отвечает: пускач не работает в этом ядре")
|
| 182 |
+
print(" запусти ячейку запуска заново, она запишет %s и порты" % LINKS)
|
| 183 |
+
elif only.get("events", 0) == 0:
|
| 184 |
+
print("\nвывод:")
|
| 185 |
+
print(" прокси ответил, но событий SSE нет: смотри muscriptor_server.log")
|
| 186 |
+
else:
|
| 187 |
+
print("\nвывод:")
|
| 188 |
+
print(" локально всё работает: %d нот, %d пульсов"
|
| 189 |
+
% (only["notes"], only["pings"]))
|
| 190 |
return 0
|
| 191 |
|
| 192 |
|