423 lines
9.3 KiB
Markdown
423 lines
9.3 KiB
Markdown
# BGP Region Aggregation Plan
|
|
|
|
## Goal
|
|
|
|
This document refines the current BGP `activity layer` into an implementation-ready regional aggregation design.
|
|
|
|
Primary product goal:
|
|
|
|
- turn sparse prefix-level observations, anomalies, and incidents into a readable `regional observability layer`
|
|
- keep Earth visually alive during low-incident periods
|
|
- make `incident markers` remain the highest-confidence foreground layer instead of replacing them
|
|
|
|
This layer is not a new collector, detector, or raw storage table.
|
|
It is an aggregation/view-model layer:
|
|
|
|
`observations -> enrichment -> anomalies/incidents -> geography mapping -> region aggregation -> Earth/UI activity layer`
|
|
|
|
## Why This Layer Exists
|
|
|
|
Current product gap from [bgp-context.md](/home/ray/dev/linkong/planet/docs/bgp-context.md):
|
|
|
|
- incident density is naturally low
|
|
- anomaly density is higher, but still not enough to keep the globe expressive all the time
|
|
- collector presence alone proves coverage, but does not communicate `where routing is currently active or noisy`
|
|
|
|
So the missing middle layer is:
|
|
|
|
- `collectors` show that observation exists
|
|
- `regions` show where activity is building up
|
|
- `incidents` show the specific high-confidence focus events
|
|
|
|
## Scope
|
|
|
|
This plan is specifically for:
|
|
|
|
- a backend aggregation service
|
|
- a summary API for console/stats
|
|
- a GeoJSON API for Earth rendering
|
|
- an Earth background activity layer that supports, but does not replace, incident markers
|
|
|
|
This plan does not attempt to solve:
|
|
|
|
- exact prefix geolocation quality
|
|
- polygon-heavy geopolitical visualization
|
|
- persistent materialized region tables in v1
|
|
|
|
## Region Layer Definition
|
|
|
|
Recommended conceptual model:
|
|
|
|
- `region layer` = background situational awareness
|
|
- `incident layer` = focal event markers
|
|
|
|
That means:
|
|
|
|
- region activity should answer `where is routing behavior currently active or abnormal`
|
|
- incident markers should answer `which concrete event should the user click`
|
|
|
|
## Recommended Output Model
|
|
|
|
Suggested backend output object:
|
|
|
|
## `BGPRegionActivity`
|
|
|
|
```json
|
|
{
|
|
"region_key": "sea",
|
|
"region_name": "Southeast Asia",
|
|
"center_lat": 1.3521,
|
|
"center_lon": 103.8198,
|
|
"observation_count": 128,
|
|
"anomaly_count": 9,
|
|
"incident_count": 2,
|
|
"activity_score": 17.6,
|
|
"status": "incident",
|
|
"affected_prefix_count": 14,
|
|
"affected_asn_count": 6,
|
|
"collector_count": 5,
|
|
"first_seen_at": "2026-04-02T10:00:00Z",
|
|
"last_seen_at": "2026-04-02T10:12:00Z"
|
|
}
|
|
```
|
|
|
|
### Fields To Keep In MVP
|
|
|
|
- `region_key`
|
|
- `region_name`
|
|
- `center_lat`
|
|
- `center_lon`
|
|
- `observation_count`
|
|
- `anomaly_count`
|
|
- `incident_count`
|
|
- `activity_score`
|
|
- `status`
|
|
- `affected_prefix_count`
|
|
- `affected_asn_count`
|
|
- `collector_count`
|
|
- `first_seen_at`
|
|
- `last_seen_at`
|
|
|
|
### Fields To Delay
|
|
|
|
These are useful, but not required for the first implementation:
|
|
|
|
- `bounding_box`
|
|
- `top_incident_types`
|
|
- `top_prefixes`
|
|
- polygon geometry
|
|
|
|
## Region Definition Strategy
|
|
|
|
### Recommendation
|
|
|
|
Use a static region-definition table first.
|
|
|
|
Examples:
|
|
|
|
- `north_america`
|
|
- `south_america`
|
|
- `western_europe`
|
|
- `eastern_europe`
|
|
- `east_asia`
|
|
- `southeast_asia`
|
|
- `south_asia`
|
|
- `middle_east`
|
|
- `north_africa`
|
|
- `sub_saharan_africa`
|
|
- `oceania`
|
|
|
|
Why this is the right v1 choice:
|
|
|
|
- stable UI semantics
|
|
- strong readability on Earth
|
|
- easier debugging and explanation
|
|
- lower implementation cost than geohash or H3 grids
|
|
|
|
### Not Recommended For V1
|
|
|
|
- geohash cell aggregation
|
|
- H3 aggregation
|
|
- fine-grained lat/lon bucket maps
|
|
|
|
Those are more flexible, but they make the map feel fragmented and less explainable.
|
|
|
|
## Geography Mapping Strategy
|
|
|
|
Do not reduce the implementation to only `prefix -> exact geo`.
|
|
|
|
The region layer should follow the same geography-priority logic already implied by the current BGP direction:
|
|
|
|
1. `prefix_geography`
|
|
2. `prefix_scope`
|
|
3. `ASN organization region`
|
|
4. `collector centroid` fallback
|
|
|
|
This matters because exact prefix geography will often be incomplete or approximate.
|
|
The region layer should stay robust even when only partial enrichment is available.
|
|
|
|
## Backend Design
|
|
|
|
Recommended new service file:
|
|
|
|
- [backend/app/services/bgp_regions.py](/home/ray/dev/linkong/planet/backend/app/services/bgp_regions.py)
|
|
|
|
Suggested responsibilities:
|
|
|
|
- `map_record_to_region(...)`
|
|
- `aggregate_region_activity(...)`
|
|
- `build_region_geojson(...)`
|
|
- `resolve_activity_status(...)`
|
|
- `compute_activity_score(...)`
|
|
|
|
### Data Source Inputs
|
|
|
|
Use a recent rolling window, default `15 minutes`, and aggregate from:
|
|
|
|
- `BGPObservation`
|
|
- `BGPAnomaly`
|
|
- active `BGPIncident`
|
|
|
|
### Aggregation Flow
|
|
|
|
1. query observations in the time window
|
|
2. query anomalies in the same window
|
|
3. query active incidents in the same window or active status set
|
|
4. resolve each record to a best-effort region
|
|
5. accumulate per-region counters
|
|
6. compute score and status
|
|
7. return region activity list
|
|
|
|
## Status Model
|
|
|
|
Recommended status buckets:
|
|
|
|
- `idle`
|
|
- `observing`
|
|
- `anomaly`
|
|
- `incident`
|
|
|
|
Suggested rule:
|
|
|
|
```text
|
|
if incident_count > 0: incident
|
|
elif anomaly_count > 0: anomaly
|
|
elif observation_count > 0: observing
|
|
else: idle
|
|
```
|
|
|
|
This aligns well with the current Earth status language and keeps the visual mapping simple.
|
|
|
|
## Activity Score
|
|
|
|
The score should be a tunable heuristic, not a fixed truth model.
|
|
|
|
Recommended v1 formula:
|
|
|
|
```text
|
|
activity_score =
|
|
min(observation_count, 50) * 0.03
|
|
+ anomaly_count * 1.2
|
|
+ incident_count * 5.0
|
|
```
|
|
|
|
Why cap observations:
|
|
|
|
- observation volume is usually much larger than anomaly or incident volume
|
|
- uncapped observation counts would overwhelm the score
|
|
- capped observation counts preserve baseline presence without drowning real abnormality
|
|
|
|
### Practical Guidance
|
|
|
|
- treat coefficients as configuration-like constants
|
|
- expect to retune after looking at real data
|
|
- keep `incident` weight dominant
|
|
|
|
## API Design
|
|
|
|
### 1. Summary/List API
|
|
|
|
Suggested endpoint:
|
|
|
|
- `/api/v1/bgp/regions/activity`
|
|
|
|
Response shape:
|
|
|
|
```json
|
|
{
|
|
"window_minutes": 15,
|
|
"regions": []
|
|
}
|
|
```
|
|
|
|
Use cases:
|
|
|
|
- BGP console summaries
|
|
- right-side Earth stats
|
|
- future region list panels
|
|
|
|
### 2. GeoJSON API
|
|
|
|
Suggested endpoint:
|
|
|
|
- `/api/v1/visualization/geo/bgp-regions`
|
|
|
|
Response shape:
|
|
|
|
```json
|
|
{
|
|
"type": "FeatureCollection",
|
|
"features": []
|
|
}
|
|
```
|
|
|
|
Each feature should include:
|
|
|
|
- `geometry`
|
|
- v1: `Point`
|
|
- later: optional `Polygon`
|
|
- `properties`
|
|
- `region_key`
|
|
- `region_name`
|
|
- `status`
|
|
- `activity_score`
|
|
- `observation_count`
|
|
- `anomaly_count`
|
|
- `incident_count`
|
|
- `affected_prefix_count`
|
|
- `affected_asn_count`
|
|
- `collector_count`
|
|
|
|
## Earth Rendering Plan
|
|
|
|
Detailed visual layering guidance is expanded in [bgp-earth-rendering-plan.md](/home/ray/dev/linkong/planet/docs/bgp-earth-rendering-plan.md).
|
|
|
|
### Layer Relationship
|
|
|
|
- `region layer` = ambient background activity
|
|
- `incident marker` = focal event object
|
|
|
|
Do not replace incident markers with region markers.
|
|
|
|
### Region Visual Rules
|
|
|
|
Suggested mapping:
|
|
|
|
- `observing`
|
|
- weak glow
|
|
- low pulse or no pulse
|
|
- `anomaly`
|
|
- stronger glow
|
|
- more visible pulse
|
|
- `incident`
|
|
- strongest regional emphasis
|
|
- but still visually secondary to the incident marker itself
|
|
|
|
### Region Labels
|
|
|
|
Good v2 enhancement:
|
|
|
|
- show region name
|
|
- show counts like `2 incidents / 5 anomalies`
|
|
|
|
This is useful, but should come after the core aggregation and Earth glow layer are working.
|
|
|
|
## Interaction Model
|
|
|
|
### Click Region
|
|
|
|
Recommended detail payload:
|
|
|
|
- region name
|
|
- observation/anomaly/incident counts in the selected window
|
|
- affected prefix count
|
|
- affected ASN count
|
|
- collector count
|
|
- recent incidents in the region
|
|
|
|
### Click Incident
|
|
|
|
Keep the current incident-detail flow.
|
|
|
|
Interaction should feel hierarchical:
|
|
|
|
1. region gives situational context
|
|
2. incident gives event focus
|
|
|
|
## MVP Implementation Order
|
|
|
|
### Step 1
|
|
|
|
Define static `REGIONS` in code or config.
|
|
|
|
### Step 2
|
|
|
|
Map geography-enriched BGP records into regions using the fallback chain.
|
|
|
|
### Step 3
|
|
|
|
Aggregate recent window counts:
|
|
|
|
- `observation_count`
|
|
- `anomaly_count`
|
|
- `incident_count`
|
|
|
|
### Step 4
|
|
|
|
Compute `activity_score` and `status`.
|
|
|
|
### Step 5
|
|
|
|
Expose:
|
|
|
|
- `/api/v1/bgp/regions/activity`
|
|
- `/api/v1/visualization/geo/bgp-regions`
|
|
|
|
### Step 6
|
|
|
|
Render region glows on Earth behind incident markers.
|
|
|
|
## Out Of Scope For MVP
|
|
|
|
- persistent materialized region tables
|
|
- geohash or H3 support
|
|
- polygon-filled regional overlays
|
|
- detailed top-prefix ranking in the first release
|
|
- complicated scoring personalization
|
|
|
|
## Risks And Constraints
|
|
|
|
### Geography Quality
|
|
|
|
Prefix geography is approximate and incomplete.
|
|
The region layer must tolerate fallback-based placement.
|
|
|
|
### Query Cost
|
|
|
|
Dynamic aggregation is the right v1 choice, but repeated short-window queries may eventually need:
|
|
|
|
- in-process caching
|
|
- scheduled pre-aggregation
|
|
- materialized summaries
|
|
|
|
### UI Overcrowding
|
|
|
|
If region glow, collector activity, and incidents all become too strong at once, Earth readability will regress.
|
|
The region layer must remain supportive, not dominant.
|
|
|
|
## Final Recommendation
|
|
|
|
The current BGP roadmap should explicitly add:
|
|
|
|
- `region aggregation` as the concrete implementation of the missing `activity layer`
|
|
|
|
The recommended product interpretation is:
|
|
|
|
- `collectors` prove observation coverage
|
|
- `regions` communicate live routing activity and abnormality
|
|
- `incidents` remain the clearest high-confidence event objects
|
|
|
|
In one sentence:
|
|
|
|
`region aggregation is not a replacement for incidents; it is the situational background that makes sparse incidents feel legible on Earth.`
|