///|
pub(all) struct ServiceSnapshot {
service : String
budget : BudgetReport
} derive(Eq, Debug)
///|
pub fn ServiceSnapshot::new(
service : String,
budget : BudgetReport,
) -> ServiceSnapshot {
{ service, budget }
}
///|
pub fn ServiceSnapshot::healthy(self : ServiceSnapshot) -> Bool {
self.budget.healthy()
}
///|
pub fn ServiceSnapshot::availability_bp(self : ServiceSnapshot) -> Int {
self.budget.window.availability_bp()
}
///|
pub(all) struct PortfolioSummary {
portfolio : String
service_count : Int
healthy_count : Int
unhealthy_count : Int
total_requests : Int
total_bad : Int
availability_bp : Int
} derive(Eq, Debug)
///|
pub fn PortfolioSummary::healthy(self : PortfolioSummary) -> Bool {
self.unhealthy_count == 0 && self.service_count > 0
}
///|
pub fn PortfolioSummary::to_json(self : PortfolioSummary) -> String {
"{\"portfolio\":\"\{escape_json(self.portfolio)}\",\"service_count\":\{self.service_count},\"healthy_count\":\{self.healthy_count},\"unhealthy_count\":\{self.unhealthy_count},\"total_requests\":\{self.total_requests},\"total_bad\":\{self.total_bad},\"availability_bp\":\{self.availability_bp}}"
}
///|
pub(all) struct SloPortfolio {
name : String
services : Array[ServiceSnapshot]
} derive(Eq, Debug)
///|
pub fn SloPortfolio::new(name : String) -> SloPortfolio {
{ name, services: [] }
}
///|
pub fn SloPortfolio::add(
self : SloPortfolio,
service : ServiceSnapshot,
) -> SloPortfolio {
self.services.push(service)
self
}
///|
pub fn SloPortfolio::service_count(self : SloPortfolio) -> Int {
self.services.length()
}
///|
pub fn SloPortfolio::contains(self : SloPortfolio, service : String) -> Bool {
for item in self.services {
if item.service == service {
return true
}
}
false
}
///|
pub fn SloPortfolio::healthy_count(self : SloPortfolio) -> Int {
let mut count = 0
for service in self.services {
if service.healthy() {
count = count + 1
}
}
count
}
///|
pub fn SloPortfolio::summary(self : SloPortfolio) -> PortfolioSummary {
let mut total_requests = 0
let mut total_bad = 0
let mut availability_numerator = 0
for service in self.services {
total_requests = total_requests + service.budget.window.total
total_bad = total_bad + service.budget.actual_bad
availability_numerator = availability_numerator +
service.budget.window.good * 10000
}
let count = self.services.length()
let availability = if total_requests == 0 {
10000
} else {
availability_numerator / total_requests
}
{
portfolio: self.name,
service_count: count,
healthy_count: self.healthy_count(),
unhealthy_count: count - self.healthy_count(),
total_requests,
total_bad,
availability_bp: availability,
}
}
///|
pub fn SloPortfolio::unhealthy_services(self : SloPortfolio) -> Array[String] {
let result = []
for service in self.services {
if !service.healthy() {
result.push(service.service)
}
}
result
}
///|
pub fn SloPortfolio::to_json(self : SloPortfolio) -> String {
let result = StringBuilder()
result.write_string("{\"name\":\"\{escape_json(self.name)}\",\"services\":[")
for i, service in self.services {
if i > 0 {
result.write_string(",")
}
result.write_string(
"{\"name\":\"\{escape_json(service.service)}\",\"healthy\":\{service.healthy()},\"budget\":\{service.budget.to_json()}}",
)
}
result.write_string("]}")
result.to_string()
}