github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/alerts/alertsHandler/cronJobHandler.go (about) 1 package alertsHandler 2 3 /* 4 Copyright 2023. 5 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 See the License for the specific language governing permissions and 16 limitations under the License. 17 */ 18 19 import ( 20 "time" 21 22 "github.com/go-co-op/gocron" 23 "github.com/siglens/siglens/pkg/alerts/alertutils" 24 "github.com/siglens/siglens/pkg/ast/pipesearch" 25 log "github.com/sirupsen/logrus" 26 ) 27 28 var s = gocron.NewScheduler(time.UTC) 29 30 func VerifyAlertCronJobExists(alertDataObj *alertutils.AlertDetails) bool { 31 job_ids := s.GetAllTags() 32 for _, id := range job_ids { 33 if alertDataObj.AlertId == id { 34 return true 35 } 36 } 37 return false 38 } 39 40 func AddCronJob(alertDataObj *alertutils.AlertDetails) (*gocron.Job, error) { 41 evaluationIntervalInSec := int(alertDataObj.EvalInterval * 60) 42 43 cron_job, err := s.Every(evaluationIntervalInSec).Second().Tag(alertDataObj.AlertId).DoWithJobDetails(evaluate, alertDataObj) 44 if err != nil { 45 log.Errorf("AddCronJob: Error adding a new cronJob to the CRON Scheduler: %s", err) 46 return &gocron.Job{}, err 47 } 48 s.StartAsync() 49 //TODO: for multinode set up, set create and set node_id to which this alert will be assigned 50 //TODO: node_id should be created using hash function 51 return cron_job, nil 52 } 53 54 func AddMinionSearchCronJob(alertDataObj *alertutils.MinionSearch) (*gocron.Job, error) { 55 evaluationIntervalInSec := int(alertDataObj.EvalInterval * 60) 56 57 cron_job, err := s.Every(evaluationIntervalInSec).Second().Tag(alertDataObj.AlertId).DoWithJobDetails(evaluateMinionSearch, alertDataObj) 58 if err != nil { 59 log.Errorf("AddMinionSearchCronJob: Error adding a new cronJob to the CRON Scheduler: %s", err) 60 return &gocron.Job{}, err 61 } 62 s.StartAsync() 63 //TODO: for multinode set up, set create and set node_id to which this alert will be assigned 64 //TODO: node_id should be created using hash function 65 return cron_job, nil 66 } 67 68 func RemoveCronJob(alertId string) error { 69 err := s.RemoveByTag(alertId) 70 if err != nil { 71 log.Errorf("ALERTSERVICE: RemoveCronJob error %v.", err) 72 return err 73 } 74 return nil 75 } 76 77 func evaluate(alertToEvaluate *alertutils.AlertDetails, job gocron.Job) { 78 serResVal := pipesearch.ProcessAlertsPipeSearchRequest(alertToEvaluate.QueryParams) 79 if serResVal == -1 { 80 log.Errorf("ALERTSERVICE: evaluate: Empty response returned by server.") 81 return 82 } 83 isFiring := evaluateConditions(serResVal, &alertToEvaluate.Condition, alertToEvaluate.Value) 84 if isFiring { 85 err := updateAlertState(alertToEvaluate.AlertId, alertutils.Firing) 86 87 if err != nil { 88 log.Errorf("ALERTSERVICE: evaluate: could not update the state to FIRING. Alert=%+v & err=%+v.", alertToEvaluate.AlertName, err) 89 90 } 91 92 alertEvent := alertutils.AlertHistoryDetails{ 93 AlertId: alertToEvaluate.AlertId, 94 EventDescription: alertutils.AlertFiring, 95 UserName: alertutils.SystemGeneratedAlert, 96 EventTriggeredAt: time.Now().UTC(), 97 } 98 _, err = databaseObj.CreateAlertHistory(&alertEvent) 99 if err != nil { 100 log.Errorf("ALERTSERVICE: evaluate: could not create alert event in alert history. found error = %v", err) 101 } 102 err = NotifyAlertHandlerRequest(alertToEvaluate.AlertId) 103 if err != nil { 104 log.Errorf("ALERTSERVICE: evaluate: could not setup the notification handler. found error = %v", err) 105 return 106 } 107 } else { 108 err := updateAlertState(alertToEvaluate.AlertId, alertutils.Inactive) 109 if err != nil { 110 log.Errorf("ALERTSERVICE: evaluate: could not update the state to INACTIVE. Alert=%+v & err=%+v.", alertToEvaluate.AlertName, err) 111 112 } 113 114 alertEvent := alertutils.AlertHistoryDetails{ 115 AlertId: alertToEvaluate.AlertId, 116 EventDescription: alertutils.AlertNormal, 117 UserName: alertutils.SystemGeneratedAlert, 118 EventTriggeredAt: time.Now().UTC(), 119 } 120 _, err = databaseObj.CreateAlertHistory(&alertEvent) 121 if err != nil { 122 log.Errorf("ALERTSERVICE: evaluate: could not create alert event in alert history. found error = %v", err) 123 } 124 125 } 126 } 127 128 func updateAlertState(alertId string, alertState alertutils.AlertState) error { 129 err := databaseObj.UpdateAlertStateByAlertID(alertId, alertState) 130 return err 131 } 132 133 func evaluateConditions(serResVal int, queryCond *alertutils.AlertQueryCondition, val float32) bool { 134 switch *queryCond { 135 case alertutils.IsAbove: 136 return serResVal > int(val) 137 case alertutils.IsBelow: 138 return serResVal < int(val) 139 case alertutils.IsEqualTo: 140 return serResVal == int(val) 141 case alertutils.IsNotEqualTo: 142 return serResVal != int(val) 143 case alertutils.HasNoValue: 144 return serResVal == 0 145 default: 146 return false 147 } 148 } 149 150 func evaluateMinionSearch(msToEvaluate *alertutils.MinionSearch, job gocron.Job) { 151 serResVal := pipesearch.ProcessAlertsPipeSearchRequest(msToEvaluate.QueryParams) 152 if serResVal == -1 { 153 log.Errorf("MinionSearch: evaluate: Empty response returned by server.") 154 return 155 } 156 isFiring := evaluateConditions(serResVal, &msToEvaluate.Condition, msToEvaluate.Value) 157 if isFiring { 158 err := updateMinionSearchState(msToEvaluate.AlertId, alertutils.Firing) 159 if err != nil { 160 log.Errorf("MinionSearch: evaluate: could not update the state to FIRING. Alert=%+v & err=%+v.", msToEvaluate.AlertName, err) 161 } 162 163 alertEvent := alertutils.AlertHistoryDetails{ 164 AlertId: msToEvaluate.AlertId, 165 EventDescription: alertutils.AlertFiring, 166 UserName: alertutils.SystemGeneratedAlert, 167 EventTriggeredAt: time.Now().UTC(), 168 } 169 _, err = databaseObj.CreateAlertHistory(&alertEvent) 170 if err != nil { 171 log.Errorf("MinionSearch: evaluate: could not create alert event in alert history. found error = %v", err) 172 173 } 174 err = NotifyAlertHandlerRequest(msToEvaluate.AlertId) 175 if err != nil { 176 log.Errorf("MinionSearch: evaluate: could not setup the notification handler. found error = %v", err) 177 return 178 } 179 } else { 180 err := updateMinionSearchState(msToEvaluate.AlertId, alertutils.Inactive) 181 if err != nil { 182 log.Errorf("MinionSearch: evaluate: could not update the state to INACTIVE. Alert=%+v & err=%+v.", msToEvaluate.AlertName, err) 183 184 } 185 186 alertEvent := alertutils.AlertHistoryDetails{ 187 AlertId: msToEvaluate.AlertId, 188 EventDescription: alertutils.AlertNormal, 189 UserName: alertutils.SystemGeneratedAlert, 190 EventTriggeredAt: time.Now().UTC(), 191 } 192 _, err = databaseObj.CreateAlertHistory(&alertEvent) 193 if err != nil { 194 log.Errorf("MinionSearch: evaluate: could not create alert event in alert history. found error = %v", err) 195 196 } 197 } 198 } 199 200 func updateMinionSearchState(alertId string, alertState alertutils.AlertState) error { 201 err := databaseObj.UpdateMinionSearchStateByAlertID(alertId, alertState) 202 return err 203 }