Geçen hafta, sürekli büyüyen uygulama loglarını otomatik tarayıp kritik hataları bize mail atan bir bot yazdım. Python ile, Elasticsearch'ten veri çekip, belirli pattern'leri yakalayınca SMTP ile posta atıyordu. Harika çalışıyordu, ta ki...
Bir sabah uyandığımda telefonum çıldırmıştı. 347 yeni mail. Hepsi de botumdan, aynı konuyla: "CRITICAL: Aynı hata 1000+ kez tekrarlandı!". İlk düşüncem, "Vay be, sistem çökmüş!" oldu. Hemen terminali açtım.
Python:
if error_count > 1000:
send_alert("CRITICAL: Aynı hata 1000+ kez tekrarlandı!")
Sorun şuydu: Bot, logları okurken kendi gönderdiği "CRITICAL" alert maillerini de loglayan bir başka servisi okuyordu. Yani bot, kendi ürettiği hatayı görüyor, tekrar mail atıyor, bu da tekrar loglanıyor... Sonsuz bir döngü. StackOverflow'da bile böyle saçma bir özyineleme (recursion) örneği bulamazsınız.
Kafayı yiyecektim. Meğerse sorun, log kaynağını filtrelerken benim botun process ID'sini veya mesaj imzasını hariç tutmamış olmamdaymış. Çözüm basitti ama 3 saat debug ettim:
Python:
if "CRITICAL: Aynı hata" in log_line and "AlertBot-Signature" not in log_line:
# İşlemi yap
AlertBot-Signature diye özel bir string ekleyip, botun kendi ürettiği log satırlarını görmezden gelmesini sağladım. Bir de throttle mekanizması ekledim, aynı hata için 1 dakikada 1'den fazla mail atmasın diye.
Otomasyon yaparken, otomasyonun kendisinin sisteme nasıl etki edeceğini düşünmek zorundasın. Yoksa seni kendi silahınla vurur. Loglama yapıyorsan, log okuyan bir botun, kendi loglarını yememesi için mutlaka bir "kendini hariç tut" filtresi yaz.
Siz de benzer bir kendi kendini tetikleyen (self-triggering) saçmalık yaşadınız mı? Bu işin daha şık bir yolu var mı sizce? Yorumlarda fikirlerinizi bekliyorum, belki hep birlikte daha komik felaket hikayeleri duyarız.