atlasbot: clarify scoped metrics and format percent values
This commit is contained in:
parent
5e4a974733
commit
600c124ef2
@ -406,15 +406,56 @@ def _apply_node_filter(expr: str, node_regex: str | None) -> str:
|
||||
replacement = f'node_uname_info{{nodename!=\"\",nodename=~\"{node_regex}\"}}'
|
||||
return expr.replace(needle, replacement)
|
||||
|
||||
def _metric_expr_uses_percent(entry: dict[str, Any]) -> bool:
|
||||
exprs = entry.get("exprs")
|
||||
expr = exprs[0] if isinstance(exprs, list) and exprs else ""
|
||||
return "* 100" in expr or "*100" in expr
|
||||
|
||||
|
||||
def _format_metric_value(value: str, *, percent: bool) -> str:
|
||||
try:
|
||||
num = float(value)
|
||||
except (TypeError, ValueError):
|
||||
return value
|
||||
if percent:
|
||||
return f"{num:.1f}%"
|
||||
if abs(num) >= 1:
|
||||
return f"{num:.2f}".rstrip("0").rstrip(".")
|
||||
return f"{num:.4f}".rstrip("0").rstrip(".")
|
||||
|
||||
|
||||
def _format_metric_label(metric: dict[str, Any]) -> str:
|
||||
label_parts = []
|
||||
for k in ("namespace", "pod", "container", "node", "instance", "job", "phase"):
|
||||
if metric.get(k):
|
||||
label_parts.append(f"{k}={metric.get(k)}")
|
||||
if not label_parts:
|
||||
for k in sorted(metric.keys()):
|
||||
if k.startswith("__"):
|
||||
continue
|
||||
label_parts.append(f"{k}={metric.get(k)}")
|
||||
if len(label_parts) >= 4:
|
||||
break
|
||||
return ", ".join(label_parts) if label_parts else "series"
|
||||
|
||||
|
||||
def _format_metric_answer(entry: dict[str, Any], res: dict | None) -> str:
|
||||
series = _vm_value_series(res)
|
||||
panel = entry.get("panel_title") or "Metric"
|
||||
if not series:
|
||||
return ""
|
||||
rendered = vm_render_result(res, limit=5)
|
||||
if not rendered:
|
||||
percent = _metric_expr_uses_percent(entry)
|
||||
lines: list[str] = []
|
||||
for r in series[:5]:
|
||||
if not isinstance(r, dict):
|
||||
continue
|
||||
metric = r.get("metric") or {}
|
||||
value = r.get("value") or []
|
||||
val = value[1] if isinstance(value, list) and len(value) > 1 else ""
|
||||
label = _format_metric_label(metric if isinstance(metric, dict) else {})
|
||||
lines.append(f"{label}: {_format_metric_value(val, percent=percent)}")
|
||||
if not lines:
|
||||
return ""
|
||||
lines = [line.lstrip("-").strip() for line in rendered.splitlines() if line.strip().startswith("-")]
|
||||
if len(lines) == 1:
|
||||
return f"{panel}: {lines[0]}."
|
||||
return f"{panel}:\n" + "\n".join(f"- {line}" for line in lines)
|
||||
@ -627,6 +668,16 @@ def structured_answer(prompt: str, *, inventory: list[dict[str, Any]], metrics_s
|
||||
res = vm_query(expr, timeout=20)
|
||||
answer = _format_metric_answer(entry, res)
|
||||
if answer:
|
||||
scope_parts: list[str] = []
|
||||
if include_hw:
|
||||
scope_parts.append(" and ".join(sorted(include_hw)))
|
||||
if exclude_hw:
|
||||
scope_parts.append(f"excluding {' and '.join(sorted(exclude_hw))}")
|
||||
if only_workers:
|
||||
scope_parts.append("worker")
|
||||
if scope_parts:
|
||||
scope = " ".join(scope_parts)
|
||||
return f"Among {scope} nodes, {answer}"
|
||||
return answer
|
||||
if metrics_summary:
|
||||
return metrics_summary
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user