diff --git a/ebpf/main.go b/ebpf/main.go index 8a2715cf..2f55f0ca 100644 --- a/ebpf/main.go +++ b/ebpf/main.go @@ -82,11 +82,73 @@ func isAmdArch() bool { return false } +func mainNew() { + // Start env update goroutine + go envUpdateGoroutine() + + // Run the main eBPF program + run() +} + +func nextLogLevel(current string) string { + levels := []string{"DEBUG", "INFO", "WARN", "ERROR"} + + for i, lvl := range levels { + if lvl == current { + return levels[(i+1)%len(levels)] + } + } + return "INFO" +} + +func envUpdateGoroutine() { + restartIntervalMinutes := 30 + trafficUtils.InitVar("RESTART_INTERVAL_MINUTES", &restartIntervalMinutes) + + ticker := time.NewTicker(time.Duration(restartIntervalMinutes) * time.Second) + defer ticker.Stop() + + slog.Info("๐Ÿงช Config watcher started", "interval_minutes", restartIntervalMinutes) + + for range ticker.C { + current := os.Getenv("AKTO_LOG_LEVEL") + next := nextLogLevel(current) + + slog.Info( + "๐Ÿ“ Configuration changed, restarting process...", + "old_AKTO_LOG_LEVEL", current, + "new_AKTO_LOG_LEVEL", next, + ) + + os.Setenv("AKTO_LOG_LEVEL", next) + restartSelf() + } +} + +func restartSelf() { + exe, err := os.Executable() + if err != nil { + slog.Error("Failed to get executable path", "error", err) + return + } + + slog.Info("๐Ÿ”„ Restarting process with new environment...") + + // Replace current process with fresh instance using updated environment + err = syscall.Exec(exe, os.Args, os.Environ()) + if err != nil { + slog.Error("Failed to restart process", "error", err) + } + // Never reaches here if Exec succeeds +} + func main() { // Setting GC percent as 50, uses less memory overhead. // More testing needed for final release. // debug.SetGCPercent(50) - run() + + // Use mainNew() which starts config watcher and runs eBPF + mainNew() } func run() {