@@ -13,7 +13,7 @@ export type ByResource = {
1313 critical : SeverityStats ;
1414 warning : SeverityStats ;
1515 other : SeverityStats ;
16- score : number ;
16+ score : Score ;
1717} ;
1818
1919type SeverityStats = {
@@ -41,6 +41,17 @@ type HealthMetadata = {
4141 namespaceLabels ?: string [ ] ;
4242} ;
4343
44+ type Score = {
45+ total : number ;
46+ details : ScoreDetail [ ] ;
47+ } ;
48+
49+ type ScoreDetail = {
50+ alertName : string ;
51+ rawScore : number ;
52+ weight : number ;
53+ } ;
54+
4455export const getHealthMetadata = ( annotations : PrometheusLabels ) : HealthMetadata | undefined => {
4556 if ( 'netobserv_io_network_health' in annotations ) {
4657 const md = ( JSON . parse ( annotations [ 'netobserv_io_network_health' ] ) as HealthMetadata ) || undefined ;
@@ -141,7 +152,7 @@ const statsFromGrouped = (name: string, grouped: AlertWithRuleName[]): ByResourc
141152 critical : { firing : [ ] , pending : [ ] , silenced : [ ] , inactive : [ ] } ,
142153 warning : { firing : [ ] , pending : [ ] , silenced : [ ] , inactive : [ ] } ,
143154 other : { firing : [ ] , pending : [ ] , silenced : [ ] , inactive : [ ] } ,
144- score : 0
155+ score : { total : 0 , details : [ ] }
145156 } ;
146157 _ . uniqWith ( grouped , ( a , b ) => {
147158 return a . ruleName === b . ruleName && _ . isEqual ( a . labels , b . labels ) ;
@@ -241,37 +252,52 @@ const getSeverityWeight = (a: AlertWithRuleName) => {
241252 }
242253} ;
243254
255+ const getStateWeight = ( a : AlertWithRuleName ) => {
256+ switch ( a . state ) {
257+ case 'pending' :
258+ return pendingWeight ;
259+ case 'silenced' :
260+ return silencedWeight ;
261+ }
262+ return 1 ;
263+ } ;
264+
244265// Score [0,10]; higher is better
245- export const computeScore = ( r : ByResource ) : number => {
266+ export const computeScore = ( r : ByResource ) : Score => {
246267 const allAlerts = getAllAlerts ( r ) ;
247- const score = allAlerts . map ( a => computeAlertScore ( a ) ) . reduce ( ( a , b ) => a + b , 0 ) ;
248- if ( score === 0 ) {
249- return 10 ;
268+ const allScores = allAlerts
269+ . map ( computeAlertScore )
270+ . concat ( r . critical . inactive . map ( name => ( { alertName : name , rawScore : 10 , weight : criticalWeight } ) ) )
271+ . concat ( r . warning . inactive . map ( name => ( { alertName : name , rawScore : 10 , weight : warningWeight } ) ) )
272+ . concat ( r . other . inactive . map ( name => ( { alertName : name , rawScore : 10 , weight : minorWeight } ) ) ) ;
273+ const sum = allScores . map ( s => s . rawScore * s . weight ) . reduce ( ( a , b ) => a + b , 0 ) ;
274+ const sumWeights = allScores . map ( s => s . weight ) . reduce ( ( a , b ) => a + b , 0 ) ;
275+ if ( sumWeights === 0 ) {
276+ return { total : 10 , details : [ ] } ;
250277 }
251- const div =
252- allAlerts . map ( getSeverityWeight ) . reduce ( ( a , b ) => a + b , 0 ) +
253- r . critical . inactive . length * criticalWeight +
254- r . warning . inactive . length * warningWeight +
255- r . other . inactive . length * minorWeight ;
256- return 10 * ( 1 - score / div ) ;
278+ return { total : sum / sumWeights , details : allScores } ;
257279} ;
258280
259281// Score [0,1]; lower is better
260- export const computeAlertScore = ( a : AlertWithRuleName , ignoreSeverity ?: boolean ) : number => {
261- let multiplier = ignoreSeverity ? 1 : getSeverityWeight ( a ) ;
262- switch ( a . state ) {
263- case 'pending' :
264- multiplier *= pendingWeight ;
265- break ;
266- case 'silenced' :
267- multiplier *= silencedWeight ;
268- break ;
269- }
282+ const computeExcessRatio = ( a : AlertWithRuleName ) : number => {
270283 // Assuming the alert value is a [0-100] percentage. Needs update if more use cases come up.
271284 const threshold = ( a . metadata ?. thresholdF || 0 ) / 2 ;
272285 const range = 100 - threshold ;
273286 const excess = Math . max ( ( a . value as number ) - threshold , 0 ) ;
274- return ( excess * multiplier ) / range ;
287+ return excess / range ;
288+ } ;
289+
290+ export const computeExcessRatioStatusWeighted = ( a : AlertWithRuleName ) : number => {
291+ return computeExcessRatio ( a ) * getStateWeight ( a ) ;
292+ } ;
293+
294+ // Score [0,10]; higher is better
295+ export const computeAlertScore = ( a : AlertWithRuleName ) : ScoreDetail => {
296+ return {
297+ alertName : a . ruleName ,
298+ rawScore : 10 * ( 1 - computeExcessRatio ( a ) ) ,
299+ weight : getSeverityWeight ( a ) * getStateWeight ( a )
300+ } ;
275301} ;
276302
277303export const isSilenced = ( silence : SilenceMatcher [ ] , labels : PrometheusLabels ) : boolean => {
0 commit comments