"description":"Network-operations overview — answers 'is the network healthy right now?' at a glance. Counts come from stats_* aggregate tables so the dashboard stays fast at production scale.",
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"Routers\" FROM routers","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"Routers Down\" FROM routers WHERE state != 'up'","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"Peers Up\" FROM bgp_peers WHERE isprepolicy = true AND state = 'up'","refId":"A"}],
"description":"BGP peers that went down within the selected time range. Investigate any non-zero value. (Removed/decommissioned peers fall outside the range and are not counted.)",
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"Peers Down\" FROM bgp_peers WHERE isprepolicy = true AND state != 'up' AND $__timeFilter(timestamp)","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"Flaps (1h)\" FROM peer_event_log WHERE state = 'down' AND timestamp > NOW() - INTERVAL '1 hour'","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, COALESCE(SUM(updates),0) AS \"RIB Updates (5m)\" FROM stats_chg_bypeer WHERE interval_time > NOW() - INTERVAL '5 minutes'","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT NOW() AS time, count(*) AS \"RPKI Invalid\"\nFROM ip_rib r\nJOIN base_attrs ba ON ba.hash_id = r.base_attr_hash_id\nWHERE r.iswithdrawn = false AND r.isipv4 = true\n AND EXISTS (SELECT 1 FROM rpki_validator rv WHERE rv.prefix >>= r.prefix AND rv.origin_as != ba.origin_as)\n AND NOT EXISTS (SELECT 1 FROM rpki_validator rv WHERE rv.prefix >>= r.prefix AND rv.origin_as = ba.origin_as AND r.prefix_len <= rv.prefix_len_max)","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT\n $__timeGroupAlias(e.timestamp,'1m'),\n COALESCE(p.name, p.peer_addr::text) AS metric,\n CASE WHEN e.state = 'up' THEN 1 ELSE 0 END AS \"value\"\nFROM peer_event_log e\nJOIN bgp_peers p ON p.hash_id = e.peer_hash_id\nWHERE $__timeFilter(e.timestamp)\nORDER BY 1, 2","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"time_series","rawSql":"SELECT\n $__timeGroupAlias(interval_time,'5m'),\n SUM(updates) AS \"Updates\",\n SUM(withdraws) AS \"Withdraws\"\nFROM stats_chg_bypeer\nWHERE $__timeFilter(interval_time)\nGROUP BY 1\nORDER BY 1","refId":"A"}],
"description":"Peers that went down within the selected time range. Empty is healthy. Widen the time range to see longer-standing issues. Click a peer to open Peer Detail.",
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"table","rawSql":"SELECT\n p.hash_id AS peer_hash_id,\n COALESCE(p.name, p.peer_addr::text) AS \"Peer\",\n p.peer_addr AS \"Address\",\n p.peer_as AS \"AS\",\n p.state AS \"State\",\n p.timestamp AS \"Last Change\",\n p.error_text AS \"Reason\"\nFROM bgp_peers p\nWHERE p.isprepolicy = true AND p.state != 'up' AND $__timeFilter(p.timestamp)\nORDER BY p.timestamp DESC","refId":"A"}],
{"matcher":{"id":"byName","options":"Prefix"},"properties":[{"id":"links","value":[{"title":"Open in Prefix Explorer","url":"/d/prefix-hist/prefix-explorer?var-prefix=${__value.text}"}]}]}
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"table","rawSql":"SELECT\n r.prefix AS \"Prefix\",\n ba.origin_as AS \"Observed Origin AS\",\n rv.origin_as AS \"Authorized AS (ROA)\",\n 'Invalid' AS \"Status\"\nFROM ip_rib r\nJOIN base_attrs ba ON ba.hash_id = r.base_attr_hash_id\nJOIN rpki_validator rv ON rv.prefix >>= r.prefix AND rv.origin_as != ba.origin_as\nWHERE r.iswithdrawn = false AND r.isipv4 = true\n AND NOT EXISTS (SELECT 1 FROM rpki_validator rv2 WHERE rv2.prefix >>= r.prefix AND rv2.origin_as = ba.origin_as AND r.prefix_len <= rv2.prefix_len_max)\nORDER BY r.prefix\nLIMIT 50","refId":"A"}],
"targets":[{"datasource":{"type":"postgres","uid":"obmp_postgres"},"format":"table","rawSql":"SELECT\n timestamp AS \"Time\",\n COALESCE(interface_addr::text, '') AS \"Local\",\n COALESCE(neighbor_addr::text, '') AS \"Neighbor\",\n CASE WHEN iswithdrawn THEN 'withdrawn' ELSE 'updated' END AS \"Action\"\nFROM ls_links_log\nWHERE $__timeFilter(timestamp)\nORDER BY timestamp DESC\nLIMIT 50","refId":"A"}],