Geçen birkaç ay, günlük ardışık sistemimizde anomali tespiti üzerinde çalıştım ve klasik eşik tabanlı uyarılardan LLM-yardımlı desen tespitine geçişin fark edilmesi kolay oldu. Ortamımda, yüzlerce Linux düğümünden gelen syslog akışları günlük olarak gigabaytlarca metin üretiyor ve gürültü içinde bazen görünen çekirdek hatası (kernel oops) veya modül yükleme başarısızlığı gibi nadir olsa da kritik sorunları bulmak, daha ve daha karmaşık grep zincirleri yazmak anlamına geliyordu. Küçük ve hızlı bir model olan GPT-4o mini’nin, bu nadir ama kritik satırları yanlış pozitif oranını minimumda tutarak işaretleyip ardından bir düzeltme playbook’ını otomatik olarak tetikleyip tetikleyemeyeceğini görmek istedim.
GPT-4o mini ile syslog anomali tespiti
Zaten merkezi bir ELK stack çalıştırıyorum, bu yüzden ham veri mevcut. Zorunlu olan veri toplama değil, yorumlamaktı: kernel: BUG: unable to handle kernel paging request at ffffffffc0a00000 gibi tek bir satır, bir donuk kilitlemeyi önceden gösterene kadar görünüşte zararsız görünürdü. Geleneksel regex kuralları ya varyantları kaçırdı ya da geliştirme çekirdeklerinden gelen benzer görünen debug çıktılarıyla yanlış pozitiflerle bize dolu doldurdu. GPT-4o mini, jeton başına ucuz ve bir saniye içinde yanıt veriyor, bu yüzden bütçeyi aşmadan dakikada bir son 5.000 satırın kayan penceresi üzerinde çalıştırabiliyorum.
Prompt engineering that worked
Birkaç iterasyon sonra bu sistem promptuna karar verdim:
Sen bir Linux çekirdeği mühendisi olarak syslog girişlerini inceleyen bir uzmansın.
Sadece gerçek bir anomaliyi gösteren satırları işaretle: çekirdek oops, kilitlenme, donanım hatası, dosya sistemi bozulması veya insan müdahalesi gerektiren modül yükleme hatası.
Bilgilendirici mesajları, rutin debug çıktılarını ve zararsız olarak bilinen desenleri yoksay.
Belirsiz olduğunda, tam olarak "NULL" kelimesini yanıt olarak ver.
Anomali varsa, orijinal satırı değiştirmeden çıktısını ver.
Kullanıcı mesajını sadece toplu log parçası olarak tutuyorum. Model ya da hatalı satırı aynen yansıtacak ya da NULL döndürecek. Bu sıkı sözleşme, sonrası işlemeyi çok basit yapıyor: NULL olmayan her yanıt, uyarı yöneticisine iletiliyor.
Uygulama Taslağı
Burada log toplayıcı üzerinde systemd servisi olarak çalıştırdığım Python kod parçacığı var:
import openai, os, sys, json
from datetime import datetime, timedelta
def fetch_recent_lines():
# Kurulumumda, Fluentd /var/log/aggregate/syslog- recent dosyasına yazıyor
cmd = ["tail", "-n", "5000", "/var/log/aggregate/syslog- recent"]
return os.popen(" ".join(cmd)).read().splitlines()
def call_model(lines):
client = openai.OpenAI(api_key=os.getenv"OPENAI_API_KEY")
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "\n".join(lines)}
],
temperature=0.0,
max_tokens=1024,
)
return resp.choices[0].message.content.strip()
if __name__ == "__main__":
lines = fetch_recent_lines()
out = call_model(lines)
if out and out != "NULL":
payload = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"host": os.uname().nodename,
"anomaly": out
}
# webhook veya logger'a gönder
sys.stdout.write(json.dumps(payload) + "\n")
Bu kodu kendisiyle çakışmayacak şekilde bir dakikalık zamanlayıcı birim içinde sarmaladım. Küçük bir VM'de CPU kullanımı %2'nin altında kalıyor; günlük ~300 MB syslog hacmi için OpenAI API faturalaması ortalama $0.03'in altında kalıyor.
Algoritmadan Eyleme
Satırı algılamak sadece mücadele yarısı; ben otomatik kısıtlama istiyordum. Betik bir JSON yükü çıktığında, yan Fluentd filtresi bunu eşleştirir ve olayı ayrı bir Kafka konusuna gönderir. Küçük bir Go tüketicisi daha sonra:
- Zenginleştirme ekler: son dmesg çıktısı, ilişkili systemd birimi durumu ve aynı hosttan gelen son 20 journalctl satırı.
- Host’u CMDB’mizde arar, sorumluluğu ve Slack kanalını belirler.
- O kanala, önceden onaylanmış bir Ansible Tower iş şablonunu tetikleyen (sosreport toplar, memtester çalıştırır ve bir bilet açar) bir tıkla "Tanılama Çalıştır" düğmesi olan biçimlendirilmiş bir mesaj gönderir.
Modelin yanlış pozitif oranı altı hafta süren denememde %5'in altında kaldığı için, sinyal-gürültü oranı yeterince iyileşti ve mühendisler uyarıyı susturmak yerine düğmeye tıklamaya başladı.
Çekinceler ve ayarlama ipuçları
- Belirteç sınırları: GPT-4o mini’nin bağlam penceresi 128k, ancak hızlı ve ucuz kalmak için toplu işleri 4k belirteç altında tutuyorum. Kesme görürseniz, toplu iş boyutunu düşürün veya kayan örtüşmeyi artırın.
- İstek sapması: Bir çekirdek yükseltmesinden sonra, model yeni
-[smpboot] Booting Nodesatırlarını anormal olarak işaretlemeye başladı. Bu sorunu önlemek için ön işleme aşamasında bilinen başlangıç mesajları için basit bir izin listesi regex’i ekledim. - Maliyet sürprizleri: API yanıtındaki
usagealanını izleyin; kaçan bir döngü para hızla tüketebilir. OpenAI’nin proje düzeyindeki bütçe özelliğiyle sert bir günlük sınır ekledim. - Gizlilik: Syslog’unuz PII veya dahili IP adresleri içeriyorsa, gönderimden önce temizleyin ya da Azure OpenAI’yi özel ağ uç noktalarıyla kullanın.
Sonuç
GPT-4o mini'yi syslog anomali tespiti için kullanmak, gerçek çekirdek hatalarını gürültüyle boğuşmadan tespit etme konusunda bana pratik bir avantaj sağladı. Yaklaşım, mevcut ardışık düzenlerin yanında çalıştırılabilecek kadar hafiftir ve geri bildirim döngüsü—algıla → zenginleştir → eylem—iki dakikadan kısa sürede tamamlanır. Eğer zaten günlükleri bir merkezi yere gönderiyorsanız, akışın sonunu iyi bir promptla desteklenen bir LLM çağrısıyla sarmak, bir hafta sonu deneyimi olarak değer yapar.
Önceden Auditd ve crontab değişiklikleriyle ilgili gönderimimde (<https://furkanikkan.com/urun/auditd-ile-yetkisiz-crontab-degisikliklerini-anlik-siem-e-aktarma-78>) belirttiğim gibi, "bir satırı algıla, zenginleştir, sonra otomatikleştir" deseni farklı kullanım durumlarında tekrarlanır; regex'i bir LLM ile değiştirmek, aynı araç setinin sadece başka bir aracıdır.
Kapak görseli: ₡ґǘșϯγ Ɗᶏ Ⱪᶅṏⱳդ · CC0 (Openverse / kamu malı) · https://www.flickr.com/photos/148598741@N02/51973552248
