///|
/// Replay mode controls whether detector state is allowed to mutate.
pub(all) enum ProductionReplayMode {
StatefulReplay
ShadowReplay
CompareReplay
}
///|
pub fn production_replay_mode_name(mode : ProductionReplayMode) -> String {
match mode {
StatefulReplay => "stateful"
ShadowReplay => "shadow"
CompareReplay => "compare"
}
}
///|
/// Replay options for deterministic regression and incident investigation.
pub struct ProductionReplayConfig {
mode : ProductionReplayMode
start_timestamp : Int64
step : Int64
maximum_points : Int
compare_tolerance : Double
include_quiet : Bool
}
///|
pub fn ProductionReplayConfig::new(
mode? : ProductionReplayMode = StatefulReplay,
start_timestamp? : Int64 = 0L,
step? : Int64 = 1L,
maximum_points? : Int = 100000,
compare_tolerance? : Double = 1.0e-9,
include_quiet? : Bool = false,
) -> ProductionReplayConfig {
{
mode,
start_timestamp,
step: if step < 1L {
1L
} else {
step
},
maximum_points: if maximum_points < 1 {
1
} else {
maximum_points
},
compare_tolerance: if compare_tolerance < 0.0 {
0.0
} else {
compare_tolerance
},
include_quiet,
}
}
///|
pub fn ProductionReplayConfig::mode(
self : ProductionReplayConfig,
) -> ProductionReplayMode {
self.mode
}
///|
pub fn ProductionReplayConfig::start_timestamp(
self : ProductionReplayConfig,
) -> Int64 {
self.start_timestamp
}
///|
pub fn ProductionReplayConfig::step(self : ProductionReplayConfig) -> Int64 {
self.step
}
///|
pub fn ProductionReplayConfig::maximum_points(
self : ProductionReplayConfig,
) -> Int {
self.maximum_points
}
///|
pub fn ProductionReplayConfig::compare_tolerance(
self : ProductionReplayConfig,
) -> Double {
self.compare_tolerance
}
///|
pub fn ProductionReplayConfig::include_quiet(
self : ProductionReplayConfig,
) -> Bool {
self.include_quiet
}
///|
/// One normalized replay output row.
pub struct ProductionReplayObservation {
index : Int
timestamp : Int64
value : Double
baseline : Double
result : DetectionResult
state : ProductionHealthState
emitted : Bool
}
///|
pub fn ProductionReplayObservation::index(
self : ProductionReplayObservation,
) -> Int {
self.index
}
///|
pub fn ProductionReplayObservation::timestamp(
self : ProductionReplayObservation,
) -> Int64 {
self.timestamp
}
///|
pub fn ProductionReplayObservation::value(
self : ProductionReplayObservation,
) -> Double {
self.value
}
///|
pub fn ProductionReplayObservation::baseline(
self : ProductionReplayObservation,
) -> Double {
self.baseline
}
///|
pub fn ProductionReplayObservation::result(
self : ProductionReplayObservation,
) -> DetectionResult {
self.result
}
///|
pub fn ProductionReplayObservation::state(
self : ProductionReplayObservation,
) -> ProductionHealthState {
self.state
}
///|
pub fn ProductionReplayObservation::emitted(
self : ProductionReplayObservation,
) -> Bool {
self.emitted
}
///|
pub fn ProductionReplayObservation::summary(
self : ProductionReplayObservation,
) -> String {
self.index.to_string() +
"," +
self.timestamp.to_string() +
"," +
self.value.to_string() +
"," +
self.baseline.to_string() +
"," +
self.result.score.to_string() +
"," +
self.result.changed.to_string() +
"," +
production_health_state_name(self.state) +
"," +
self.emitted.to_string()
}
///|
/// Aggregate replay statistics and a deterministic checksum.
pub struct ProductionReplaySummary {
points : Int
valid : Int
invalid : Int
changes : Int
emitted : Int
suppressed : Int
checksum : Double
first_change : Int
mean_score : Double
maximum_score : Double
final_state : ProductionHealthState
}
///|
pub fn ProductionReplaySummary::points(self : ProductionReplaySummary) -> Int {
self.points
}
///|
pub fn ProductionReplaySummary::valid(self : ProductionReplaySummary) -> Int {
self.valid
}
///|
pub fn ProductionReplaySummary::invalid(self : ProductionReplaySummary) -> Int {
self.invalid
}
///|
pub fn ProductionReplaySummary::changes(self : ProductionReplaySummary) -> Int {
self.changes
}
///|
pub fn ProductionReplaySummary::emitted(self : ProductionReplaySummary) -> Int {
self.emitted
}
///|
pub fn ProductionReplaySummary::suppressed(
self : ProductionReplaySummary,
) -> Int {
self.suppressed
}
///|
pub fn ProductionReplaySummary::checksum(
self : ProductionReplaySummary,
) -> Double {
self.checksum
}
///|
pub fn ProductionReplaySummary::first_change(
self : ProductionReplaySummary,
) -> Int {
self.first_change
}
///|
pub fn ProductionReplaySummary::mean_score(
self : ProductionReplaySummary,
) -> Double {
self.mean_score
}
///|
pub fn ProductionReplaySummary::maximum_score(
self : ProductionReplaySummary,
) -> Double {
self.maximum_score
}
///|
pub fn ProductionReplaySummary::final_state(
self : ProductionReplaySummary,
) -> ProductionHealthState {
self.final_state
}
///|
pub fn ProductionReplaySummary::summary(
self : ProductionReplaySummary,
) -> String {
"points=" +
self.points.to_string() +
",valid=" +
self.valid.to_string() +
",invalid=" +
self.invalid.to_string() +
",changes=" +
self.changes.to_string() +
",emitted=" +
self.emitted.to_string() +
",suppressed=" +
self.suppressed.to_string() +
",checksum=" +
self.checksum.to_string() +
",first_change=" +
self.first_change.to_string() +
",mean_score=" +
self.mean_score.to_string() +
",maximum_score=" +
self.maximum_score.to_string() +
",state=" +
production_health_state_name(self.final_state)
}
///|
/// Runs a configured monitor over a reproducible input signal.
pub struct ProductionReplayRunner {
config : ProductionReplayConfig
observations : Array[ProductionReplayObservation]
mut skipped : Int
}
///|
pub fn ProductionReplayRunner::new(
config? : ProductionReplayConfig = ProductionReplayConfig::new(),
) -> ProductionReplayRunner {
{ config, observations: [], skipped: 0 }
}
///|
pub fn ProductionReplayRunner::config(
self : ProductionReplayRunner,
) -> ProductionReplayConfig {
self.config
}
///|
pub fn ProductionReplayRunner::skipped(self : ProductionReplayRunner) -> Int {
self.skipped
}
///|
pub fn ProductionReplayRunner::observations(
self : ProductionReplayRunner,
) -> Array[ProductionReplayObservation] {
let result : Array[ProductionReplayObservation] = []
for observation in self.observations {
result.push(observation)
}
result
}
///|
fn production_replay_checksum(
checksum : Double,
observation : ProductionReplayObservation,
) -> Double {
let factor = observation.result.score +
observation.value * 0.0001 +
observation.baseline * 0.00001
let bonus = if observation.result.changed { 0.37 } else { 0.0 }
let next = checksum * 1.0000003 + factor + bonus
if next > 1.0e12 {
next % 1000000007.0
} else {
next
}
}
///|
pub fn ProductionReplayRunner::run(
self : ProductionReplayRunner,
monitor : ProductionMonitor,
points : Array[SignalPoint],
) -> ProductionReplaySummary {
let limit = self.config.maximum_points()
let mut checksum = 0.0
let mut valid = 0
let mut invalid = 0
let mut changes = 0
let mut emitted = 0
let mut suppressed = 0
let mut first_change = -1
let mut score_total = 0.0
let mut maximum_score = 0.0
let mut processed = 0
for point in points {
if processed >= limit {
self.skipped += 1
continue
}
processed += 1
match monitor.update_point(point) {
None => self.skipped += 1
Some(event) => {
let result = event.result()
if is_finite(point.value) {
valid += 1
} else {
invalid += 1
}
if result.changed {
changes += 1
if first_change < 0 {
first_change = processed
}
if event.kind() is AlertEmitted {
emitted += 1
} else {
suppressed += 1
}
}
score_total += result.score
if result.score > maximum_score {
maximum_score = result.score
}
let observation = {
index: processed,
timestamp: point.timestamp,
value: point.value,
baseline: event.baseline(),
result,
state: event.state(),
emitted: event.kind() is AlertEmitted,
}
checksum = production_replay_checksum(checksum, observation)
if self.config.include_quiet() || result.changed {
self.observations.push(observation)
}
}
}
}
let final_snapshot = monitor.snapshot()
{
points: processed,
valid,
invalid,
changes,
emitted,
suppressed,
checksum,
first_change,
mean_score: if processed == 0 {
0.0
} else {
score_total / processed.to_double()
},
maximum_score,
final_state: final_snapshot.state(),
}
}
///|
pub fn ProductionReplayRunner::reset(self : ProductionReplayRunner) -> Unit {
self.observations.clear()
self.skipped = 0
}
///|
/// Difference between two deterministic replay results.
pub struct ProductionReplayDifference {
points_delta : Int
changes_delta : Int
emitted_delta : Int
checksum_delta : Double
score_delta : Double
equivalent : Bool
}
///|
pub fn ProductionReplayDifference::from_summaries(
left : ProductionReplaySummary,
right : ProductionReplaySummary,
tolerance? : Double = 1.0e-9,
) -> ProductionReplayDifference {
let checksum_delta = absolute(left.checksum() - right.checksum())
let score_delta = absolute(left.mean_score() - right.mean_score())
{
points_delta: right.points() - left.points(),
changes_delta: right.changes() - left.changes(),
emitted_delta: right.emitted() - left.emitted(),
checksum_delta,
score_delta,
equivalent: left.points() == right.points() &&
left.changes() == right.changes() &&
left.emitted() == right.emitted() &&
checksum_delta <= tolerance &&
score_delta <= tolerance,
}
}
///|
pub fn ProductionReplayDifference::points_delta(
self : ProductionReplayDifference,
) -> Int {
self.points_delta
}
///|
pub fn ProductionReplayDifference::changes_delta(
self : ProductionReplayDifference,
) -> Int {
self.changes_delta
}
///|
pub fn ProductionReplayDifference::emitted_delta(
self : ProductionReplayDifference,
) -> Int {
self.emitted_delta
}
///|
pub fn ProductionReplayDifference::checksum_delta(
self : ProductionReplayDifference,
) -> Double {
self.checksum_delta
}
///|
pub fn ProductionReplayDifference::score_delta(
self : ProductionReplayDifference,
) -> Double {
self.score_delta
}
///|
pub fn ProductionReplayDifference::equivalent(
self : ProductionReplayDifference,
) -> Bool {
self.equivalent
}
///|
pub fn ProductionReplayDifference::summary(
self : ProductionReplayDifference,
) -> String {
"points_delta=" +
self.points_delta.to_string() +
",changes_delta=" +
self.changes_delta.to_string() +
",emitted_delta=" +
self.emitted_delta.to_string() +
",checksum_delta=" +
self.checksum_delta.to_string() +
",score_delta=" +
self.score_delta.to_string() +
",equivalent=" +
self.equivalent.to_string()
}
///|
/// Creates sorted points from a deterministic scenario for benchmark harnesses.
pub fn production_scenario_points(
scenario : SignalScenario,
start_timestamp? : Int64 = 0L,
step? : Int64 = 1L,
) -> Array[SignalPoint] {
let values = generate_signal(scenario)
let result : Array[SignalPoint] = []
for i, value in values {
result.push(
SignalPoint::new(start_timestamp + step * i.to_int64(), value, sequence=i),
)
}
result
}
///|
/// Computes a stable hash-like checksum over a numeric output series.
pub fn production_values_checksum(values : Array[Double]) -> Double {
let mut checksum = 17.0
for i, value in values {
let safe = if is_finite(value) { value } else { 0.0 }
checksum = checksum * 31.0 + safe + i.to_double() * 0.000001
if checksum > 1.0e15 {
checksum = checksum % 1000000007.0
}
}
checksum
}
///|
pub fn production_observations_csv_header() -> String {
"index,timestamp,value,baseline,score,changed,state,emitted\n"
}
///|
pub fn production_observations_csv(
observations : Array[ProductionReplayObservation],
) -> String {
let mut output = production_observations_csv_header()
for observation in observations {
output = output + observation.summary() + "\n"
}
output
}