{"id":201,"date":"2026-07-09T00:00:00","date_gmt":"2026-07-08T20:30:00","guid":{"rendered":"https:\/\/www.anynet.ir\/blog\/%d8%b4%d8%b1%d9%88%d8%b9-%d8%ac%d9%85%d8%b9%d8%a2%d9%88%d8%b1%db%8c-%d8%aa%d8%a7%d8%b1%db%8c%d8%ae%da%86%d9%87-bgp-%d8%a8%d8%a7-%d8%a7%d8%b3%d8%aa%d9%81%d8%a7%d8%af%d9%87-%d8%a7%d8%b2-bmp-en\/"},"modified":"2026-07-09T00:00:00","modified_gmt":"2026-07-08T20:30:00","slug":"%d8%b4%d8%b1%d9%88%d8%b9-%d8%ac%d9%85%d8%b9%d8%a2%d9%88%d8%b1%db%8c-%d8%aa%d8%a7%d8%b1%db%8c%d8%ae%da%86%d9%87-bgp-%d8%a8%d8%a7-%d8%a7%d8%b3%d8%aa%d9%81%d8%a7%d8%af%d9%87-%d8%a7%d8%b2-bmp-en","status":"publish","type":"post","link":"https:\/\/www.anynet.ir\/blog\/en\/%d8%b4%d8%b1%d9%88%d8%b9-%d8%ac%d9%85%d8%b9%d8%a2%d9%88%d8%b1%db%8c-%d8%aa%d8%a7%d8%b1%db%8c%d8%ae%da%86%d9%87-bgp-%d8%a8%d8%a7-%d8%a7%d8%b3%d8%aa%d9%81%d8%a7%d8%af%d9%87-%d8%a7%d8%b2-bmp-en\/","title":{"rendered":"Let&#8217;s Start Collecting BGP History with BMP"},"content":{"rendered":"<div><\/div>\n<div>\n<div><\/div>\n<\/div>\n<div>\n<div>\n<div>\n<p>I have been troubleshooting service-provider network issues for more than 25<br \/>\nyears. A lot has changed in that time. Service-provider networks moved from<br \/>\nIOS-based 7200\/7500 platforms to IOS XR on ASR 9000 and CRS, then to NCS 5500<br \/>\nand newer platforms. Routers reached terabit-scale forwarding rates and routing<br \/>\ntables grew to millions of routes.<\/p>\n<p>Despite that evolution, some operational questions are still hard to answer:<\/p>\n<ul>\n<li>What was the next hop for a particular BGP route two days ago at 14:15 CET?<\/li>\n<li>Which communities did a route carry during a reported outage?<\/li>\n<li>What was the egress label, forwarding state, or route attribute at a specific<br \/>\nmoment in time?<\/li>\n<li>When exactly did a route start flapping, and which peer did the updates come<br \/>\nfrom?<\/li>\n<\/ul>\n<p>These are questions about the past state of the network. Without historical BGP<br \/>\nstate, they are still difficult to answer. Absence of historical information forces<br \/>\nthe networking engineer to guess or come up with possible theories instead of<br \/>\nrelying on facts.<\/p>\n<p>This project offers a working BMP collecting and storing pipeline, it also offers<br \/>\na web UI showing how collected BGP historical information can be used for basic<br \/>\nanalytical purposes.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Why Traditional Methods Fall Short<\/h2>\n<p>Modern network operating systems produce much richer traces than the old syslog<br \/>\nand console messages many of us grew up with. Those traces are useful, but they<br \/>\nare not a complete answer to historical route-state analysis.<\/p>\n<p>Traces have several practical limitations:<\/p>\n<ul>\n<li>They often require a network engineer to manually search through large volumes<br \/>\nof data.<\/li>\n<li>They are usually written for developers and protocol owners, not for quick<br \/>\noperational route-history queries.<\/li>\n<li>They can produce a significant amount of data without presenting the BGP state<br \/>\nin the shape an operator needs.<\/li>\n<\/ul>\n<p>Another common approach is collecting route information with scripts that run<br \/>\nCLI commands and scrape the output. This does not scale well in modern networks.<br \/>\nThe output of detailed BGP commands can be large, command formats can change<br \/>\nbetween releases, and text scraping is both expensive and fragile. On a scaled<br \/>\nrouter, a detailed route command can take tens of minutes to complete.<\/p>\n<p>Streaming telemetry and gRPC-based approaches can be reliable and efficient,<br \/>\nespecially when they support event-driven publishing of route updates. The<br \/>\nchallenge is consistency: support varies across BGP speaker implementations and<br \/>\nsoftware versions.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Why BMP Fits<\/h2>\n<p>BGP Monitoring Protocol (BMP) is designed for this kind of problem. It is a<br \/>\nstandardized way to monitor BGP sessions and obtain route views from BGP<br \/>\nspeakers. BMP is defined in <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc7854.html\" style=\"color: rgb(0, 102, 204)\">RFC 7854<\/a>.<\/p>\n<p>BMP is not a routing protocol. It is a monitoring protocol. A BMP collector can<br \/>\nreceive an initial view of monitored BGP routes and then continue receiving<br \/>\nincremental route updates, peer-up events, peer-down events, and statistics.<\/p>\n<p>The exact visibility depends on the BGP speaker implementation, BMP<br \/>\nconfiguration, and whether pre-policy, post-policy, or both views are exported.<br \/>\nIn many service-provider designs, connecting BMP collectors to route reflectors<br \/>\nprovides broad visibility into the BGP domain because route reflectors already<br \/>\nobserve a large portion of the BGP update stream.<\/p>\n<p>That makes BMP a natural source for route-history collection.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">From BMP Stream to Queryable History<\/h2>\n<p>Collecting BMP messages is only the first step. To answer operational questions,<br \/>\nthe data needs to be parsed, normalized, persisted, and made queryable.<\/p>\n<p>This solution uses &#8220;processing pipeline&#8221; approach, where each processing stage<br \/>\nis responsible for a very specific set of actions. Starting from the producer of BMP<br \/>\ninformation and all the way down to the consumer of stored histprical information,<br \/>\neach stage receives, validates, mutates and passes the information to the next stage<br \/>\nto make it a reliable source, undisputable fact of the life cycle of a bgp route.<\/p>\n<p>Below diagram gives a visual represention of the components and information flow.<\/p>\n<pre><code><span>Routers \/ Route Reflectors\n<\/span><span> |\n<\/span><span> | BMP (RFC 7854)\n<\/span><span> v\n<\/span><span> +---------+\n<\/span><span> | GoBMP | parses BMP and publishes JSON\n<\/span><span> +----+----+\n<\/span><span> |\n<\/span><span> | Kafka topics (gobmp.parsed.*)\n<\/span><span> v\n<\/span><span>+----------------------------------+\n<\/span><span>| GoBMP-MongoDB Connector |\n<\/span><span>| |\n<\/span><span>| Kafka consumer |\n<\/span><span>| consumes per-AFI\/SAFI topics |\n<\/span><span>| |\n<\/span><span>| MongoDB writer |\n<\/span><span>| stores current route state |\n<\/span><span>| stores route event history |\n<\/span><span>| tracks statistics and damping |\n<\/span><span>+----------------+-----------------+\n<\/span><span> |\n<\/span><span> v\n<\/span><span> MongoDB\n<\/span><span> |\n<\/span><span> v\n<\/span><span> Queries, dashboards, reports,\n<\/span><span> correlation, alerting, analytics\n<\/span><\/code><\/pre>\n<p>GoBMP handles the BMP parsing and publishes structured JSON route documents to<br \/>\nKafka, so it acts as a producer of translated BGP\/BMP messages.<br \/>\nGoBMP-MongoDB Connector consumes those Kafka topics and updates MongoDB.<br \/>\nThe most important result is not a particular screen or workflow. It is a<br \/>\npersistent, queryable history of BGP state.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">What GoBMP-MongoDB Connector Stores<\/h2>\n<p>For each route, MongoDB keeps the current state and the event history. That makes<br \/>\nit possible to ask both &#8220;what is the state now?&#8221; and &#8220;how did this state change<br \/>\nover time?&#8221;<\/p>\n<p>The stored data includes route identity, peer information, BMP source, path ID,<br \/>\nBGP attributes, timestamps, and history entries. For VPN routes, the Route Distinguisher<br \/>\nis part of the route identity, which makes VRF-level inspection possible.<\/p>\n<p>The connector also keeps route instability data. It tracks withdrawals,<br \/>\nannouncements, attribute changes, and BGP route dampening metrics so operators<br \/>\ncan quickly find unstable or frequently changing prefixes.<\/p>\n<p>Below is the list of supported and stored address families:<\/p>\n<ul>\n<li>IPv4 unicast<\/li>\n<li>IPv6 unicast<\/li>\n<li>VPNv4<\/li>\n<li>VPNv6<\/li>\n<\/ul>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Why Kafka Is in the Middle<\/h2>\n<p>Kafka gives the pipeline a useful separation between collection and storage.<br \/>\nGoBMP can focus on parsing BMP and publishing route messages. The MongoDB<br \/>\nconnector can focus on consuming those messages, preserving ordering where it<br \/>\nmatters, and writing route state to the database.<\/p>\n<p>This separation also makes the system easier to evolve. Additional consumers can<br \/>\nsubscribe to the same topics without changing the BMP collection layer. Operators<br \/>\ncan decide whether they need one downstream consumer or several, depending on<br \/>\ntheir analytics, monitoring, or archival needs.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">What Operators Can Answer<\/h2>\n<p>Once route information is stored, the troubleshooting workflow changes. Instead<br \/>\nof searching through traces or trying to reproduce a past failure, an operator<br \/>\ncan query the history directly.<\/p>\n<p>Examples:<\/p>\n<ul>\n<li>Show me the state of <code>45.8.233.0\/24<\/code> in the <code>unicast_prefix_v4<\/code> collection at a<br \/>\nspecific timestamp.<\/li>\n<li>Show every update for a VPNv4 route in a particular Route Distinguisher.<\/li>\n<li>List the routes with the highest withdrawal count in the last hour.<\/li>\n<li>Compare route history across peers.<\/li>\n<li>Find when a route&#8217;s next hop, label, AS path, or community list changed.<\/li>\n<\/ul>\n<p>The dashboard included with <code>GoBMP-MongoDB Connector<\/code> is one example of how this<br \/>\ndata can be used. It focuses on common operational questions such as<br \/>\nflapping-route analysis, recent route changes, peer statistics, route search, and<br \/>\nroute details.<\/p>\n<p>But the dashboard is not the centerpiece. The centerpiece is the collected BGP<br \/>\nhistory. Once the data exists, teams can build the analytics that make sense for<br \/>\ntheir environment: dashboards, reports, anomaly detection, incident timelines,<br \/>\ncapacity studies, peer comparisons, route-policy validation, or integrations<br \/>\nwith existing observability platforms.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">The Main Point<\/h2>\n<p>If we want to answer questions about past BGP state, we need to collect that<br \/>\nstate before, during and after the outage happens.<\/p>\n<p>BMP gives us a practical source of BGP route updates. GoBMP turns BMP messages<br \/>\ninto structured data. Kafka gives us a transport layer between producers and<br \/>\nconsumers. MongoDB gives us persistent route history. The<br \/>\n<code>GoBMP-MongoDB Connector<\/code> ties those parts together and turns a stream of route<br \/>\nupdates into a durable dataset that operators and automation systems can query,<br \/>\ncorrelate, and analyze.<\/p>\n<p>No data, no analytics. Once the route history exists, the questions that used to<br \/>\nbe difficult become database queries.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Availability<\/h2>\n<p><code>GoBMP-MongoDB Connector<\/code> is available as a docker container at the docker hub at<br \/>\ndocker.io\/sbezverk\/gobmp-mongodb-connector<\/p>\n<p>. If you would like to discuss the<br \/>\nwork, or get the docker compose file for the test environment, please contact me<br \/>\ndirectly at <a href=\"https:\/\/xrdocs.io\/cdn-cgi\/l\/email-protection#a4d7c6c1ded2c1d6cfe4c7cdd7c7cb8ac7cbc9\" style=\"color: rgb(0, 102, 204)\"><span data-cfemail=\"512233342b2734233a11323822323e7f323e3c\">[email&nbsp;protected]<\/span><\/a> or use the GoBMP Google<br \/>\nGroup at <a href=\"https:\/\/xrdocs.io\/cdn-cgi\/l\/email-protection#f69199949b86b6919999919a93918499838685d895999b\" style=\"color: rgb(0, 102, 204)\"><span data-cfemail=\"086f676a6578486f67676f646d6f7a677d787b266b6765\">[email&nbsp;protected]<\/span><\/a>.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Example Lab Topology<\/h2>\n<p>For the examples in this post, I am using a small lab where routes are injected<br \/>\ninto a Cisco XRd instance, exported through BMP, parsed by GoBMP, delivered<br \/>\nthrough Kafka, and stored by <code>GoBMP-MongoDB Connector<\/code> in MongoDB.<\/p>\n<pre><code><span>bgpinjector\n<\/span><span>(RIS Live and manual injection)\n<\/span><span> |\n<\/span><span> v\n<\/span><span>Cisco XRd 26.2.1\n<\/span><span> |\n<\/span><span> v\n<\/span><span>GoBMP collector\n<\/span><span> |\n<\/span><span> v\n<\/span><span>Kafka\n<\/span><span> |\n<\/span><span> v\n<\/span><span>GoBMP-MongoDB Connector\n<\/span><span> |\n<\/span><span> v\n<\/span><span>MongoDB\n<\/span><\/code><\/pre>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Lab Environment and Performance Notes<\/h2>\n<p>In this lab, <code>bgpinjector<\/code> consumed the RIS Live stream and also supported<br \/>\nmanual route injection. During the test, the pipeline processed roughly 1,500<br \/>\nroute events per second. MongoDB was deployed as a single-shard replica set in<br \/>\nthe same lab environment.<\/p>\n<p>A single VM (16GB RAM, 8 vCPUs) setup which was used for this test bed, is<br \/>\nuseful for demonstrating the data model and validating the collection pipeline<br \/>\nunder a meaningful event rate. It should NOT be treated as a recommended<br \/>\nproduction layout.<\/p>\n<p>For an environment closer to production, plan for at least a three-VM<br \/>\ndeployment. Kafka should be able to run with broker replication, and MongoDB<br \/>\nshould be able to run in its normal distributed form: sharded where required,<br \/>\nwith replica sets providing redundancy. The final sizing depends on peer count,<br \/>\nroute scale, event rate, retention period, indexing strategy, and query<br \/>\nworkload. Disk space is mostly controlled by the desired retention policy and<br \/>\nshould be calculated with that policy in mind.<\/p>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Example Visualization<\/h2>\n<p>The included dashboard is one example consumer of the collected route-history<br \/>\ndata. It is intentionally not the only way to use the dataset, but it helps show<br \/>\nhow common operational questions can be presented quickly.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.anynet.ir\/blog\/wp-content\/uploads\/2026\/10\/unicast_v4_main_page.webp\" alt=\"Unicast IPv4 route history dashboard example\"><\/p>\n<p>The same data model also supports VPN routes where the Route Distinguisher is<br \/>\npart of the route identity.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.anynet.ir\/blog\/wp-content\/uploads\/2026\/10\/vpnv4_main_page.webp\" alt=\"VPNv4 route history dashboard example\"><\/p>\n<blockquote>\n<p><strong style=\"color: rgb(26, 26, 26)\">Let&#8217;s stop asking engineers to do machine work by hand, and start using<br \/>\ncollected BGP history as a source of facts.<\/strong><\/p>\n<\/blockquote>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Appendix A: Sample of BGP configuration of XRD instance used in the test bed<\/h2>\n<pre><code><span>route-policy pass-all\n<\/span><span> pass\n<\/span><span>end-policy\n<\/span><span>!\n<\/span><span>router bgp 5070\n<\/span><span> bgp router-id 1.1.1.1\n<\/span><span># Activating all address families we want to support \n<\/span><span> address-family ipv4 unicast\n<\/span><span> label mode per-vrf\n<\/span><span> redistribute connected\n<\/span><span>!\n<\/span><span> address-family vpnv4 unicast\n<\/span><span> retain route-target all\n<\/span><span>!\n<\/span><span> address-family ipv6 unicast\n<\/span><span> redistribute connected\n<\/span><span>!\n<\/span><span> address-family vpnv6 unicast\n<\/span><span> retain route-target all\n<\/span><span>!\n<\/span><span># BGP peer connection to bgpinjecor process\n<\/span><span> neighbor 10.2.1.5\n<\/span><span> remote-as 50123\n<\/span><span> ebgp-multihop 254\n<\/span><span> tcp mtu-discovery\n<\/span><span># Activating BMP server to send all BGP updates \n<\/span><span># received from bgpinjector towards GoBMP collector\n<\/span><span> bmp-activate server 1\n<\/span><span> update-source GigabitEthernet0\/0\/0\/1\n<\/span><span> address-family ipv4 unicast\n<\/span><span> route-policy pass-all in\n<\/span><span> route-policy pass-all out\n<\/span><span>!\n<\/span><span> address-family ipv4 labeled-unicast\n<\/span><span> route-policy pass-all in\n<\/span><span> route-policy pass-all out\n<\/span><span>!\n<\/span><span> address-family vpnv4 unicast\n<\/span><span> route-policy pass-all in\n<\/span><span> route-policy pass-all out\n<\/span><span>!\n<\/span><span> address-family ipv6 unicast\n<\/span><span> route-policy pass-all in\n<\/span><span> route-policy pass-all out\n<\/span><span>!\n<\/span><span> address-family vpnv6 unicast\n<\/span><span> route-policy pass-all in\n<\/span><span> route-policy pass-all out\n<\/span><span>!\n<\/span><span>!\n<\/span><span>!\n<\/span><span># Configure BMP collector\n<\/span><span>bmp server 1\n<\/span><span> host 10.1.1.2 port 5000\n<\/span><span>!\n<\/span><\/code><\/pre>\n<h2 style=\"color: rgb(26, 26, 26); font-weight: 700\">Appendix B: MongoDB Query Examples<\/h2>\n<p>The following <code>mongosh<\/code> queries are draft examples for the lab data. They use the<br \/>\nroute <code>45.8.233.0\/24<\/code> in the <code>unicast_prefix_v4<\/code> collection.<\/p>\n<p>This appendix keeps two representative examples in the main post. The full query<br \/>\nset and result excerpts are available in the<br \/>\n<a href=\"https:\/\/github.com\/sbezverk\/gobmp-mongodb-connector-supplements\/blob\/main\/mongodb-query-examples-and-results.md\" style=\"color: rgb(0, 102, 204)\">gobmp-mongodb-connector-supplements repository<\/a>.<\/p>\n<p>Before running the examples, set the database, collection, route, and time-window<br \/>\nvariables:<\/p>\n<pre><code><span>use gobmp_history\n<\/span><span><span>var<\/span> routeColl <span>=<\/span> <span>\"unicast_prefix_v4\"<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> eventColl <span>=<\/span> routeColl <span>+<\/span> <span>\"_events\"<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> routePrefix <span>=<\/span> <span>\"45.8.233.0\"<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> routeLen <span>=<\/span> <span>24<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> since <span>=<\/span> <span>new<\/span> <span>Date<\/span><span>(<\/span><span>Date<\/span><span>.<\/span><span>now<\/span><span>(<\/span><span>)<\/span> <span>-<\/span> <span>60<\/span> <span>*<\/span> <span>60<\/span> <span>*<\/span> <span>1000<\/span><span>)<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> until <span>=<\/span> <span>new<\/span> <span>Date<\/span><span>(<\/span><span>)<\/span><span>;<\/span>\n<\/span><span><span>\/\/ Fill these in after the first lookup query.<\/span>\n<\/span><span><span>var<\/span> peer <span>=<\/span> <span>\"10.2.1.5\"<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> bmpSource <span>=<\/span> <span>\"10.2.1.3\"<\/span><span>;<\/span>\n<\/span><span><span>var<\/span> pathID <span>=<\/span> <span>0<\/span><span>;<\/span>\n<\/span><span><span>\/\/ Pick the timestamp you want to inspect. This example is just before the<\/span>\n<\/span><span><span>\/\/ peer-down withdrawal seen in the sample output below.<\/span>\n<\/span><span><span>var<\/span> at <span>=<\/span> <span><span>ISODate<\/span><\/span><span>(<\/span><span>\"2026-07-07T02:17:57.500Z\"<\/span><span>)<\/span><span>;<\/span>\n<\/span><\/code><\/pre>\n<h3 style=\"color: rgb(26, 26, 26); font-weight: 700\">Find Stored Instances of the Route<\/h3>\n<p>Use this first to discover which peers, BMP sources, and path IDs currently have<br \/>\ndocuments for <code>45.8.233.0\/24<\/code>.<\/p>\n<pre><code><span>db<span>.<\/span><span>getCollection<\/span><span>(<\/span>routeColl<span>)<\/span><span>.<\/span><span>find<\/span><span>(<\/span>\n<\/span><span> <span>{<\/span>\n<\/span><span> <span>\"_id.pfx\"<\/span><span>:<\/span> routePrefix<span>,<\/span>\n<\/span><span> <span>\"_id.len\"<\/span><span>:<\/span> routeLen\n<\/span><span> <span>}<\/span><span>,<\/span>\n<\/span><span> <span>{<\/span>\n<\/span><span> <span>_id<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>current_state<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>stats<\/span><span>:<\/span> <span>1<\/span>\n<\/span><span> <span>}<\/span>\n<\/span><span><span>)<\/span><span>.<\/span><span>sort<\/span><span>(<\/span><span>{<\/span>\n<\/span><span> <span>\"current_state.last_update\"<\/span><span>:<\/span> <span>-<\/span><span>1<\/span>\n<\/span><span><span>}<\/span><span>)<\/span><span>.<\/span><span>pretty<\/span><span>(<\/span><span>)<\/span>\n<\/span><\/code><\/pre>\n<p>Result:<\/p>\n<pre><code><span>[\n<\/span><span> {\n<\/span><span> _id: {\n<\/span><span> pfx: '45.8.233.0',\n<\/span><span> len: 24,\n<\/span><span> peer: '10.2.1.5',\n<\/span><span> bmp_source_ip: '10.2.1.3',\n<\/span><span> path_id: 0\n<\/span><span>},\n<\/span><span> current_state: {\n<\/span><span> attributes: null,\n<\/span><span> status: 'withdrawn',\n<\/span><span> last_update: ISODate('2026-07-07T02:17:57.613Z')\n<\/span><span>},\n<\/span><span> stats: {\n<\/span><span> advertisements: 2640,\n<\/span><span> withdrawals: 313,\n<\/span><span> instability_score: 0,\n<\/span><span> dampening_penalty: 0,\n<\/span><span> is_suppressed: false,\n<\/span><span> attribute_changes: 2327\n<\/span><span>}\n<\/span><span>}\n<\/span><span>]\n<\/span><\/code><\/pre>\n<p>This route is a good example of why storing history matters. The current state<br \/>\nonly says that the route is withdrawn. The counters show much more: 2,640<br \/>\nadvertisements, 313 withdrawals, and 2,327 attribute changes were observed for<br \/>\nthis one route instance.<\/p>\n<h3 style=\"color: rgb(26, 26, 26); font-weight: 700\">Show Route State at a Specific Time<\/h3>\n<p>This query finds the last event for the selected route instance at or before<br \/>\n<code>at<\/code>. If the last event is <code>withdraw<\/code>, the route was withdrawn at that point. If<br \/>\nthe last event is <code>advertise<\/code> or <code>update<\/code>, the route was advertised at that<br \/>\npoint. For a complete attribute reconstruction, replay all prior events for the<br \/>\nselected route.<\/p>\n<pre><code><span>db<span>.<\/span><span>getCollection<\/span><span>(<\/span>eventColl<span>)<\/span><span>.<\/span><span>find<\/span><span>(<\/span>\n<\/span><span> <span>{<\/span>\n<\/span><span> <span>\"route_key.pfx\"<\/span><span>:<\/span> routePrefix<span>,<\/span>\n<\/span><span> <span>\"route_key.len\"<\/span><span>:<\/span> routeLen<span>,<\/span>\n<\/span><span> <span>\"route_key.peer\"<\/span><span>:<\/span> peer<span>,<\/span>\n<\/span><span> <span>\"route_key.bmp_source_ip\"<\/span><span>:<\/span> bmpSource<span>,<\/span>\n<\/span><span> <span>\"route_key.path_id\"<\/span><span>:<\/span> pathID<span>,<\/span>\n<\/span><span> <span>ts<\/span><span>:<\/span> <span>{<\/span> <span>$lte<\/span><span>:<\/span> at <span>}<\/span>\n<\/span><span> <span>}<\/span><span>,<\/span>\n<\/span><span> <span>{<\/span>\n<\/span><span> <span>_id<\/span><span>:<\/span> <span>0<\/span><span>,<\/span>\n<\/span><span> <span>route_key<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>ts<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>event<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>changed<\/span><span>:<\/span> <span>1<\/span><span>,<\/span>\n<\/span><span> <span>kafka<\/span><span>:<\/span> <span>1<\/span>\n<\/span><span> <span>}<\/span>\n<\/span><span><span>)<\/span><span>.<\/span><span>sort<\/span><span>(<\/span><span>{<\/span> <span>ts<\/span><span>:<\/span> <span>-<\/span><span>1<\/span><span>,<\/span> <span>_id<\/span><span>:<\/span> <span>-<\/span><span>1<\/span> <span>}<\/span><span>)<\/span><span>.<\/span><span>limit<\/span><span>(<\/span><span>1<\/span><span>)<\/span><span>.<\/span><span>pretty<\/span><span>(<\/span><span>)<\/span>\n<\/span><\/code><\/pre>\n<p>Result:<\/p>\n<pre><code><span>[\n<\/span><span> {\n<\/span><span> route_key: {\n<\/span><span> pfx: '45.8.233.0',\n<\/span><span> len: 24,\n<\/span><span> peer: '10.2.1.5',\n<\/span><span> bmp_source_ip: '10.2.1.3',\n<\/span><span> path_id: 0\n<\/span><span>},\n<\/span><span> ts: ISODate('2026-07-07T02:17:57.467Z'),\n<\/span><span> event: 'update',\n<\/span><span> changed: {\n<\/span><span> as_path: [ Long('50123'), Long('58308'), Long('29075'), Long('41765')],\n<\/span><span> community_list: [\n<\/span><span> '41765:8000',\n<\/span><span> '41765:9400',\n<\/span><span> '51706:64601',\n<\/span><span> '51706:64650',\n<\/span><span> '51706:65011',\n<\/span><span> '51706:65012'\n<\/span><span>]\n<\/span><span>},\n<\/span><span> kafka: {\n<\/span><span> topic: 'gobmp.parsed.unicast_prefix_v4',\n<\/span><span> partition: 1,\n<\/span><span> offset: Long('2520143')\n<\/span><span>}\n<\/span><span>}\n<\/span><span>]\n<\/span><\/code><\/pre>\n<p>With <code>at = ISODate(\"2026-07-07T02:17:57.500Z\")<\/code>, the last event before that<br \/>\ntimestamp is the <code>update<\/code> at <code>2026-07-07T02:17:57.467Z<\/code>. That means the route<br \/>\nwas still advertised just before the <code>2026-07-07T02:17:57.613Z<\/code> peer-down<br \/>\nwithdrawal. The event also shows the AS path, communities, Kafka topic,<br \/>\npartition, and offset associated with that observation.<\/p>\n<div title=\"\u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0644 \u0627\u06cc\u0646 \u0628\u062e\u0634\" style=\"display: flex\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><\/svg><\/div>\n<div title=\"\u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0644 \u0627\u06cc\u0646 \u0628\u062e\u0634\" style=\"display: flex\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><\/svg><\/div>\n<div title=\"\u0627\u0646\u062a\u062e\u0627\u0628 \u06a9\u0644 \u0627\u06cc\u0646 \u0628\u062e\u0634\" style=\"display: flex\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><\/svg><\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I have been troubleshooting service-provider network issues for more than 25 years. A lot has changed in that time. Service-provider networks moved from IOS-based\u2026<\/p>\n","protected":false},"author":1,"featured_media":199,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[142,130,139,69,43],"tags":[],"class_list":["post-201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics-en","category-bgp-en","category-bmp-en","category-iosxr-en-en","category-networking-en"],"_links":{"self":[{"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/posts\/201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":0,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/media\/199"}],"wp:attachment":[{"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.anynet.ir\/blog\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}