fix
This commit is contained in:
@@ -555,7 +555,8 @@ async function refresh() {
|
|||||||
const cache = data.status_cache || {};
|
const cache = data.status_cache || {};
|
||||||
const streamCoverage = data.stream_coverage || [];
|
const streamCoverage = data.stream_coverage || [];
|
||||||
const context = data.event_context || {};
|
const context = data.event_context || {};
|
||||||
const enabledStreams = streamCoverage.filter(item => item.enabled);
|
const enabledConfigStreams = (configuration.graylog_streams || []).filter(item => item.enabled);
|
||||||
|
const enabledStreams = streamCoverage.some(item => item.enabled) ? streamCoverage.filter(item => item.enabled) : enabledConfigStreams;
|
||||||
const streamsMissingProfile = enabledStreams.filter(item => !item.profile_ready).length;
|
const streamsMissingProfile = enabledStreams.filter(item => !item.profile_ready).length;
|
||||||
const enabledWithNoRawEvents = enabledStreams.filter(item => Number(item.events_fetched || 0) === 0);
|
const enabledWithNoRawEvents = enabledStreams.filter(item => Number(item.events_fetched || 0) === 0);
|
||||||
const displayedAggregateEvents = mcp.status === 'refreshing' ? Number(mcp.previous_aggregate_events || 0) : Number(mcp.aggregate_events || 0);
|
const displayedAggregateEvents = mcp.status === 'refreshing' ? Number(mcp.previous_aggregate_events || 0) : Number(mcp.aggregate_events || 0);
|
||||||
|
|||||||
@@ -36,6 +36,23 @@ def _stream_titles(config: dict[str, object]) -> dict[str, str]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _public_runtime_config(config: dict[str, object]) -> dict[str, object]:
|
||||||
|
public = {
|
||||||
|
key: value
|
||||||
|
for key, value in config.items()
|
||||||
|
if key not in {"graylog_mcp_token", "abuseipdb_api_key", "virustotal_api_key"}
|
||||||
|
}
|
||||||
|
public["graylog_mcp_token_configured"] = bool(config.get("graylog_mcp_token"))
|
||||||
|
public["abuseipdb_api_key_configured"] = bool(config.get("abuseipdb_api_key"))
|
||||||
|
public["virustotal_api_key_configured"] = bool(config.get("virustotal_api_key"))
|
||||||
|
public["enabled_streams"] = sum(
|
||||||
|
1
|
||||||
|
for item in config.get("graylog_streams", [])
|
||||||
|
if isinstance(item, dict) and item.get("enabled")
|
||||||
|
)
|
||||||
|
return public
|
||||||
|
|
||||||
|
|
||||||
def _stream_name(stream_id: str, stream_titles: dict[str, str], profile: object | None = None) -> str:
|
def _stream_name(stream_id: str, stream_titles: dict[str, str], profile: object | None = None) -> str:
|
||||||
return stream_titles.get(stream_id) or getattr(profile, "name", "") or stream_id
|
return stream_titles.get(stream_id) or getattr(profile, "name", "") or stream_id
|
||||||
|
|
||||||
@@ -136,7 +153,7 @@ def build_status(
|
|||||||
config_store = ConfigStore(config_path) if config_path else None
|
config_store = ConfigStore(config_path) if config_path else None
|
||||||
config_exists = bool(config_store and config_store.path.exists())
|
config_exists = bool(config_store and config_store.path.exists())
|
||||||
runtime_values = config_store.read() if config_exists and config_store else {}
|
runtime_values = config_store.read() if config_exists and config_store else {}
|
||||||
runtime_config = config_store.public() if config_store else {}
|
runtime_config = _public_runtime_config(runtime_values) if config_store else {}
|
||||||
stream_profiles = parse_profiles(runtime_values.get("graylog_stream_profiles", []))
|
stream_profiles = parse_profiles(runtime_values.get("graylog_stream_profiles", []))
|
||||||
stream_titles = _stream_titles(runtime_values)
|
stream_titles = _stream_titles(runtime_values)
|
||||||
events = read_events(log_path) if Path(log_path).exists() else []
|
events = read_events(log_path) if Path(log_path).exists() else []
|
||||||
@@ -517,7 +534,7 @@ def write_status(status: dict[str, object], output: str) -> None:
|
|||||||
tmp_path.replace(output_path)
|
tmp_path.replace(output_path)
|
||||||
|
|
||||||
|
|
||||||
def write_refreshing_status(output: str, *, cache_path: str | None = None, call_timeout_seconds: int = 0, poll_timeout_seconds: int = 0) -> None:
|
def write_refreshing_status(output: str, *, cache_path: str | None = None, call_timeout_seconds: int = 0, poll_timeout_seconds: int = 0, runtime_values: dict[str, object] | None = None) -> None:
|
||||||
output_path = Path(output)
|
output_path = Path(output)
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
try:
|
try:
|
||||||
@@ -538,6 +555,9 @@ def write_refreshing_status(output: str, *, cache_path: str | None = None, call_
|
|||||||
current["generated_at"] = now
|
current["generated_at"] = now
|
||||||
current["stale"] = False
|
current["stale"] = False
|
||||||
current["stale_reason"] = ""
|
current["stale_reason"] = ""
|
||||||
|
if runtime_values is not None:
|
||||||
|
current["configuration"] = _public_runtime_config(runtime_values)
|
||||||
|
current["stream_coverage"] = _stream_coverage(runtime_values, {}, {"streams": []}, [], _stream_titles(runtime_values))
|
||||||
capabilities = current.setdefault("capabilities", {})
|
capabilities = current.setdefault("capabilities", {})
|
||||||
if isinstance(capabilities, dict):
|
if isinstance(capabilities, dict):
|
||||||
previous_events = previous_mcp.get("events_fetched", 0) if isinstance(previous_mcp, dict) else 0
|
previous_events = previous_mcp.get("events_fetched", 0) if isinstance(previous_mcp, dict) else 0
|
||||||
@@ -595,7 +615,7 @@ def monitor_loop(
|
|||||||
mcp_call_timeout = max(1, int(runtime.get("graylog_mcp_call_timeout_seconds", 8) or 8))
|
mcp_call_timeout = max(1, int(runtime.get("graylog_mcp_call_timeout_seconds", 8) or 8))
|
||||||
mcp_poll_timeout = max(60, int(runtime.get("graylog_mcp_poll_timeout_seconds", 120) or 120))
|
mcp_poll_timeout = max(60, int(runtime.get("graylog_mcp_poll_timeout_seconds", 120) or 120))
|
||||||
if runtime.get("log_source") == "graylog_mcp":
|
if runtime.get("log_source") == "graylog_mcp":
|
||||||
write_refreshing_status(output, cache_path=status_cache_path, call_timeout_seconds=mcp_call_timeout, poll_timeout_seconds=mcp_poll_timeout)
|
write_refreshing_status(output, cache_path=status_cache_path, call_timeout_seconds=mcp_call_timeout, poll_timeout_seconds=mcp_poll_timeout, runtime_values=runtime)
|
||||||
try:
|
try:
|
||||||
status = build_status(
|
status = build_status(
|
||||||
log_path, policy_path=policy_path, anomaly_limit=anomaly_limit,
|
log_path, policy_path=policy_path, anomaly_limit=anomaly_limit,
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class MonitorTests(unittest.TestCase):
|
|||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
|
|
||||||
write_refreshing_status(str(output), call_timeout_seconds=8, poll_timeout_seconds=120)
|
write_refreshing_status(str(output), call_timeout_seconds=8, poll_timeout_seconds=120, runtime_values={"log_source": "graylog_mcp", "graylog_streams": [{"id": "fw", "title": "Firewall", "enabled": True}]})
|
||||||
|
|
||||||
status = json.loads(output.read_text(encoding="utf-8"))
|
status = json.loads(output.read_text(encoding="utf-8"))
|
||||||
self.assertFalse(status["stale"])
|
self.assertFalse(status["stale"])
|
||||||
@@ -68,6 +68,8 @@ class MonitorTests(unittest.TestCase):
|
|||||||
self.assertEqual(status["capabilities"]["graylog_mcp"]["previous_fetch_mode"], "aggregate")
|
self.assertEqual(status["capabilities"]["graylog_mcp"]["previous_fetch_mode"], "aggregate")
|
||||||
self.assertEqual(status["capabilities"]["graylog_mcp"]["call_timeout_seconds"], 8)
|
self.assertEqual(status["capabilities"]["graylog_mcp"]["call_timeout_seconds"], 8)
|
||||||
self.assertEqual(status["capabilities"]["graylog_mcp"]["poll_timeout_seconds"], 120)
|
self.assertEqual(status["capabilities"]["graylog_mcp"]["poll_timeout_seconds"], 120)
|
||||||
|
self.assertEqual(status["configuration"]["enabled_streams"], 1)
|
||||||
|
self.assertEqual(status["stream_coverage"][0]["stream_name"], "Firewall")
|
||||||
self.assertFalse(status["status_cache"]["served_from_cache"])
|
self.assertFalse(status["status_cache"]["served_from_cache"])
|
||||||
|
|
||||||
def test_write_refreshing_status_uses_last_good_cache(self):
|
def test_write_refreshing_status_uses_last_good_cache(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user