Bugfix Problem Metrics
All checks were successful
release-tag / release-image (push) Successful in 5m59s

This commit is contained in:
2026-04-29 15:02:27 +02:00
parent 5e45b8cae8
commit d93151746c

94
main.go
View File

@@ -1688,6 +1688,7 @@ func main() {
s.templates = tmpl
go s.runSOCLoop()
go s.runBaselineLoop()
go s.runDetectionLoop()
mux := http.NewServeMux()
@@ -1756,6 +1757,53 @@ func (s *server) runSOCLoop() {
}
}
func (s *server) runBaselineLoop() {
ticker := time.NewTicker(s.cfg.DetectionInterval)
defer ticker.Stop()
s.runBaselineOnce()
for range ticker.C {
s.runBaselineOnce()
}
}
func (s *server) runBaselineOnce() {
if !s.cfg.BaselineEnabled {
return
}
rules := []struct {
name string
timeout time.Duration
fn func(context.Context) error
}{
{"baseline_anomaly", 120 * time.Second, s.detector.runBaselineAnomalyRule},
{"baseline_update", 120 * time.Second, s.detector.runBaselineUpdate},
}
for _, rule := range rules {
start := time.Now()
ctx, cancel := context.WithTimeout(context.Background(), rule.timeout)
err := rule.fn(ctx)
cancel()
dur := time.Since(start)
if err != nil {
s.logger.Printf("baseline rule %s error after %s: %v", rule.name, dur, err)
s.detector.ruleErrorsTotal.WithLabelValues(rule.name).Inc()
continue
}
s.logger.Printf("baseline rule %s completed in %s", rule.name, dur)
s.detector.ruleLastRunGauge.WithLabelValues(rule.name).Set(float64(time.Now().Unix()))
s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(dur.Seconds())
}
}
func (s *server) runSOCOnce() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
@@ -3941,17 +3989,18 @@ func (d *detector) runBaselineUpdate(ctx context.Context) error {
windowEnd := time.Now().UTC()
windowStart := windowEnd.Add(-d.cfg.BaselineWindow)
hour := windowEnd.Hour()
dayOfWeek := int(windowEnd.Weekday()+6) % 7 // Go: Sonntag=0, MySQL WEEKDAY: Montag=0
rows, err := d.db.QueryContext(ctx, `
SELECT
hostname,
channel_name,
event_id,
HOUR(ts) AS hour_of_day,
WEEKDAY(ts) AS day_of_week,
COUNT(*) AS cnt
FROM event_logs
WHERE ts >= ? AND ts < ?
GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
GROUP BY hostname, channel_name, event_id
`, windowStart, windowEnd)
if err != nil {
return err
@@ -3964,13 +4013,14 @@ GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
&b.Hostname,
&b.Channel,
&b.EventID,
&b.Hour,
&b.DayOfWeek,
&b.Count,
); err != nil {
return err
}
b.Hour = hour
b.DayOfWeek = dayOfWeek
excluded, err := d.isBaselineExcluded(ctx, b.Hostname, b.Channel, b.EventID)
if err != nil {
return err
@@ -3995,6 +4045,12 @@ GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
return rows.Err()
}
func mysqlWeekday(t time.Time) int {
// MySQL WEEKDAY(): Monday=0 ... Sunday=6
// Go Weekday(): Sunday=0 ... Saturday=6
return (int(t.UTC().Weekday()) + 6) % 7
}
func (d *detector) hasConfirmedIncidentInWindow(ctx context.Context, hostname, channel string, eventID uint32, windowStart, windowEnd time.Time) (bool, error) {
var count int
@@ -4129,35 +4185,34 @@ func (d *detector) runBaselineAnomalyRule(ctx context.Context) error {
windowEnd := time.Now().UTC()
windowStart := windowEnd.Add(-d.cfg.BaselineWindow)
hour := windowEnd.Hour()
dayOfWeek := mysqlWeekday(windowEnd)
rows, err := d.db.QueryContext(ctx, `
SELECT
e.hostname,
e.channel_name,
e.event_id,
HOUR(e.ts) AS hour_of_day,
WEEKDAY(e.ts) AS day_of_week,
COUNT(*) AS cnt,
b.avg_count,
b.stddev_count,
b.sample_count
COALESCE(b.avg_count, 0),
COALESCE(b.stddev_count, 0),
COALESCE(b.sample_count, 0)
FROM event_logs e
JOIN baseline_event_stats b
LEFT JOIN baseline_event_stats b
ON b.hostname = e.hostname
AND b.channel_name = e.channel_name
AND b.event_id = e.event_id
AND b.hour_of_day = HOUR(e.ts)
AND b.day_of_week = WEEKDAY(e.ts)
AND b.hour_of_day = ?
AND b.day_of_week = ?
WHERE e.ts >= ? AND e.ts < ?
GROUP BY
e.hostname,
e.channel_name,
e.event_id,
HOUR(e.ts),
WEEKDAY(e.ts),
b.avg_count,
b.stddev_count,
b.sample_count
`, windowStart, windowEnd)
`, hour, dayOfWeek, windowStart, windowEnd)
if err != nil {
return err
}
@@ -4167,8 +4222,6 @@ GROUP BY
var host string
var channel string
var eventID uint32
var hour int
var dayOfWeek int
var count int
var avg float64
var stddev float64
@@ -4178,8 +4231,6 @@ GROUP BY
&host,
&channel,
&eventID,
&hour,
&dayOfWeek,
&count,
&avg,
&stddev,
@@ -4769,9 +4820,6 @@ func (s *server) runDetectionsOnce() {
{"new_source_ip_for_user", s.detector.runNewSourceIPForUserRule},
{"dynamic_rules", s.detector.runDynamicRules},
{"baseline_anomaly", s.detector.runBaselineAnomalyRule},
{"baseline_update", s.detector.runBaselineUpdate},
{"ueba_admin_new_host", s.detector.runAdminNewHostRule},
{"ueba_offhours_login", s.detector.runOffHoursLoginRule},
{"ueba_first_privileged_use", s.detector.runFirstTimePrivilegedRule},