fix(prometheus, syslog): a target or pattern pauses with a Pause/Resume button, not an "on" tick box in its form (#6419)
Monitors, schedules and maintenance plans already pause with a Pause/Resume button and say "Paused" where they're listed. Prometheus targets and syslog patterns only had a tick box inside the edit form, so a target refused by its endpoint couldn't be stopped from its page. - Both get a Pause/Resume button (target page and list; patterns list) posting to /toggle, recorded in the audit log, and a Paused badge. - The forms lose the tick box. A new one starts running; an edit keeps whether it is paused. - A target's "off" state is now "paused", in its pages and MCP tools. A resumed target reads "not scraped yet" until its next scrape, and its counter rates start over. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -108,8 +108,7 @@ def parse_form(form) -> dict:
|
||||
if window not in WINDOWS:
|
||||
window = 15
|
||||
return {"name": name, "phrases": phrases, "max_severity": max_severity,
|
||||
"source_id": form.get("source_id") or None, "window_minutes": window,
|
||||
"enabled": "enabled" in form}
|
||||
"source_id": form.get("source_id") or None, "window_minutes": window}
|
||||
|
||||
|
||||
def matches(pattern, severity: int, message: str) -> bool:
|
||||
|
||||
@@ -381,13 +381,13 @@ async def add_preset(key: str):
|
||||
@syslog_bp.get("/patterns/new")
|
||||
@require_role(UserRole.admin)
|
||||
async def new_pattern():
|
||||
return await _render_pattern_form(None, {"window_minutes": 15, "enabled": True})
|
||||
return await _render_pattern_form(None, {"window_minutes": 15})
|
||||
|
||||
|
||||
def _typed_pattern(form) -> dict:
|
||||
return {"name": form.get("name", ""), "phrases": form.get("phrases", ""),
|
||||
"max_severity": form.get("max_severity", ""), "source_id": form.get("source_id", ""),
|
||||
"window_minutes": form.get("window_minutes", 15, type=int), "enabled": "enabled" in form}
|
||||
"window_minutes": form.get("window_minutes", 15, type=int)}
|
||||
|
||||
|
||||
@syslog_bp.post("/patterns/new")
|
||||
@@ -426,7 +426,7 @@ async def edit_pattern(pattern_id: str):
|
||||
return await _render_pattern_form(p, {
|
||||
"name": p.name, "phrases": "\n".join(p.phrases or []),
|
||||
"max_severity": "" if p.max_severity is None else str(p.max_severity),
|
||||
"source_id": p.source_id or "", "window_minutes": p.window_minutes, "enabled": p.enabled})
|
||||
"source_id": p.source_id or "", "window_minutes": p.window_minutes})
|
||||
|
||||
|
||||
@syslog_bp.post("/patterns/<pattern_id>/edit")
|
||||
@@ -451,6 +451,20 @@ async def save_pattern(pattern_id: str):
|
||||
return redirect(PATTERNS)
|
||||
|
||||
|
||||
@syslog_bp.post("/patterns/<pattern_id>/toggle")
|
||||
@require_role(UserRole.admin)
|
||||
async def toggle_pattern(pattern_id: str):
|
||||
"""Pause a pattern's counting, or resume it, from the patterns list."""
|
||||
async with current_app.db_sessionmaker() as db:
|
||||
async with db.begin():
|
||||
p = await _pattern_or_404(db, pattern_id)
|
||||
p.enabled = not p.enabled
|
||||
enabled, name = p.enabled, p.name
|
||||
await log_audit(current_app, *_actor(), "syslog.pattern_resumed" if enabled else "syslog.pattern_paused",
|
||||
entity_type="syslog_pattern", entity_id=pattern_id, detail={"name": name})
|
||||
return redirect(PATTERNS)
|
||||
|
||||
|
||||
@syslog_bp.post("/patterns/<pattern_id>/delete")
|
||||
@require_role(UserRole.admin)
|
||||
async def delete_pattern(pattern_id: str):
|
||||
|
||||
@@ -45,12 +45,6 @@
|
||||
</select>
|
||||
<span class="field-hint">The count is of matches this far back, so an alert on it clears this long after the last one.</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-check">
|
||||
<input type="checkbox" name="enabled"{% if v.enabled %} checked{% endif %}>
|
||||
Counted: off keeps the pattern without counting it
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="page-actions">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{# plugins/syslog/templates/syslog/patterns.html — telling phrases counted in
|
||||
each source's lines every minute, so an alert rule can watch them (#6001). #}
|
||||
{% extends "base.html" %}
|
||||
{% from "_macros.html" import crumbs, page_header, empty_state %}
|
||||
{% from "_macros.html" import crumbs, page_header, empty_state, status_badge %}
|
||||
{% block title %}Patterns — Syslog — Steward{% endblock %}
|
||||
{% block breadcrumb %}{{ crumbs([("Syslog", "/plugins/syslog/"), ("Patterns", "")]) }}{% endblock %}
|
||||
{% block content %}
|
||||
@@ -23,7 +23,7 @@
|
||||
<tbody>
|
||||
{% for p in patterns %}
|
||||
<tr>
|
||||
<td>{{ p.name }}{% if not p.enabled %} <span class="field-hint">(off)</span>{% endif %}<div class="field-hint mono">{{ p.metric }}</div></td>
|
||||
<td>{{ p.name }}{% if not p.enabled %} {{ status_badge('paused') }}{% endif %}<div class="field-hint mono">{{ p.metric }}</div></td>
|
||||
<td>
|
||||
{% if p.phrases %}<span class="mono" title="{{ p.phrases|join('\n') }}">{{ p.phrases[:3]|join(" · ") }}{% if p.phrases|length > 3 %} · +{{ p.phrases|length - 3 }} more{% endif %}</span>{% endif %}
|
||||
{% if p.severity %}<div class="field-hint">{{ p.severity }} and worse</div>{% endif %}
|
||||
@@ -37,7 +37,10 @@
|
||||
{% if can_alert %}
|
||||
<td style="white-space:nowrap;">
|
||||
{% if p.alert_resource %}<a class="btn btn-sm btn-ghost" href="/alerts/rules/new?source_module=syslog&resource_name={{ p.alert_resource|urlencode }}&metric_name={{ p.metric|urlencode }}">Alert on it</a>{% endif %}
|
||||
{% if admin %}<a class="btn btn-sm btn-ghost" href="/plugins/syslog/patterns/{{ p.id }}/edit">Edit</a>{% endif %}
|
||||
{% if admin %}<a class="btn btn-sm btn-ghost" href="/plugins/syslog/patterns/{{ p.id }}/edit">Edit</a>
|
||||
<form method="post" action="/plugins/syslog/patterns/{{ p.id }}/toggle" style="display:inline;margin:0;">{{ csrf_field() }}
|
||||
<button type="submit" class="btn btn-sm btn-ghost">{{ "Pause" if p.enabled else "Resume" }}</button>
|
||||
</form>{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user