Tüm yazılar
·7 dk okuma·ShamashAi Ekibi

ShamashAi Maintenance Windows: planlı bakımda alarm sessiz, log kaybı yok

ShamashAi maintenance_windows modülü, planlı bakım pencerelerinde alert evaluation'ı atlar, log ingestion devam eder. Gece 03:00 false-alarm'larına son verin; scope: project, site veya device seviyesi. Audit trail korunur.

Cuma 02:47 — DC-01 "patlıyor" ama siz yama yüklüyorsunuz

Cuma gecesi 02:47'de telefonunuz titreşir. ShamashAi mobil app: "DC-01: CPU %98, 14 failed authentication, service restart loop". Hemen Discord'u açıyorsunuz — ekip zaten uyanık: "Abi bakım başladı 02:30'da, DC'yi yeniden başlatacağız, normal bu." Siz de hatırlıyorsunuz: Çarşamba toplantısında Windows Server 2019→2022 upgrade'i planlamıştınız, takvime de eklemiştiniz. Ama ShamashAi'a söylemeyi unuttunuz. Maintenance windows olmadan, SIEM planlı bakımı saldırıdan ayırt edemez. Sonuç: 40 dakikalık bakım → 160 critical alert → 6 kişi uykusuz → ertesi gün morale sıfır. Ya da alert engine'i elle kapatırsınız — o zaman gerçek saldırı olursa göremezsiniz. Ya da ingest'i durdurursunız — 40 dakikalık log kaybı, compliance problemi. ShamashAi'nin Maintenance Windows modülü bu kısır döngüyü kırar: scope (project / site / device), zaman penceresi ve sebep tanımlarsınız; window aktif olduğu sürece alert evaluation atlanır, ama log ingestion devam eder. Bakım bitince audit trail eksiksiz, false-alarm sıfır.

ShamashAi maintenance_windows tablosu ve scope yapısı

ShamashAi'de planlı sessizlik dbo.maintenance_windows tablosunda saklanır. Her pencere şu bilgileri tutar:
  • scope_type: project, site veya device
  • scope_id: hangi proje / site / cihaz için (UUID)
  • starts_at: ISO 8601 timestamp (Europe/Istanbul)
  • ends_at: bitiş zamanı
  • reason: "DC-01 Windows Server upgrade", "Fiber hat kesme çalışması" gibi serbest metin
  • created_by: hangi kullanıcı tanımladı (dbo.users foreign key)
  • status: scheduled, active, completed, cancelled
Örnek pencere: sql INSERT INTO dbo.maintenance_windows (scope_type, scope_id, starts_at, ends_at, reason, created_by) VALUES ('device', 'a3f7c...-device-uuid', '2026-09-12T02:30:00+03:00', '2026-09-12T04:00:00+03:00', 'DC-01 Windows Server 2022 upgrade + reboot', 'u-4d91...-user-uuid'); Scope hiyerarşisi:
  • project: tüm proje sessiz (tüm site'ler, tüm device'lar)
  • site: o site'deki tüm cihazlar sessiz
  • device: sadece o cihaz sessiz
ShamashAi alert rule evaluator, her event için önce dbo.maintenance_windows tablosunu kontrol eder: csharp // .NET 8 alert evaluator snippet (ShamashAi Agent codebase) var activeWindow = await _dbContext.MaintenanceWindows .Where(w => w.Status == "active" && w.StartsAt <= utcNow && w.EndsAt >= utcNow && ( (w.ScopeType == "project" && w.ScopeId == evt.ProjectId) || (w.ScopeType == "site" && w.ScopeId == evt.SiteId) || (w.ScopeType == "device" && w.ScopeId == evt.DeviceId) )) .FirstOrDefaultAsync(); if (activeWindow != null) { _logger.LogDebug("Event {EventId} skip alert eval: maintenance window {WindowId}", evt.Id, activeWindow.Id); await _dbContext.AuditLog.AddAsync(new AuditEntry { Action = "ALERT_EVAL_SKIPPED", Reason = $"Maintenance window: {activeWindow.Reason}", EventId = evt.Id, WindowId = activeWindow.Id }); return; // alert rule evaluation atlanır } Eğer aktif pencere varsa alert evaluation atlanır, ama event dbo.events tablosuna yazılır. Log kaybı yok.

POST /maintenance-windows — pencere oluşturma

Yeni pencere oluşturmak için ShamashAi API: javascript // Node.js Fastify route (ShamashAi API) fastify.post('/maintenance-windows', { schema: { body: { type: 'object', required: ['scope_type', 'scope_id', 'starts_at', 'ends_at', 'reason'], properties: { scope_type: { type: 'string', enum: ['project', 'site', 'device'] }, scope_id: { type: 'string', format: 'uuid' }, starts_at: { type: 'string', format: 'date-time' }, ends_at: { type: 'string', format: 'date-time' }, reason: { type: 'string', maxLength: 500 } } } }, preHandler: fastify.authenticate // JWT token }, async (req, reply) => { const { scope_type, scope_id, starts_at, ends_at, reason } = req.body; const userId = req.user.id; // Validation: ends_at > starts_at if (new Date(ends_at) <= new Date(starts_at)) { return reply.code(400).send({ error: 'ends_at must be after starts_at' }); } // Scope existence check const scopeExists = await checkScopeExists(scope_type, scope_id); if (!scopeExists) { return reply.code(404).send({ error: ${scope_type} ${scope_id} not found }); } const windowId = uuidv4(); await fastify.db.query( `INSERT INTO dbo.maintenance_windows (id, scope_type, scope_id, starts_at, ends_at, reason, created_by, status) VALUES (@id, @scope_type, @scope_id, @starts_at, @ends_at, @reason, @created_by, 'scheduled')`, { id: windowId, scope_type, scope_id, starts_at, ends_at, reason, created_by: userId } ); await fastify.audit.log({ action: 'MAINTENANCE_WINDOW_CREATED', user_id: userId, resource_id: windowId, details: { scope_type, scope_id, starts_at, ends_at, reason } }); return reply.code(201).send({ id: windowId, status: 'scheduled' }); }); Status geçişleri:
  • scheduledactive (starts_at geldiğinde background worker otomatik değiştirir)
  • activecompleted (ends_at geldiğinde)
  • scheduled | activecancelled (manuel iptal)
ShamashAi background worker her 30 saniyede dbo.maintenance_windows tarar: javascript // Node.js background worker (ShamashAi API) setInterval(async () => { const now = new Date().toISOString(); // scheduled → active await fastify.db.query( `UPDATE dbo.maintenance_windows SET status = 'active' WHERE status = 'scheduled' AND starts_at <= @now`, { now } ); // active → completed await fastify.db.query( `UPDATE dbo.maintenance_windows SET status = 'completed' WHERE status = 'active' AND ends_at <= @now`, { now } ); }, 30_000);

Ingest devam eder, alert evaluation atlanır

Önemli: Maintenance window alert'leri susturur, ama log ingestion'ı durdurmaz. ShamashAi Agent (Node.js veya .NET 8 syslog listener), cihazdan gelen event'leri dbo.events tablosuna yazar: csharp // .NET 8 Agent syslog handler public async Task HandleSyslogMessage(SyslogMessage msg) { var evt = new Event { Id = Guid.NewGuid(), DeviceId = msg.DeviceId, SiteId = await GetSiteIdForDevice(msg.DeviceId), ProjectId = await GetProjectIdForDevice(msg.DeviceId), Timestamp = msg.Timestamp, RawLog = msg.RawMessage, Severity = msg.Severity }; // Event insert (maintenance window olsun olmasın) await _dbContext.Events.AddAsync(evt); await _dbContext.SaveChangesAsync(); // Alert rule evaluation (maintenance window varsa atlanır) await EvaluateAlertRules(evt); } EvaluateAlertRules fonksiyonu yukarıda gördüğünüz gibi aktif pencereyi kontrol eder. Pencere varsa dbo.audit_log'a "ALERT_EVAL_SKIPPED" yazar, alert oluşturmaz. Bu sayede:
  • Bakım bittikten sonra log timeline eksiksiz
  • Compliance evidence pack'e dahil
  • Forensics analiz yapabilirsiniz

Web arayüzü: Next.js takvim görünümü

ShamashAi web paneli (Next.js) /maintenance sayfasında pencere listesi ve takvim görünümü sunar: typescript // Next.js page component (ShamashAi Web) import { useQuery } from '@tanstack/react-query'; import { Calendar } from '@/components/Calendar'; const apiUrl = process.env.NEXT_PUBLIC_API_URL; interface MaintenanceWindow { id: string; scope_type: 'project' | 'site' | 'device'; scope_id: string; starts_at: string; ends_at: string; reason: string; status: 'scheduled' | 'active' | 'completed' | 'cancelled'; } export default function MaintenancePage() { const { data: windows } = useQuery<MaintenanceWindow[]>( ['maintenance-windows'], async () => { const res = await fetch(${apiUrl}/maintenance-windows, { headers: { Authorization: Bearer ${getToken()} } }); return res.json(); } ); const calendarEvents = windows?.map(w => ({ title: w.reason, start: new Date(w.starts_at), end: new Date(w.ends_at), color: w.status === 'active' ? 'orange' : 'gray' })); return ( <div> <h1>Planlı Bakım Pencereleri</h1> <Calendar events={calendarEvents} /> <button onClick={() => openCreateModal()}>Yeni Pencere</button> </div> ); } Yeni pencere oluşturmak için modal: typescript const createWindow = async (data: CreateWindowInput) => { const res = await fetch(${apiUrl}/maintenance-windows, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: Bearer ${getToken()} }, body: JSON.stringify(data) }); if (!res.ok) throw new Error('Failed to create window'); return res.json(); };

Audit trail: geçmiş pencereler retention-immune

ShamashAi'de dbo.events tablosu retention policy'ye tabidir (örneğin 90 gün). Ama dbo.maintenance_windows retention-immune: geçmiş pencereler silinmez. KVKK Madde 12 uyarınca "işleme amacı ortadan kalktığında" silme gerekir, ama maintenance window audit trail "hukuki yükümlülük" kapsamında saklanır (örneğin: "O tarihte neden alert çıkmadı?" sorusuna cevap). Sorgu örneği: sql -- 2026 Eylül ayında DC-01 için hangi pencereler aktifti? SELECT mw.starts_at, mw.ends_at, mw.reason, mw.status, u.email AS created_by_email FROM dbo.maintenance_windows mw JOIN dbo.users u ON mw.created_by = u.id WHERE mw.scope_type = 'device' AND mw.scope_id = 'a3f7c...-device-uuid' AND mw.starts_at >= '2026-09-01' AND mw.starts_at < '2026-10-01' ORDER BY mw.starts_at; Audit log'da hangi event'lerin window nedeniyle atlandığını görebilirsiniz: sql SELECT al.timestamp, al.action, -- 'ALERT_EVAL_SKIPPED' al.reason, -- 'Maintenance window: DC-01 Windows Server 2022 upgrade + reboot' e.event_type, e.source_ip FROM dbo.audit_log al JOIN dbo.events e ON al.event_id = e.id WHERE al.action = 'ALERT_EVAL_SKIPPED' AND al.timestamp >= '2026-09-12T02:30:00' AND al.timestamp <= '2026-09-12T04:00:00';

Overlap ve manuel iptal senaryoları

ShamashAi aynı scope için overlap eden pencereler oluşturmanıza izin verir (ör. "DC-01 02:30-04:00" ve "DC-01 03:00-05:00"). Alert evaluator en uzun pencereyi dikkate alır — 02:30-05:00 arası sessiz. Manuel iptal: javascript // PATCH /maintenance-windows/:id/cancel fastify.patch('/maintenance-windows/:id/cancel', { preHandler: fastify.authenticate }, async (req, reply) => { const { id } = req.params; const userId = req.user.id; const result = await fastify.db.query( `UPDATE dbo.maintenance_windows SET status = 'cancelled' WHERE id = @id AND status IN ('scheduled', 'active')`, { id } ); if (result.rowsAffected === 0) { return reply.code(404).send({ error: 'Window not found or already completed' }); } await fastify.audit.log({ action: 'MAINTENANCE_WINDOW_CANCELLED', user_id: userId, resource_id: id }); return reply.send({ status: 'cancelled' }); }); İptal edilen pencere artık alert'leri susturmaz, ama audit trail'de kalır.

Gerçek dünya senaryoları

Bir orta ölçekli Türk e-ticaret firması haftalık veritabanı bakımını Pazar 03:00-05:00 arası yapar. ShamashAi'a her Pazar için tekrarlayan pencere tanımlamak isterse: ShamashAi dokümantasyonu recurring window özelliği hakkında daha fazla bilgi vermiyor; şu an her pencereyi elle oluşturmanız gerekir. Pilot kapsamında detay paylaşılır. Başka senaryo: Fiber hat kesme çalışması, ISP bildirimi "09 Eylül 10:00-12:00 internet kesilecek". VPN gateway cihazı için pencere: { "scope_type": "device", "scope_id": "vpn-gw-uuid", "starts_at": "2026-09-09T10:00:00+03:00", "ends_at": "2026-09-09T12:00:00+03:00", "reason": "ISP fiber hat bakımı — internet kesilecek" } Bu pencere sırasında CONN_DOWN, VPN_TUNNEL_LOST gibi alert'ler tetiklenmez.

Limitler ve dürüst notlar

  • Recurring window yok: Her pencereyi manuel oluşturmalısınız. API veya web UI üzerinden toplu oluşturma mümkün, ama "her Pazar 03:00" gibi CRON mantığı yok.
  • Granular alert scope yok: Maintenance window tüm alert rule'ları susturur. "Sadece CPU alert'leri sessiz olsun, AUTH_FAIL devam etsin" seçeneği yok.
  • Bildirim iptali yok: Alert oluşturulmaz ama event dbo.events'de; isterseniz manuel sorgu ile görebilirsiniz. Push bildirimi veya e-posta otomatik gitmez.
  • Timezone: API ISO 8601 bekler; web UI Europe/Istanbul kabul eder. Farklı timezone senaryosu dokümantasyonda detaylandırılmamış.
  • Max pencere süresi yok: 10 dakikalık veya 10 günlük pencere tanımlayabilirsiniz, ama uzun pencereler yanlışlıkla gerçek incident'i maskeleyebilir — manuel review tavsiye edilir.

Planlı bakım pencerelerini ShamashAi'ya bildirmek, false-alarm gürültüsünü keser, ekip moralini korur ve log timeline'ı eksiksiz tutar. Pilot programı 30 gün ücretsiz: shamashai.com.tr/iletisim
Paylaş

Bu konuyu projenize uygulayalım

Pilot programı kapsamında ürünü gerçek altyapınızda 30 gün ücretsiz deneyin.