mcp status
This commit is contained in:
@@ -535,6 +535,11 @@ async function refresh() {
|
|||||||
const displayedFetchMode = mcp.fetch_mode || mcp.previous_fetch_mode || configuration.graylog_fetch_mode || 'raw';
|
const displayedFetchMode = mcp.fetch_mode || mcp.previous_fetch_mode || configuration.graylog_fetch_mode || 'raw';
|
||||||
const displayedCoverage = mcp.coverage_status || mcp.previous_coverage_status || 'unknown';
|
const displayedCoverage = mcp.coverage_status || mcp.previous_coverage_status || 'unknown';
|
||||||
const zeroRawWindow = mcp.status === 'refreshing' ? 'previous completed poll' : 'this poll';
|
const zeroRawWindow = mcp.status === 'refreshing' ? 'previous completed poll' : 'this poll';
|
||||||
|
const nowSeconds = Math.floor(Date.now() / 1000);
|
||||||
|
const pollStartedAt = Number(mcp.poll_started_at || 0);
|
||||||
|
const pollCompletedAt = Number(mcp.poll_completed_at || mcp.previous_poll_completed_at || 0);
|
||||||
|
const pollRunningSeconds = pollStartedAt ? Math.max(0, nowSeconds - pollStartedAt) : 0;
|
||||||
|
const pollCompletedAge = pollCompletedAt ? Math.max(0, nowSeconds - pollCompletedAt) : 0;
|
||||||
const rawCorrelations = data.cross_source_correlations || [];
|
const rawCorrelations = data.cross_source_correlations || [];
|
||||||
const correlationsCached = rawCorrelations.length === 0 && uiCache.correlations.length > 0;
|
const correlationsCached = rawCorrelations.length === 0 && uiCache.correlations.length > 0;
|
||||||
const correlations = rawCorrelations.length ? rawCorrelations : uiCache.correlations;
|
const correlations = rawCorrelations.length ? rawCorrelations : uiCache.correlations;
|
||||||
@@ -573,6 +578,9 @@ async function refresh() {
|
|||||||
`Discovery fields recorded: ${esc((data.baseline || {}).discovery_fields_recorded || 0)}`,
|
`Discovery fields recorded: ${esc((data.baseline || {}).discovery_fields_recorded || 0)}`,
|
||||||
`Discovery cache events: ${esc((data.baseline || {}).discovery_cache_events || 0)}`,
|
`Discovery cache events: ${esc((data.baseline || {}).discovery_cache_events || 0)}`,
|
||||||
`MCP status: ${esc(mcp.status || 'unknown')}`,
|
`MCP status: ${esc(mcp.status || 'unknown')}`,
|
||||||
|
mcp.status === 'refreshing' && pollStartedAt ? `MCP poll running: ${esc(pollRunningSeconds)}s` : '',
|
||||||
|
pollCompletedAt ? `Last completed MCP poll: ${esc(pollCompletedAge)}s ago` : '',
|
||||||
|
mcp.status === 'refreshing' && pollRunningSeconds > Math.max(120, Number(configuration.graylog_range_seconds || 300)) ? `<span class="sev-high">MCP poll has been refreshing for ${esc(pollRunningSeconds)}s. It may be slow or stuck.</span>` : '',
|
||||||
mcp.error ? `<span class="sev-high">MCP error: ${esc(mcp.error)}</span>` : '',
|
mcp.error ? `<span class="sev-high">MCP error: ${esc(mcp.error)}</span>` : '',
|
||||||
`Enabled streams: ${esc(enabledStreams.length)}`,
|
`Enabled streams: ${esc(enabledStreams.length)}`,
|
||||||
`MCP fetch mode: ${esc(displayedFetchMode)}${mcp.status === 'refreshing' ? ' (refreshing, showing previous counters)' : ''}`,
|
`MCP fetch mode: ${esc(displayedFetchMode)}${mcp.status === 'refreshing' ? ' (refreshing, showing previous counters)' : ''}`,
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ def build_status(
|
|||||||
"events_fetched": len(events),
|
"events_fetched": len(events),
|
||||||
"raw_events_fetched": len(events),
|
"raw_events_fetched": len(events),
|
||||||
"aggregate_events": aggregate_events_total,
|
"aggregate_events": aggregate_events_total,
|
||||||
|
"poll_completed_at": int(time.time()),
|
||||||
"fetch_mode": "aggregate" if use_aggregate else "raw",
|
"fetch_mode": "aggregate" if use_aggregate else "raw",
|
||||||
"range_seconds": range_seconds,
|
"range_seconds": range_seconds,
|
||||||
"max_events_per_stream": max_events_per_stream,
|
"max_events_per_stream": max_events_per_stream,
|
||||||
@@ -482,6 +483,7 @@ def write_status(status: dict[str, object], output: str) -> None:
|
|||||||
|
|
||||||
def write_refreshing_status(output: str, *, cache_path: str | None = None) -> None:
|
def write_refreshing_status(output: str, *, cache_path: str | None = None) -> None:
|
||||||
output_path = Path(output)
|
output_path = Path(output)
|
||||||
|
now = int(time.time())
|
||||||
try:
|
try:
|
||||||
current = json.loads(output_path.read_text(encoding="utf-8")) if output_path.exists() else {}
|
current = json.loads(output_path.read_text(encoding="utf-8")) if output_path.exists() else {}
|
||||||
except (json.JSONDecodeError, OSError):
|
except (json.JSONDecodeError, OSError):
|
||||||
@@ -495,8 +497,9 @@ def write_refreshing_status(output: str, *, cache_path: str | None = None) -> No
|
|||||||
current = cached
|
current = cached
|
||||||
used_cache = True
|
used_cache = True
|
||||||
previous_mcp = current.get("capabilities", {}).get("graylog_mcp", {}) if isinstance(current.get("capabilities"), dict) else {}
|
previous_mcp = current.get("capabilities", {}).get("graylog_mcp", {}) if isinstance(current.get("capabilities"), dict) else {}
|
||||||
|
previous_completed_at = previous_mcp.get("poll_completed_at", current.get("generated_at", 0)) if isinstance(previous_mcp, dict) else current.get("generated_at", 0)
|
||||||
current.setdefault("status_schema", 2)
|
current.setdefault("status_schema", 2)
|
||||||
current["generated_at"] = int(time.time())
|
current["generated_at"] = now
|
||||||
current["stale"] = False
|
current["stale"] = False
|
||||||
current["stale_reason"] = ""
|
current["stale_reason"] = ""
|
||||||
capabilities = current.setdefault("capabilities", {})
|
capabilities = current.setdefault("capabilities", {})
|
||||||
@@ -518,6 +521,8 @@ def write_refreshing_status(output: str, *, cache_path: str | None = None) -> No
|
|||||||
"events_fetched": previous_events,
|
"events_fetched": previous_events,
|
||||||
"raw_events_fetched": previous_raw_events,
|
"raw_events_fetched": previous_raw_events,
|
||||||
"aggregate_events": previous_aggregate_events,
|
"aggregate_events": previous_aggregate_events,
|
||||||
|
"poll_started_at": now,
|
||||||
|
"previous_poll_completed_at": previous_completed_at,
|
||||||
"fetch_mode": previous_fetch_mode,
|
"fetch_mode": previous_fetch_mode,
|
||||||
"coverage_status": previous_coverage_status or "refreshing",
|
"coverage_status": previous_coverage_status or "refreshing",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class MonitorTests(unittest.TestCase):
|
|||||||
"last_good",
|
"last_good",
|
||||||
{
|
{
|
||||||
"summary": {"total": 1234},
|
"summary": {"total": 1234},
|
||||||
"capabilities": {"graylog_mcp": {"status": "connected", "events_fetched": 99, "raw_events_fetched": 88, "aggregate_events": 1234, "fetch_mode": "aggregate", "coverage_status": "complete_window"}},
|
"capabilities": {"graylog_mcp": {"status": "connected", "events_fetched": 99, "raw_events_fetched": 88, "aggregate_events": 1234, "poll_completed_at": 123456, "fetch_mode": "aggregate", "coverage_status": "complete_window"}},
|
||||||
"cross_source_correlations": [{"entity": "10.0.0.1", "entity_label": "host01 (10.0.0.1)"}],
|
"cross_source_correlations": [{"entity": "10.0.0.1", "entity_label": "host01 (10.0.0.1)"}],
|
||||||
"llm_assessment": {"enabled": True, "status": "cached", "text": "previous assessment"},
|
"llm_assessment": {"enabled": True, "status": "cached", "text": "previous assessment"},
|
||||||
},
|
},
|
||||||
@@ -96,6 +96,8 @@ class MonitorTests(unittest.TestCase):
|
|||||||
self.assertEqual(mcp["raw_events_fetched"], 88)
|
self.assertEqual(mcp["raw_events_fetched"], 88)
|
||||||
self.assertEqual(mcp["aggregate_events"], 1234)
|
self.assertEqual(mcp["aggregate_events"], 1234)
|
||||||
self.assertEqual(mcp["previous_status"], "connected")
|
self.assertEqual(mcp["previous_status"], "connected")
|
||||||
|
self.assertGreater(mcp["poll_started_at"], 123456)
|
||||||
|
self.assertEqual(mcp["previous_poll_completed_at"], 123456)
|
||||||
self.assertTrue(status["llm_assessment"]["enabled"])
|
self.assertTrue(status["llm_assessment"]["enabled"])
|
||||||
self.assertTrue(status["status_cache"]["served_from_cache"])
|
self.assertTrue(status["status_cache"]["served_from_cache"])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user