- Use Google Distroless images for all services (Go & Node.js). - Standardize documentation with [PROJECT-NAME].md. - Add .dockerignore and .gitignore to all projects. - Remove docker-compose.yml in favor of docker run instructions. - Fix Go version and dependency issues in observability, repo-integrations, and security-governance. - Add Podman support (fully qualified image names). - Update Dashboard to use Node.js static server for Distroless compatibility.
85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package alerter
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/lab/observability-core/internal/db"
|
|
)
|
|
|
|
type Alerter struct {
|
|
queries *db.Queries
|
|
}
|
|
|
|
func New(queries *db.Queries) *Alerter {
|
|
return &Alerter{queries: queries}
|
|
}
|
|
|
|
func (a *Alerter) Start() {
|
|
log.Println("Starting alerter")
|
|
ticker := time.NewTicker(30 * time.Second) // Run every 30 seconds
|
|
|
|
go func() {
|
|
for range ticker.C {
|
|
a.runAlerts()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (a *Alerter) runAlerts() {
|
|
rules, err := a.queries.ListAlertRules(context.Background())
|
|
if err != nil {
|
|
log.Printf("Error listing alert rules: %v", err)
|
|
return
|
|
}
|
|
|
|
for _, rule := range rules {
|
|
go a.evaluateRule(rule)
|
|
}
|
|
}
|
|
|
|
func (a *Alerter) evaluateRule(rule db.AlertRule) {
|
|
// This is a very simplified logic.
|
|
// It should query metrics within the `for_duration` and check if they meet the threshold.
|
|
// For now, we'll just log a message.
|
|
log.Printf("Evaluating alert rule: %s", rule.Name)
|
|
|
|
// A real implementation would look something like this:
|
|
/*
|
|
params := db.GetMetricsForCheckParams{
|
|
CheckID: rule.CheckID,
|
|
StartTime: time.Now().Add(-time.Duration(rule.ForDuration) * time.Second),
|
|
EndTime: time.Now(),
|
|
}
|
|
metrics, err := a.queries.GetMetricsForCheck(context.Background(), params)
|
|
if err != nil {
|
|
log.Printf("Error getting metrics for rule %s: %v", rule.Name, err)
|
|
return
|
|
}
|
|
|
|
isFailing := true
|
|
for _, metric := range metrics {
|
|
if !compare(metric.Value, rule.Threshold, rule.Operator) {
|
|
isFailing = false
|
|
break
|
|
}
|
|
}
|
|
|
|
if isFailing {
|
|
// Create or update incident
|
|
}
|
|
*/
|
|
}
|
|
|
|
func compare(value, threshold float64, operator string) bool {
|
|
switch operator {
|
|
case ">":
|
|
return value > threshold
|
|
case "<":
|
|
return value < threshold
|
|
case "=":
|
|
return value == threshold
|
|
}
|
|
return false
|
|
}
|