2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								package  schedule 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"sync" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"golang.org/x/sync/errgroup" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-25 06:34:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"github.com/benbjohnson/clock" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/models" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/notifier" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/state" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/store" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/infra/log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/alerting" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ngalert/eval" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/tsdb" 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// timeNow makes it possible to test usage of time
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  timeNow  =  time . Now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// ScheduleService handles scheduling
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  ScheduleService  interface  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-25 06:34:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Ticker ( context . Context ,  * state . StateTracker )  error 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									Pause ( )  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Unpause ( )  error 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									WarmStateCache ( * state . StateTracker ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// the following are used by tests only used for tests
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									evalApplied ( models . AlertRuleKey ,  time . Time ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									stopApplied ( models . AlertRuleKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									overrideCfg ( cfg  SchedulerCfg ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  ruleRoutine ( grafanaCtx  context . Context ,  key  models . AlertRuleKey ,  evalCh  <- chan  * evalContext ,  stopCh  <- chan  struct { } ,  stateTracker  * state . StateTracker )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . log . Debug ( "alert rule routine started" ,  "key" ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									evalRunning  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  start ,  end  time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  attempt  int64 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									var  alertRule  * models . AlertRule 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  ctx  :=  <- evalCh : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  evalRunning  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											evaluate  :=  func ( attempt  int64 )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												start  =  timeNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												// fetch latest alert rule version
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  alertRule  ==  nil  ||  alertRule . Version  <  ctx . version  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													q  :=  models . GetAlertRuleByUIDQuery { OrgID :  key . OrgID ,  UID :  key . UID } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													err  :=  sch . ruleStore . GetAlertRuleByUID ( & q ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														sch . log . Error ( "failed to fetch alert rule" ,  "key" ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
														return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													alertRule  =  q . Result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													sch . log . Debug ( "new alert rule version fetched" ,  "title" ,  alertRule . Title ,  "key" ,  key ,  "version" ,  alertRule . Version ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 00:56:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												condition  :=  models . Condition { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													Condition :  alertRule . Condition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													OrgID :      alertRule . OrgID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Data :       alertRule . Data , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												results ,  err  :=  sch . evaluator . ConditionEval ( & condition ,  ctx . now ,  sch . dataService ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												end  =  timeNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-19 02:57:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													// consider saving alert instance on error
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													sch . log . Error ( "failed to evaluate alert rule" ,  "title" ,  alertRule . Title , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
														"key" ,  key ,  "attempt" ,  attempt ,  "now" ,  ctx . now ,  "duration" ,  end . Sub ( start ) ,  "error" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-16 21:11:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												processedStates  :=  stateTracker . ProcessEvalResults ( alertRule ,  results ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												sch . saveAlertStates ( processedStates ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												alerts  :=  FromAlertStateToPostableAlerts ( processedStates ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												sch . log . Debug ( "sending alerts to notifier" ,  "count" ,  len ( alerts ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												err  =  sch . sendAlerts ( alerts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													sch . log . Error ( "failed to put alerts in the notifier" ,  "count" ,  len ( alerts ) ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												evalRunning  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													evalRunning  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													sch . evalApplied ( key ,  ctx . now ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												for  attempt  =  0 ;  attempt  <  sch . maxAttempts ;  attempt ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													err  :=  evaluate ( attempt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										case  <- stopCh : 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											sch . stopApplied ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											sch . log . Debug ( "stopping alert rule routine" ,  "key" ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											// interrupt evaluation if it's running
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										case  <- grafanaCtx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  grafanaCtx . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Notifier handles the delivery of alert notifications to the end user
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  Notifier  interface  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									PutAlerts ( alerts  ... * notifier . PostableAlert )  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								type  schedule  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// base tick rate (fastest possible configured check)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									baseInterval  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// each alert rule gets its own channel and routine
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									registry  alertRuleRegistry 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									maxAttempts  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clock  clock . Clock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									heartbeat  * alerting . Ticker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// evalApplied is only used for tests: test code can set it to non-nil
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// function, and then it'll be called from the event loop whenever the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// message from evalApplied is handled.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									evalAppliedFunc  func ( models . AlertRuleKey ,  time . Time ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// stopApplied is only used for tests: test code can set it to non-nil
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// function, and then it'll be called from the event loop whenever the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// message from stopApplied is handled.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									stopAppliedFunc  func ( models . AlertRuleKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									log  log . Logger 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 01:27:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									evaluator  eval . Evaluator 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									store  store . Store 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ruleStore  store . RuleStore 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									dataService  * tsdb . Service 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									notifier  Notifier 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 01:27:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// SchedulerCfg is the scheduler configuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  SchedulerCfg  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									C                clock . Clock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									BaseInterval     time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Logger           log . Logger 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									EvalAppliedFunc  func ( models . AlertRuleKey ,  time . Time ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									MaxAttempts      int64 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									StopAppliedFunc  func ( models . AlertRuleKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									Evaluator        eval . Evaluator 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Store            store . Store 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									RuleStore        store . RuleStore 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Notifier         Notifier 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// NewScheduler returns a new schedule.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  NewScheduler ( cfg  SchedulerCfg ,  dataService  * tsdb . Service )  * schedule  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ticker  :=  alerting . NewTicker ( cfg . C . Now ( ) ,  time . Second * 0 ,  cfg . C ,  int64 ( cfg . BaseInterval . Seconds ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									sch  :=  schedule { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										registry :         alertRuleRegistry { alertRuleInfo :  make ( map [ models . AlertRuleKey ] alertRuleInfo ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										maxAttempts :      cfg . MaxAttempts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clock :            cfg . C , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										baseInterval :     cfg . BaseInterval , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										log :              cfg . Logger , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										heartbeat :        ticker , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										evalAppliedFunc :  cfg . EvalAppliedFunc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										stopAppliedFunc :  cfg . StopAppliedFunc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										evaluator :        cfg . Evaluator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										store :            cfg . Store , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ruleStore :        cfg . RuleStore , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 14:02:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										dataService :      dataService , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										notifier :         cfg . Notifier , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & sch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  overrideCfg ( cfg  SchedulerCfg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . clock  =  cfg . C 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . baseInterval  =  cfg . BaseInterval 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . heartbeat  =  alerting . NewTicker ( cfg . C . Now ( ) ,  time . Second * 0 ,  cfg . C ,  int64 ( cfg . BaseInterval . Seconds ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . evalAppliedFunc  =  cfg . EvalAppliedFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . stopAppliedFunc  =  cfg . StopAppliedFunc 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  evalApplied ( alertDefKey  models . AlertRuleKey ,  now  time . Time )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  sch . evalAppliedFunc  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . evalAppliedFunc ( alertDefKey ,  now ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  stopApplied ( alertDefKey  models . AlertRuleKey )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  sch . stopAppliedFunc  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . stopAppliedFunc ( alertDefKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  Pause ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  sch  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "scheduler is not initialised" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . heartbeat . Pause ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									sch . log . Info ( "alert rule scheduler paused" ,  "now" ,  sch . clock . Now ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  Unpause ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  sch  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  fmt . Errorf ( "scheduler is not initialised" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . heartbeat . Unpause ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									sch . log . Info ( "alert rule scheduler unpaused" ,  "now" ,  sch . clock . Now ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-25 06:34:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  Ticker ( grafanaCtx  context . Context ,  stateTracker  * state . StateTracker )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									dispatcherGroup ,  ctx  :=  errgroup . WithContext ( grafanaCtx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										select  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										case  tick  :=  <- sch . heartbeat . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											tickNum  :=  tick . Unix ( )  /  int64 ( sch . baseInterval . Seconds ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											alertRules  :=  sch . fetchAllDetails ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sch . log . Debug ( "alert rules fetched" ,  "count" ,  len ( alertRules ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											// registeredDefinitions is a map used for finding deleted alert rules
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// initially it is assigned to all known alert rules from the previous cycle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// each alert rule found also in this cycle is removed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// so, at the end, the remaining registered alert rules are the deleted ones
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											registeredDefinitions  :=  sch . registry . keyMap ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											type  readyToRunItem  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												key       models . AlertRuleKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ruleInfo  alertRuleInfo 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											readyToRun  :=  make ( [ ] readyToRunItem ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											for  _ ,  item  :=  range  alertRules  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 04:19:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												key  :=  item . GetKey ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												itemVersion  :=  item . Version 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												newRoutine  :=  ! sch . registry . exists ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ruleInfo  :=  sch . registry . getOrCreateInfo ( key ,  itemVersion ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												invalidInterval  :=  item . IntervalSeconds % int64 ( sch . baseInterval . Seconds ( ) )  !=  0 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  newRoutine  &&  ! invalidInterval  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													dispatcherGroup . Go ( func ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														return  sch . ruleRoutine ( ctx ,  key ,  ruleInfo . evalCh ,  ruleInfo . stopCh ,  stateTracker ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  invalidInterval  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													// this is expected to be always false
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													// give that we validate interval during alert rule updates
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													sch . log . Debug ( "alert rule with invalid interval will be ignored: interval should be divided exactly by scheduler interval" ,  "key" ,  key ,  "interval" ,  time . Duration ( item . IntervalSeconds ) * time . Second ,  "scheduler interval" ,  sch . baseInterval ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												itemFrequency  :=  item . IntervalSeconds  /  int64 ( sch . baseInterval . Seconds ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												if  item . IntervalSeconds  !=  0  &&  tickNum % itemFrequency  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													readyToRun  =  append ( readyToRun ,  readyToRunItem { key :  key ,  ruleInfo :  ruleInfo } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												// remove the alert rule from the registered alert rules
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 23:45:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												delete ( registeredDefinitions ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											var  step  int64  =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  len ( readyToRun )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												step  =  sch . baseInterval . Nanoseconds ( )  /  int64 ( len ( readyToRun ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  i  :=  range  readyToRun  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												item  :=  readyToRun [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												time . AfterFunc ( time . Duration ( int64 ( i ) * step ) ,  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													item . ruleInfo . evalCh  <-  & evalContext { now :  tick ,  version :  item . ruleInfo . version } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											// unregister and stop routines of the deleted alert rules
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 23:45:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											for  key  :=  range  registeredDefinitions  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ruleInfo ,  err  :=  sch . registry . get ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													sch . log . Error ( "failed to get alert rule routine information" ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ruleInfo . stopCh  <-  struct { } { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 23:52:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												sch . registry . del ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  <- grafanaCtx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											err  :=  dispatcherGroup . Wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											sch . saveAlertStates ( stateTracker . GetAll ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  sendAlerts ( alerts  [ ] * notifier . PostableAlert )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 00:37:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  sch . notifier . PutAlerts ( alerts ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  saveAlertStates ( states  [ ] state . AlertState )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . log . Debug ( "saving alert states" ,  "count" ,  len ( states ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  s  :=  range  states  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cmd  :=  models . SaveAlertInstanceCommand { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DefinitionOrgID :    s . OrgID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DefinitionUID :      s . UID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Labels :             models . InstanceLabels ( s . Labels ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											State :              models . InstanceStateType ( s . State . String ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											LastEvalTime :       s . LastEvaluationTime , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CurrentStateSince :  s . StartsAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											CurrentStateEnd :    s . EndsAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										err  :=  sch . store . SaveAlertInstance ( & cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sch . log . Error ( "failed to save alert state" ,  "uid" ,  s . UID ,  "orgId" ,  s . OrgID ,  "labels" ,  s . Labels . String ( ) ,  "state" ,  s . State . String ( ) ,  "msg" ,  err . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( sch  * schedule )  WarmStateCache ( st  * state . StateTracker )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sch . log . Info ( "warming cache for startup" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									st . ResetCache ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									orgIdsCmd  :=  models . FetchUniqueOrgIdsQuery { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  :=  sch . store . FetchOrgIds ( & orgIdsCmd ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sch . log . Error ( "unable to fetch orgIds" ,  "msg" ,  err . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  states  [ ] state . AlertState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  orgIdResult  :=  range  orgIdsCmd . Result  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cmd  :=  models . ListAlertInstancesQuery { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DefinitionOrgID :  orgIdResult . DefinitionOrgID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  :=  sch . store . ListAlertInstances ( & cmd ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sch . log . Error ( "unable to fetch previous state" ,  "msg" ,  err . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  _ ,  entry  :=  range  cmd . Result  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-14 05:38:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											lbs  :=  map [ string ] string ( entry . Labels ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-02 23:11:33 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											stateForEntry  :=  state . AlertState { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												UID :                 entry . DefinitionUID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												OrgID :               entry . DefinitionOrgID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												CacheId :             fmt . Sprintf ( "%s %s" ,  entry . DefinitionUID ,  lbs ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Labels :              lbs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												State :               translateInstanceState ( entry . CurrentState ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Results :             [ ] state . StateEvaluation { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												StartsAt :            entry . CurrentStateSince , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												EndsAt :              entry . CurrentStateEnd , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												LastEvaluationTime :  entry . LastEvalTime , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											states  =  append ( states ,  stateForEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									st . Put ( states ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  translateInstanceState ( state  models . InstanceStateType )  eval . State  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  state  ==  models . InstanceStateFiring : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  eval . Alerting 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  state  ==  models . InstanceStateNormal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  eval . Normal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  eval . Error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								type  alertRuleRegistry  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									mu             sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									alertRuleInfo  map [ models . AlertRuleKey ] alertRuleInfo 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// getOrCreateInfo returns the channel for the specific alert rule
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// if it does not exists creates one and returns it
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  getOrCreateInfo ( key  models . AlertRuleKey ,  ruleVersion  int64 )  alertRuleInfo  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									r . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  r . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									info ,  ok  :=  r . alertRuleInfo [ key ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										r . alertRuleInfo [ key ]  =  alertRuleInfo { evalCh :  make ( chan  * evalContext ) ,  stopCh :  make ( chan  struct { } ) ,  version :  ruleVersion } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  r . alertRuleInfo [ key ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									info . version  =  ruleVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									r . alertRuleInfo [ key ]  =  info 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  info 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// get returns the channel for the specific alert rule
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// if the key does not exist returns an error
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  get ( key  models . AlertRuleKey )  ( * alertRuleInfo ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									r . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  r . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									info ,  ok  :=  r . alertRuleInfo [ key ] 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  fmt . Errorf ( "%v key not found" ,  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & info ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  exists ( key  models . AlertRuleKey )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									r . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  r . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_ ,  ok  :=  r . alertRuleInfo [ key ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  ok 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  del ( key  models . AlertRuleKey )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									r . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  r . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									delete ( r . alertRuleInfo ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  iter ( )  <- chan  models . AlertRuleKey  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c  :=  make ( chan  models . AlertRuleKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									f  :=  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										r . mu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										defer  r . mu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  k  :=  range  r . alertRuleInfo  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											c  <-  k 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										close ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									go  f ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( r  * alertRuleRegistry )  keyMap ( )  map [ models . AlertRuleKey ] struct { }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									definitionsIDs  :=  make ( map [ models . AlertRuleKey ] struct { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-07 23:45:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  k  :=  range  r . iter ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										definitionsIDs [ k ]  =  struct { } { } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  definitionsIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-04 01:13:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								type  alertRuleInfo  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-11 22:14:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									evalCh   chan  * evalContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									stopCh   chan  struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-17 22:00:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									version  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  evalContext  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									now      time . Time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									version  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}