mrtkit

    BGP MRT parser and route change analyzer in MoonBit

    bgp
    mrt
    network
    parser
    Download zip
    Author
    Version
    0.2.2
    License
    Apache-2.0
    Last updated
    1 hour ago
    Downloads
    43

    No dependencies

    #MRTKit

    CI Mooncakes License

    用 MoonBit 解析 BGP MRT 档案,查询路由并分析变化。提供无第三方依赖的协议核心库和流式 CLI,适用于离线路由研究、故障复盘与教学。

    #快速开始

    需要 MoonBit(moonc ≥0.10.16)和 Node.js 22+;读取 bz2 另需 Python 3。当前固定工具链为 moonbit-toolchain.version 中的 0.10.18+6c83a7f62,构建和测试前会检查真实编译器版本。无需安装 npm 依赖。

    git clone https://github.com/prowk/mrtkit.git cd mrtkit npm run build node cli/mrtkit.mjs parse fixtures/demo.mrt node cli/mrtkit.mjs stats --threshold 3 fixtures/demo.mrt node cli/mrtkit.mjs timeline --prefix 203.0.113.0/24 fixtures/demo.mrt

    MoonBit 项目可用 moon add prowk/mrtkit@0.2.2 引入核心库。完整安装、样本解读、筛选、导出和真实档案回放见入门教程。CLI 和离线报告从源码运行。

    #功能

    • TABLE_DUMP_V2、BGP4MP/BGP4MP_ET 的 IPv4/IPv6 单播,含四字节 ASN、ADD-PATH 和会话状态。
    • 常用路径、聚合与社区属性;保留原始编码并解释 AS4 有效值,检查长度、标志和宣告必需属性。
    • 前缀、ASN、时间筛选,JSON Lines / CSV 导出,带文件、记录号和解压后偏移。
    • 初始 RIB 与连续更新回放、结构化变化、快照差异、前缀时间线和变化聚合。
    • 显式采集器/视图隔离回放,按 peer 磁盘分区保存完整逻辑状态。
    • 有界内存的跨观测点语义关联、分离式摘要/观测导出,以及可选紧凑变化流。
    • 离线 HTML 展示可读属性差异、关联组与来源跳转,提供倒排筛选、分页、取消和重置。
    • 调查规则、MOAS 区间、更具体前缀检查、窗口对比与路径演变;操作流程和在线静态案例。

    从多采集器示例开始,或查看固定真实案例。

    这是离线分析工具。旧 TABLE_DUMP、RIB_GENERIC、多播、VPN/EVPN 和在线 BGP 会话不在范围内;时间线描述采集器观测,不推断业务中断。规则、资源限制和边界见兼容清单。

    #文档与验证

    协议解析、回放和报告均有自动测试;真实档案对照、完整回放资源测量与历史工具链结果见验证记录。

    npm test moon test --target wasm --deny-warn moon test --target wasm-gc --deny-warn moon info moon fmt --check

    发布记录见 CHANGELOG。许可证为 Apache-2.0。

    ParseError

    pub suberror ParseError {
    Invalid(Int, String)
    }

    解析错误包含字节位置,便于定位损坏记录。

    Aggregation

    pub struct Aggregation {
    // private fields
    }

    Aggregation::new

    Aggregation::observe

    fn Aggregation::observe(self : Aggregation, change : Change) -> Unit raise ParseError

    同一输入事件的多个变化类型只占一次前缀事件计数。

    Aggregation::report

    fn Aggregation::report(self : Aggregation, top? : Int) -> AggregationReport raise ParseError

    AggregationReport

    pub struct AggregationReport {
    schema_version : String
    scope : String
    deduplication : String
    ordering : String
    changed_prefixes : Int
    affected_peers : Int
    change_notices : Int64
    change_types : Map[String, Int64]
    top_prefixes : Array[PrefixRanking]
    } derive(ToJson)

    AggregationReport::to_json

    Aggregator

    pub struct Aggregator {
    asn : UInt
    address : String
    } derive(Eq, Hash, ToJson,
    FromJson
    )

    Aggregator::equal

    fn Aggregator::equal(Aggregator, Aggregator) -> Bool

    Aggregator::hash

    fn Aggregator::hash(self : Aggregator) -> Int

    Aggregator::hash_combine

    fn Aggregator::hash_combine(Aggregator, Hasher) -> Unit

    Aggregator::not_equal

    fn Aggregator::not_equal(x : Aggregator, y : Aggregator) -> Bool

    Aggregator::to_json

    fn Aggregator::to_json(Aggregator) -> Json

    AggregatorDiff

    pub struct AggregatorDiff {
    before : Aggregator?
    after : Aggregator?
    }

    AggregatorDiff::to_json

    fn AggregatorDiff::to_json(self : AggregatorDiff) -> Json

    AnalysisQuery

    pub struct AnalysisQuery {
    side : String?
    origin_asns : Array[UInt]?
    path_asns : Array[UInt]?
    communities : Array[UInt]?
    origin_unknown : Bool?
    prefix : String?
    prefix_mode : String?
    peer_asn : UInt?
    outbound : Bool?
    path_id : UInt?
    collector : String?
    view : String?
    from_us : UInt64?
    to_us : UInt64?
    kind : String?
    } derive(ToJson,
    FromJson
    )

    Analyzer

    pub struct Analyzer {
    // private fields
    }

    Analyzer::new

    fn Analyzer::new(window_seconds? : Int, threshold? : Int, capacity? : Int, from_time? : UInt, to_time? : UInt, from_micros? : Int, to_micros? : Int) -> Analyzer raise ParseError

    Analyzer::observe

    fn Analyzer::observe(self : Analyzer, event : RouteEvent) -> Array[Change] raise ParseError

    每个 peer、方向和前缀单独跟踪,固定窗口内仅提醒一次波动。

    Analyzer::observe_state

    fn Analyzer::observe_state(self : Analyzer, state : StateChange) -> Unit

    会话离开 Established 时清除该 peer 的缓存,避免跨会话误报。

    Analyzer::path_totals

    fn Analyzer::path_totals(self : Analyzer) -> (Int64, Int64)

    分区摘要按整数路径总长和样本数合并,避免合并均值带来的舍入误差。

    Analyzer::record_batch

    fn Analyzer::record_batch(self : Analyzer, batch : Batch) -> Unit

    Analyzer::route_count

    fn Analyzer::route_count(self : Analyzer) -> Int

    Analyzer::route_state_iter

    fn Analyzer::route_state_iter(self : Analyzer) -> Iter[RouteEvent]

    分块导出使用迭代器,顺序不作承诺;消费完成前不得改变分析器状态。

    Analyzer::route_states

    fn Analyzer::route_states(self : Analyzer) -> Array[RouteEvent]

    返回可审计的结束状态,顺序按状态键排序。

    Analyzer::seed

    fn Analyzer::seed(self : Analyzer, event : RouteEvent) -> Unit raise ParseError

    基线记录仅建立状态,不参与统计或波动计数。

    Analyzer::set_baseline

    fn Analyzer::set_baseline(self : Analyzer) -> Unit

    Analyzer::storage_stats

    fn Analyzer::storage_stats(self : Analyzer) -> StorageStats

    共享只按完整原始属性相等判定;哈希碰撞仍通过 Eq 检查,不丢弃来源和编码。

    Analyzer::summary

    fn Analyzer::summary(self : Analyzer) -> Summary

    AsSegment

    pub struct AsSegment {
    kind : Int
    asns : Array[UInt]
    } derive(Eq, Hash, ToJson,
    FromJson
    )

    AsSegment::equal

    fn AsSegment::equal(AsSegment, AsSegment) -> Bool

    AsSegment::hash

    fn AsSegment::hash(self : AsSegment) -> Int

    AsSegment::hash_combine

    fn AsSegment::hash_combine(AsSegment, Hasher) -> Unit

    AsSegment::not_equal

    fn AsSegment::not_equal(x : AsSegment, y : AsSegment) -> Bool

    AsSegment::to_json

    fn AsSegment::to_json(AsSegment) -> Json

    AtomicAggregateDiff

    pub struct AtomicAggregateDiff {
    before : Bool
    after : Bool
    } derive(ToJson)

    AtomicAggregateDiff::to_json

    Attributes

    pub struct Attributes {
    origin : Int?
    path : Array[AsSegment]
    wire_path : Array[AsSegment]
    as4_path : Array[AsSegment]
    next_hop : String?
    med : UInt?
    local_pref : UInt?
    atomic_aggregate : Bool
    aggregator : Aggregator?
    wire_aggregator : Aggregator?
    as4_aggregator : Aggregator?
    raw_attributes : Array[RawAttribute]
    communities : Array[UInt]
    large_communities : Array[(UInt, UInt, UInt)]
    other : Array[RawAttribute]
    } derive(Eq, Hash, ToJson)

    Attributes::equal

    fn Attributes::equal(Attributes, Attributes) -> Bool

    Attributes::hash

    fn Attributes::hash(self : Attributes) -> Int

    Attributes::hash_combine

    fn Attributes::hash_combine(Attributes, Hasher) -> Unit

    Attributes::not_equal

    fn Attributes::not_equal(x : Attributes, y : Attributes) -> Bool

    Attributes::to_json

    fn Attributes::to_json(Attributes) -> Json

    Batch

    pub struct Batch {
    header : Header
    microseconds : Int?
    events : Array[RouteEvent]
    states : Array[StateChange]
    skipped : Bool
    ignored_families : Int
    message_type : Int?
    diagnostics : Array[Diagnostic]
    } derive(ToJson)

    Batch::to_json

    fn Batch::to_json(Batch) -> Json

    Batch::with_event_indices

    fn Batch::with_event_indices(self : Batch, indices : Array[Int]) -> Batch raise ParseError

    临时帧重新解码后恢复原始记录内索引;文件、记录号和偏移保持原始档案位置。

    BgpRecord

    pub struct BgpRecord {
    message_type : Int
    events : Array[RouteEvent]
    states : Array[StateChange]
    ignored_families : Int
    ignored : Array[(Int, Int)]
    }

    Change

    pub struct Change {
    schema_version : String
    timestamp : UInt
    microseconds : Int?
    prefix : String
    path_id : UInt?
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    kind : String
    source : Source?
    before : RouteSnapshot?
    after : RouteSnapshot
    diff : RouteDiff
    churn_count : Int?
    correlation_key : String?
    } derive(ToJson)

    Change::correlation_key

    fn Change::correlation_key(self : Change) -> String raise ParseError

    关联依据明确的前后语义,身份和 Path Identifier 属于本地来源,不进入跨观测点匹配键。

    Change::to_json

    fn Change::to_json(Change) -> Json

    Change::with_correlation_key

    fn Change::with_correlation_key(self : Change) -> Change raise ParseError

    CommunityDiff

    pub struct CommunityDiff {
    before : Array[UInt]
    after : Array[UInt]
    added : Array[UInt]
    removed : Array[UInt]
    } derive(ToJson)

    CommunityDiff::to_json

    ComparisonWindow

    pub struct ComparisonWindow {
    from_us : UInt64
    to_us : UInt64
    } derive(ToJson,
    FromJson
    )

    Decoder

    pub struct Decoder {
    // private fields
    }

    Decoder::decode

    fn Decoder::decode(self : Decoder, data : Bytes) -> Batch raise ParseError

    Decoder::decode_at

    fn Decoder::decode_at(self : Decoder, data : Bytes, file : String, record : Int64, offset : Int64) -> Batch raise ParseError

    偏移指解压后的 MRT 记录起点,索引为记录内零起始事件序号。

    Decoder::decode_scoped

    fn Decoder::decode_scoped(self : Decoder, data : Bytes, file : String, record : Int64, offset : Int64, collector : String, view : String) -> Batch raise ParseError

    一个采集器与视图使用一个独立 Decoder;本接口为事件、会话和诊断附加显式身份。

    Decoder::new

    fn Decoder::new() -> Decoder

    Decoder::partition_record

    fn Decoder::partition_record(self : Decoder, data : Bytes) -> PartitionedBatch raise ParseError

    原记录先完整解码校验,再原样拼接各 peer 的 RIB 条目,只改头长度与条目数。 双向 UPDATE 与会话事件使用同一 peer 分区,重置水位不会跨分区丢失。

    Decoder::reset

    fn Decoder::reset(self : Decoder) -> Unit

    新文件必须清除 peer 表,防止沿用前一文件的索引。

    Diagnostic

    pub struct Diagnostic {
    kind : String
    mrt_type : Int
    subtype : Int
    afi : Int?
    safi : Int?
    source : Source?
    } derive(ToJson)

    Diagnostic::to_json

    fn Diagnostic::to_json(Diagnostic) -> Json

    FocusRule

    pub struct FocusRule {
    prefix : String
    expected_origins : Array[UInt]?
    allowed_more_specifics : Array[String]?
    } derive(ToJson,
    FromJson
    )

    Frame

    pub struct Frame {
    header : Header
    microseconds : Int?
    payload : Bytes
    } derive(Eq)

    Frame::equal

    fn Frame::equal(Frame, Frame) -> Bool

    Frame::not_equal

    fn Frame::not_equal(x : Frame, y : Frame) -> Bool

    pub struct Header {
    timestamp : UInt
    kind : Int
    subtype : Int
    length : Int
    } derive(Eq, ToJson)

    Header::equal

    fn Header::equal(Header, Header) -> Bool

    Header::not_equal

    fn Header::not_equal(x : Header, y : Header) -> Bool

    Header::to_json

    fn Header::to_json(Header) -> Json

    HopDiff

    pub struct HopDiff {
    before : String?
    after : String?
    }

    impl ToJson for HopDiff

    HopDiff::to_json

    fn HopDiff::to_json(self : HopDiff) -> Json

    Investigation

    pub struct Investigation {
    // private fields
    }

    Investigation::new

    fn Investigation::new(text : String) -> Investigation raise ParseError

    Investigation::observe

    fn Investigation::observe(self : Investigation, event : RouteEvent, baseline? : Bool) -> Unit raise ParseError

    Investigation::observe_state

    fn Investigation::observe_state(self : Investigation, state : StateChange) -> Unit raise ParseError

    Investigation::report

    fn Investigation::report(self : Investigation) -> Json raise ParseError

    输入先在有界缓冲中稳定排序,再复用 Analyzer;没有由前端解释路径的第二套规则。

    Investigation::set_baseline_scope

    fn Investigation::set_baseline_scope(self : Investigation, collector : String, view : String) -> Unit raise ParseError

    空 RIB 的有效 peer 表同样证明显式基线存在。

    InvestigationEvent

    pub struct InvestigationEvent {
    id : String
    time_us : UInt64
    prefix : String
    peer : String
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    path_id : UInt?
    source : Source?
    kind : String
    accepted : Bool
    changes_state : Bool
    before : RouteSnapshot?
    after : RouteSnapshot?
    changes : Array[Change]
    selected : Bool
    before_path : Json?
    after_path : Json?
    } derive(ToJson)

    InvestigationEvent::to_json

    InvestigationGap

    pub struct InvestigationGap {
    from_us : UInt64
    to_us : UInt64
    collector : String?
    view : String?
    } derive(ToJson,
    FromJson
    )

    InvestigationInterval

    pub struct InvestigationInterval {
    key : String
    prefix : String
    peer : String
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    collector : String?
    view : String?
    path_id : UInt?
    from_us : UInt64
    to_us : UInt64
    state : String
    duration_us : UInt64?
    left_censored : Bool
    right_censored : Bool
    start_source : Source?
    end_source : Source?
    origin_as : UInt?
    path_length : Int?
    } derive(ToJson)

    InvestigationInterval::to_json

    InvestigationRules

    pub struct InvestigationRules {
    schema_version : String
    version : String
    from_us : UInt64
    to_us : UInt64
    bucket_us : UInt64?
    incident_us : UInt64?
    capacity : Int?
    max_bytes : Int?
    continuous : Bool?
    gaps : Array[InvestigationGap]?
    focus : Array[FocusRule]?
    query : AnalysisQuery?
    comparison : Array[ComparisonWindow]?
    sequence_prefix : String?
    scope_prefixes : Array[String]?
    scope_peer_asns : Array[UInt]?
    } derive(ToJson,
    FromJson
    )

    LargeCommunityDiff

    pub struct LargeCommunityDiff {
    before : Array[(UInt, UInt, UInt)]
    after : Array[(UInt, UInt, UInt)]
    added : Array[(UInt, UInt, UInt)]
    removed : Array[(UInt, UInt, UInt)]
    } derive(ToJson)

    LargeCommunityDiff::to_json

    ObservationGap

    pub struct ObservationGap {
    from_time : UInt
    from_micros : Int
    to_time : UInt
    to_micros : Int
    } derive(ToJson)

    ObservationGap::new

    fn ObservationGap::new(from_time : UInt, to_time : UInt, from_micros? : Int, to_micros? : Int) -> ObservationGap

    ObservationGap::to_json

    OriginDiff

    pub struct OriginDiff {
    before : UInt?
    after : UInt?
    }

    OriginDiff::to_json

    fn OriginDiff::to_json(self : OriginDiff) -> Json

    PartitionedBatch

    pub struct PartitionedBatch {
    header : Header
    microseconds : Int?
    skipped : Bool
    ignored_families : Int
    diagnostics : Array[Diagnostic]
    route_events : Int
    state_events : Int
    peer_table : Bool
    parts : Array[PeerRecord]
    } derive(ToJson)

    PartitionedBatch::to_json

    PathDiff

    pub struct PathDiff {
    before : Array[AsSegment]
    after : Array[AsSegment]
    } derive(ToJson)

    PathDiff::to_json

    fn PathDiff::to_json(PathDiff) -> Json

    Peer

    pub struct Peer {
    bgp_id : UInt
    address : String
    asn : UInt
    } derive(ToJson)

    Peer::to_json

    fn Peer::to_json(Peer) -> Json

    PeerRecord

    pub struct PeerRecord {
    peer : String
    data : Bytes
    event_indices : Array[Int]
    }

    PeerRecord::to_json

    fn PeerRecord::to_json(self : PeerRecord) -> Json

    PeerTable

    pub struct PeerTable {
    collector_id : UInt
    view_name : Bytes
    peers : Array[Peer]
    }

    Prefix

    pub struct Prefix {
    afi : Int
    length : Int
    address : Bytes
    } derive(Eq, ToJson)

    Prefix::contains

    fn Prefix::contains(self : Prefix, other : Prefix) -> Bool

    Prefix::equal

    fn Prefix::equal(Prefix, Prefix) -> Bool

    Prefix::not_equal

    fn Prefix::not_equal(x : Prefix, y : Prefix) -> Bool

    Prefix::text

    fn Prefix::text(self : Prefix) -> String

    Prefix::to_json

    fn Prefix::to_json(Prefix) -> Json

    PrefixRanking

    pub struct PrefixRanking {
    prefix : String
    changed_events : Int
    change_notices : Int64
    affected_peers : Int
    change_types : Map[String, Int64]
    } derive(ToJson)

    PrefixRanking::to_json

    Query

    pub struct Query {
    // private fields
    }

    Query::matches

    fn Query::matches(self : Query, event : RouteEvent) -> Bool

    前缀精确匹配;ASN 匹配 peer 或有效 AS 路径,时间包含端点。

    Query::new

    fn Query::new(prefix? : String, prefix_mode? : String, asn? : UInt, path_id? : UInt, from_time? : UInt, to_time? : UInt, from_micros? : Int, to_micros? : Int) -> Query raise ParseError

    RawAttribute

    pub struct RawAttribute {
    flags : Int
    code : Int
    value : Bytes
    } derive(Eq, Hash)

    RawAttribute::equal

    RawAttribute::hash

    fn RawAttribute::hash(self : RawAttribute) -> Int

    RawAttribute::hash_combine

    fn RawAttribute::hash_combine(RawAttribute, Hasher) -> Unit

    RawAttribute::not_equal

    fn RawAttribute::not_equal(x : RawAttribute, y : RawAttribute) -> Bool

    RawAttribute::to_json

    fn RawAttribute::to_json(self : RawAttribute) -> Json

    RouteDiff

    pub struct RouteDiff {
    atomic_aggregate : AtomicAggregateDiff?
    aggregator : AggregatorDiff?
    path : PathDiff?
    origin_as : OriginDiff?
    next_hop : HopDiff?
    communities : CommunityDiff?
    large_communities : LargeCommunityDiff?
    } derive(ToJson)

    RouteDiff::to_json

    fn RouteDiff::to_json(RouteDiff) -> Json

    RouteEvent

    pub struct RouteEvent {
    schema_version : String
    source : Source?
    timestamp : UInt
    microseconds : Int?
    action : String
    prefix : String
    path_id : UInt?
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    originated : UInt?
    attributes : Attributes
    } derive(ToJson)

    RouteEvent::to_json

    fn RouteEvent::to_json(RouteEvent) -> Json

    RouteSnapshot

    pub struct RouteSnapshot {
    timestamp : UInt
    microseconds : Int?
    active : Bool
    attributes : Attributes
    source : Source?
    } derive(ToJson)

    RouteSnapshot::to_json

    Snapshot

    pub struct Snapshot {
    // private fields
    }

    Snapshot::diff

    fn Snapshot::diff(self : Snapshot, after : Snapshot) -> SnapshotReport raise ParseError

    比较显式同源、同视图的两个快照;缺失不等同于观测到撤回。

    Snapshot::ingest

    fn Snapshot::ingest(self : Snapshot, data : Bytes, file : String, record : Int64, offset : Int64, query? : Query, peer_asn? : UInt) -> Unit raise ParseError

    快照保留 peer 表,避免把整个 peer 未采集误判为单条路由消失。

    Snapshot::new

    fn Snapshot::new(collector : String, capacity? : Int) -> Snapshot raise ParseError

    SnapshotChange

    pub struct SnapshotChange {
    schema_version : String
    collector : String
    kind : String
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    prefix : String?
    path_id : UInt?
    before : RouteEvent?
    after : RouteEvent?
    diff : RouteDiff?
    before_source : Source?
    after_source : Source?
    } derive(ToJson)

    SnapshotChange::to_json

    SnapshotReport

    pub struct SnapshotReport {
    schema_version : String
    collector : String
    interpretation : String
    before_source : Source?
    after_source : Source?
    before_time : UInt?
    after_time : UInt?
    before_peers : Int
    after_peers : Int
    before_routes : Int
    after_routes : Int
    changes : Array[SnapshotChange]
    } derive(ToJson)

    SnapshotReport::to_json

    Source

    pub struct Source {
    file : String
    record : Int64
    offset : Int64
    event_index : Int
    collector : String?
    view : String?
    } derive(Eq, Hash, ToJson,
    FromJson
    )

    Source::equal

    fn Source::equal(Source, Source) -> Bool

    Source::hash

    fn Source::hash(self : Source) -> Int

    Source::hash_combine

    fn Source::hash_combine(Source, Hasher) -> Unit

    Source::not_equal

    fn Source::not_equal(x : Source, y : Source) -> Bool

    Source::to_json

    fn Source::to_json(Source) -> Json

    StateChange

    pub struct StateChange {
    source : Source?
    timestamp : UInt
    microseconds : Int?
    peer_asn : UInt
    peer_ip : String
    old_state : Int
    new_state : Int
    } derive(ToJson)

    StateChange::to_json

    fn StateChange::to_json(StateChange) -> Json

    StorageStats

    pub struct StorageStats {
    route_keys : Int
    unique_attribute_sets : Int
    attribute_references : Int
    } derive(ToJson)

    StorageStats::to_json

    StreamDecoder

    pub struct StreamDecoder {
    // private fields
    }

    StreamDecoder::feed

    fn StreamDecoder::feed(self : StreamDecoder, chunk : Bytes) -> Array[Batch] raise ParseError

    输入分块上限 1 MiB,失败后需新建解码器。

    StreamDecoder::finish

    fn StreamDecoder::finish(self : StreamDecoder) -> Unit raise ParseError

    StreamDecoder::new

    Summary

    pub struct Summary {
    schema_version : String
    baseline_status : String
    warmup_records : Int64
    records : Int64
    skipped_records : Int64
    ignored_families : Int64
    rib_routes : Int64
    announcements : Int64
    withdrawals : Int64
    path_changes : Int64
    attribute_changes : Int64
    origin_changes : Int64
    duplicate_announcements : Int64
    churn_alerts : Int64
    out_of_order : Int64
    session_resets : Int64
    tracked_routes : Int
    active_routes : Int
    mean_path_length : Double
    max_path_length : Int
    } derive(ToJson)

    Summary::to_json

    fn Summary::to_json(Summary) -> Json

    Timeline

    pub struct Timeline {
    // private fields
    }

    Timeline::new

    fn Timeline::new(prefix : String, analyzer : Analyzer, continuous? : Bool, gaps? : Array[ObservationGap], capacity? : Int, peer_asn? : UInt) -> Timeline raise ParseError

    Timeline::observe

    fn Timeline::observe(self : Timeline, event : RouteEvent) -> Unit raise ParseError

    Timeline::record_batch

    fn Timeline::record_batch(self : Timeline, batch : Batch) -> Unit raise ParseError

    Timeline::report

    fn Timeline::report(self : Timeline) -> TimelineReport raise ParseError

    Timeline::seed

    fn Timeline::seed(self : Timeline, event : RouteEvent) -> Unit raise ParseError

    Timeline::seed_peers

    fn Timeline::seed_peers(self : Timeline, table : PeerTable, timestamp : UInt) -> Unit raise ParseError

    TimelineEntry

    pub struct TimelineEntry {
    timestamp : UInt
    microseconds : Int?
    kind : String
    prefix : String
    path_id : UInt?
    peer_asn : UInt?
    peer_ip : String?
    outbound : Bool?
    accepted : Bool
    source : Source?
    before : RouteSnapshot?
    after : RouteSnapshot?
    changes : Array[Change]
    } derive(ToJson)

    TimelineEntry::to_json

    TimelinePath

    pub struct TimelinePath {
    prefix : String
    path_id : UInt?
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    visibility : String
    observed_at : UInt64
    source : Source?
    } derive(ToJson)

    TimelinePath::to_json

    TimelinePeer

    pub struct TimelinePeer {
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    visibility : String
    visible_paths : Int
    not_visible_paths : Int
    unobserved_paths : Int
    baseline_present : Bool
    } derive(ToJson)

    TimelinePeer::to_json

    TimelineReport

    pub struct TimelineReport {
    schema_version : String
    prefix : String
    interpretation : String
    baseline_status : String
    continuous_observation : Bool
    last_input_time : UInt64?
    observed_window_end : UInt64?
    gaps : Array[ObservationGap]
    entries : Array[TimelineEntry]
    intervals : Array[VisibilityInterval]
    peer_intervals : Array[VisibilityInterval]
    paths : Array[TimelinePath]
    peers : Array[TimelinePeer]
    } derive(ToJson)

    TimelineReport::to_json

    TimelineReport::with_correlation_keys

    fn TimelineReport::with_correlation_keys(self : TimelineReport) -> TimelineReport raise ParseError

    VisibilityInterval

    pub struct VisibilityInterval {
    scope : String
    prefix : String
    path_id : UInt?
    peer_asn : UInt
    peer_ip : String
    outbound : Bool
    started_at : UInt64
    measured_from : UInt64
    observed_until : UInt64
    recovery_time : UInt64?
    known_invisible_microseconds : UInt64?
    left_censored : Bool
    right_censored : Bool
    quality : String
    closed_by : String
    start_source : Source?
    end_source : Source?
    } derive(ToJson)

    VisibilityInterval::to_json

    correlation_key_from_json

    fn correlation_key_from_json(text : String) -> String raise ParseError

    correlation_semantics_from_json

    fn correlation_semantics_from_json(text : String) -> String raise ParseError

    去重比关联规则更严格:比较完整规范化属性,而非只比较某一类变化的键。

    csv_header

    fn csv_header() -> String

    event_csv

    fn event_csv(event : RouteEvent) -> String

    event_json

    fn event_json(event : RouteEvent) -> String

    investigation_filter_metadata

    fn investigation_filter_metadata(query : String, row : String) -> Bool raise ParseError

    报告只传紧凑索引元数据;属性条件必须查询完整结果事件。

    investigation_match_json

    fn investigation_match_json(query : String, row : String) -> Bool raise ParseError

    investigation_source_id

    fn investigation_source_id(source : Source?) -> String

    稳定标识只使用来源元组,调用方必须传入包内文件标签。

    investigation_summary_json

    fn investigation_summary_json(rules_text : String, rows : String) -> Json raise ParseError

    origin_as

    fn origin_as(path : Array[AsSegment]) -> UInt?

    末段为 AS_SET 时无法唯一确定起源 AS。

    parse_attributes

    fn parse_attributes(data : Bytes, asn_width : Int) -> Attributes raise ParseError

    parse_bgp4mp

    fn parse_bgp4mp(frame : Frame) -> BgpRecord raise ParseError

    parse_peers

    fn parse_peers(data : Bytes) -> PeerTable raise ParseError

    parse_prefix

    fn parse_prefix(data : Bytes, afi : Int) -> Prefix raise ParseError

    parse_prefix_text

    fn parse_prefix_text(text : String) -> Prefix raise ParseError

    库和 CLI 共用的文本解析;没有掩码的地址表示主机前缀。

    parse_rib

    fn parse_rib(frame : Frame, peers : Array[Peer]) -> Array[RouteEvent] raise ParseError

    TABLE_DUMP_V2 的 AS_PATH 始终使用四字节 ASN。

    path_length

    fn path_length(path : Array[AsSegment]) -> Int

    AS_SET 计一个跳数,联盟路径不参与常规路径长度统计。

    path_text

    fn path_text(path : Array[AsSegment]) -> String

    read_frame

    fn read_frame(data : Bytes) -> Frame raise ParseError

    单条记录上限为 16 MiB,未知类型仍保留完整记录。

    reconstruct_path

    fn reconstruct_path(path : Array[AsSegment], as4 : Array[AsSegment]) -> Array[AsSegment]

    按 RFC 6793 保留旧路径前缀,再拼接 AS4_PATH。

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io