///|
priv struct WireAnalysisEvent {
id : String
time_us : UInt64
prefix : String
peer : String
peer_asn : UInt32
peer_ip : String
outbound : Bool
path_id : UInt32?
source : Source?
kind : String
accepted : Bool
changes_state : Bool
before : WireSemanticSnapshot?
after : WireSemanticSnapshot?
changes : Array[Json]
selected : Bool
} derive(@json.FromJson)
///|
fn read_analysis_event(row : Json) -> InvestigationEvent raise ParseError {
let wire : WireAnalysisEvent = @json.from_json(analysis_json(row)) catch {
_ => raise Invalid(0, "结果事件 JSON 无效")
}
let snapshot = fn(value : WireSemanticSnapshot) raise ParseError {
{
timestamp: 0U,
microseconds: None,
active: value.active,
attributes: value.attributes.attributes(),
source: None,
}
}
{
id: wire.id,
time_us: wire.time_us,
prefix: wire.prefix,
peer: wire.peer,
peer_asn: wire.peer_asn,
peer_ip: wire.peer_ip,
outbound: wire.outbound,
path_id: wire.path_id,
source: wire.source,
kind: wire.kind,
accepted: wire.accepted,
changes_state: wire.changes_state,
before: wire.before.map(snapshot),
after: wire.after.map(snapshot),
changes: wire.changes.map(row => semantic_change_from_json(row.stringify())),
selected: wire.selected,
before_path: None,
after_path: None,
}
}
///|
pub fn investigation_match_json(
query : String,
row : String,
) -> Bool raise ParseError {
let query : AnalysisQuery = @json.from_json(analysis_json(@json.parse(query))) catch {
_ => raise Invalid(0, "查询 JSON 无效")
}
if !["before", "after", "either"].contains(query.side.unwrap_or("either")) {
raise Invalid(0, "查询 side 无效")
}
ignore(
Query::new(
prefix?=query.prefix,
prefix_mode=query.prefix_mode.unwrap_or("exact"),
),
)
analysis_matches(
Some(query),
read_analysis_event(
@json.parse(row) catch {
_ => raise Invalid(0, "事件 JSON 无效")
},
),
)
}
///|
pub fn investigation_summary_json(
rules_text : String,
rows : String,
) -> Json raise ParseError {
let rules = Investigation::new(rules_text).rules
let values : Array[Json] = @json.from_json(analysis_json(@json.parse(rows))) catch {
_ => raise Invalid(0, "事件列表 JSON 无效")
}
if values.length() > rules.capacity.unwrap_or(20000) {
raise Invalid(0, "摘要超过容量")
}
let counts = chart_counts()
for value in values {
let row = read_analysis_event(value)
if row.time_us >= rules.from_us && row.time_us < rules.to_us {
counts.observe(row, rules)
}
}
counts.report("query", rules)
}