chore: 更新公共镜像至 1.5.43

This commit is contained in:
chen qiang
2026-08-27 10:38:35 +08:00
parent e5fc7a33cc
commit dfc6a96e10
8 changed files with 306 additions and 3 deletions
+164 -1
View File
@@ -978,6 +978,83 @@ def cmd_awr_download(client_code: str, date: str, output_path: str = "", as_json
print(f"Size: {result['size']} bytes")
def _log_client_code(client_code: str = "") -> str:
cfg = get_config() or {}
return (client_code or cfg.get("client_code") or cfg.get("server_id") or "").strip()
def _log_api(endpoint: str, payload: Dict[str, Any], timeout: int = 120) -> Dict[str, Any]:
cfg = get_config() or {}
if not ensure_logged_in(cfg):
return {"success": False, "error": "login required", "error_code": "login_required"}
client_code = _log_client_code(str(payload.get("client_code") or ""))
if not client_code:
return {"success": False, "error": "clientCode is required", "error_code": "invalid_request"}
body = dict(payload)
body["client_code"] = client_code
body["timeout"] = max(1, min(int(timeout or 120), 300))
try:
resp = requests.post(
f"{str(cfg.get('transit_url') or TRANSIT_URL).rstrip('/')}/api/log/{endpoint}",
json=body,
headers=make_headers(),
timeout=body["timeout"] + 5,
)
try:
result = resp.json()
except Exception:
result = {"success": False, "error": resp.text or f"HTTP {resp.status_code}"}
if not resp.ok:
result.setdefault("success", False)
result.setdefault("status_code", resp.status_code)
return result
except requests.exceptions.RequestException as e:
return {"success": False, "error": str(e), "error_code": "request_failed"}
def log_info(path: str, client_code: str = "", timeout: int = 120) -> Dict[str, Any]:
return _log_api("info", {"client_code": client_code, "path": path}, timeout)
def log_tail(path: str, client_code: str = "", lines: int = 200,
max_bytes: int = 256 * 1024, timeout: int = 120) -> Dict[str, Any]:
return _log_api("tail", {
"client_code": client_code, "path": path, "lines": lines, "max_bytes": max_bytes,
}, timeout)
def log_search(path: str, patterns: List[str], client_code: str = "", regex: bool = False,
case_sensitive: bool = False, before_lines: int = 3, after_lines: int = 3,
max_matches: int = 100, scan_scope: str = "recent",
recent_bytes: int = 100 * 1024 * 1024, timeout: int = 120) -> Dict[str, Any]:
return _log_api("search", {
"client_code": client_code, "path": path, "patterns": patterns, "regex": regex,
"case_sensitive": case_sensitive, "before_lines": before_lines, "after_lines": after_lines,
"max_matches": max_matches, "scan_scope": scan_scope, "recent_bytes": recent_bytes,
}, timeout)
def set_log_analysis_enabled(enabled: bool, client_code: str = "", timeout: int = 30) -> Dict[str, Any]:
return _log_api("config", {"client_code": client_code, "enabled": bool(enabled)}, timeout)
def _print_log_result(result: Dict[str, Any], as_json: bool = False):
if as_json or not result.get("success"):
print(json.dumps(result, ensure_ascii=False, indent=2))
return
data = result.get("data") or {}
if isinstance(data.get("lines"), list):
for entry in data["lines"]:
if isinstance(entry, dict):
marker = ">" if entry.get("match") else " "
print(f"{marker} {entry.get('scan_line', '-')}: {entry.get('text', '')}")
else:
print(entry)
print(f"matches={data.get('matches', '-')} complete={data.get('complete', True)} stop_reason={data.get('stop_reason', '')}")
else:
print(json.dumps(data, ensure_ascii=False, indent=2))
def _inspection_report_payload(result: Dict[str, Any]) -> Dict[str, Any]:
data = result.get("data") or {}
if isinstance(data, dict) and data.get("report_json"):
@@ -3351,6 +3428,45 @@ def cmd_capabilities(args):
"required": []
}
},
{
"name": "log_info",
"description": "Validate one absolute server log path and return bounded file metadata without Oracle access.",
"parameters": {"type": "object", "properties": {
"path": {"type": "string", "description": "Absolute log file path on the target server."},
"clientCode": {"type": "string", "description": "Optional client/server code."}
}, "required": ["path"]}
},
{
"name": "log_tail",
"description": "Read a bounded tail from one server log file.",
"parameters": {"type": "object", "properties": {
"path": {"type": "string"}, "clientCode": {"type": "string"},
"lines": {"type": "integer", "description": "Default 200, maximum 2000."},
"maxBytes": {"type": "integer", "description": "Default 262144, maximum 1048576."}
}, "required": ["path"]}
},
{
"name": "log_search",
"description": "Stream-search a server log with keywords or RE2 regular expressions and bounded context.",
"parameters": {"type": "object", "properties": {
"path": {"type": "string"}, "patterns": {"type": "array", "items": {"type": "string"}},
"clientCode": {"type": "string"}, "regex": {"type": "boolean"},
"caseSensitive": {"type": "boolean"}, "beforeLines": {"type": "integer"},
"afterLines": {"type": "integer"}, "maxMatches": {"type": "integer"},
"scanScope": {"type": "string", "enum": ["recent", "full"]},
"recentBytes": {"type": "integer"}, "timeout": {"type": "integer"}
}, "required": ["path", "patterns"]}
},
{
"name": "log_enable",
"description": "Enable persisted log analysis for an authorized client.",
"parameters": {"type": "object", "properties": {"clientCode": {"type": "string"}}, "required": []}
},
{
"name": "log_disable",
"description": "Disable persisted log analysis for an authorized client.",
"parameters": {"type": "object", "properties": {"clientCode": {"type": "string"}}, "required": []}
},
{
"name": "awr_list",
"description": "List AWR reports already generated and stored by the target Agent.",
@@ -3419,7 +3535,7 @@ def cmd_capabilities(args):
"analyze", "list", "source", "describe",
"search", "query", "discover", "nl2sql",
"perm", "qperm", "login", "logout",
"status", "switch", "clients", "device_register", "device_login", "ops", "ops_report", "inspection_report", "inspection_latest", "inspection_get", "awr_status", "awr_list", "awr_download", "agent_update", "capabilities"
"status", "switch", "clients", "device_register", "device_login", "ops", "ops_report", "inspection_report", "inspection_latest", "inspection_get", "awr_status", "awr_list", "awr_download", "log_info", "log_tail", "log_search", "log_enable", "log_disable", "agent_update", "capabilities"
],
"python_version": "3.6+",
"dependencies": ["requests"]
@@ -3612,6 +3728,53 @@ def main():
output_path = sys.argv[output_index + 1]
cmd_awr_download(sys.argv[2], sys.argv[3], output_path=output_path, as_json="--json" in sys.argv[4:])
elif cmd == "log_info":
parser = argparse.ArgumentParser(prog="oracle_skill.py log_info")
parser.add_argument("path")
parser.add_argument("--client", default="")
parser.add_argument("--timeout", type=int, default=120)
parser.add_argument("--json", action="store_true")
args = parser.parse_args(sys.argv[2:])
_print_log_result(log_info(args.path, args.client, args.timeout), args.json)
elif cmd == "log_tail":
parser = argparse.ArgumentParser(prog="oracle_skill.py log_tail")
parser.add_argument("path")
parser.add_argument("--client", default="")
parser.add_argument("--lines", type=int, default=200)
parser.add_argument("--max-bytes", type=int, default=256 * 1024)
parser.add_argument("--timeout", type=int, default=120)
parser.add_argument("--json", action="store_true")
args = parser.parse_args(sys.argv[2:])
_print_log_result(log_tail(args.path, args.client, args.lines, args.max_bytes, args.timeout), args.json)
elif cmd == "log_search":
parser = argparse.ArgumentParser(prog="oracle_skill.py log_search")
parser.add_argument("path")
parser.add_argument("patterns", nargs="+")
parser.add_argument("--client", default="")
parser.add_argument("--regex", action="store_true")
parser.add_argument("--case-sensitive", action="store_true")
parser.add_argument("--before", type=int, default=3)
parser.add_argument("--after", type=int, default=3)
parser.add_argument("--max-matches", type=int, default=100)
parser.add_argument("--scope", choices=("recent", "full"), default="recent")
parser.add_argument("--recent-bytes", type=int, default=100 * 1024 * 1024)
parser.add_argument("--timeout", type=int, default=120)
parser.add_argument("--json", action="store_true")
args = parser.parse_args(sys.argv[2:])
_print_log_result(log_search(
args.path, args.patterns, args.client, args.regex, args.case_sensitive,
args.before, args.after, args.max_matches, args.scope, args.recent_bytes, args.timeout,
), args.json)
elif cmd in ("log_enable", "log_disable"):
parser = argparse.ArgumentParser(prog=f"oracle_skill.py {cmd}")
parser.add_argument("client", nargs="?", default="")
parser.add_argument("--json", action="store_true")
args = parser.parse_args(sys.argv[2:])
_print_log_result(set_log_analysis_enabled(cmd == "log_enable", args.client), args.json)
elif cmd == "agent_update":
timeout = int(sys.argv[3]) if len(sys.argv) >= 4 and sys.argv[3].isdigit() else 300
cmd_agent_update(sys.argv[2] if len(sys.argv) >= 3 else "", timeout)