Van egy tévhit, amibe majdnem mindenki belefut, aki automatizációkat üzemeltet: azt hiszi, hogy egy folyamat vagy fut, vagy nem fut — és ha nem fut, azt úgyis azonnal észreveszi. A valóság ennél alattomosabb. A legveszélyesebb állapot nem a leállás, hanem a csendes, félig-hibázó futás — amikor a folyamat technikailag elindul, ütemezetten, minden órában, minden nap, de belül valami elakad, és ezt semmi nem jelzi hangosan.
A konkrét eset
Volt egy 15 perces ütemezésű automatizációm, ami email-tartalmat dolgozott fel. Ha megnéztem volna csak azt, hogy „fut-e” — van-e bejegyzés a rendszer ütemezőjében, frissül-e a log-fájl dátuma —, mindenre igent mondtam volna. A job elindult, írt egy log-sort, be is fejeződött. Minden jel szerint élt.
Csakhogy amikor tényleg beleolvastam a log tartalmába, nem csak a dátumába, kiderült: 68 napja minden egyes futás ugyanazzal a hitelesítési hibával szállt el belül, csendben. Egy hozzáférési token lejárt, és a folyamat minden indításnál megpróbált bejelentkezni, elbukott, majd — mivel a hibakezelés nem volt elég szigorú — egyszerűen befejeződött, mintha rendben lett volna. A plist élt. A cron élt. A log-fájl mtime-ja friss volt. A tényleges munka viszont két hónapja nem történt meg.
Ez a hiba pontosan azért maradt rejtve ilyen sokáig, mert minden felszíni jel „egészségesnek” tűnt.
A szabály, amit ebből levontam
A job élő-voltát soha ne a rendszer-ütemező bejegyzéséből vagy a log-fájl dátumából állapítsd meg — állapítsd meg a log TARTALMÁBÓL. Ez a különbség egyszerűnek hangzik, de a gyakorlatban ez az egyetlen módszer, ami tényleg megkülönbözteti a „fut” és a „dolgozik” állapotot.
Konkrétan ez azt jelenti, hogy minden ütemezett folyamatnál két teljesen különböző kérdést teszek fel:
- Mikor indult el utoljára? — ezt bárki meg tudja mondani egy plist vagy cron bejegyzésből.
- Mikor volt utoljára ténylegesen sikeres, mérhető eredménye? — ez csak akkor derül ki, ha a folyamat maga is explicit módon jelzi: hány elemet dolgozott fel, hány hibát kapott, mikor volt az utolsó nem-nulla eredmény.
Ha a kettő között nagy a szakadék — a job „fut”, de hetek óta nincs valódi eredménye —, az a legveszélyesebb állapot, mert semmilyen egyszerű ellenőrzés nem fogja ki.
Az ellenpélda, ahol ez jól működik
Van egy másik, gyakran futó folyamatom, ami minden egyes indulásakor egy strukturált összefoglalót ír: hány feladatot próbált végrehajtani, hány sikerült, hány hibázott. Egy adott hét alatt ez a folyamat 141-szer futott le, ebből 104 sikerrel, 36 hibával, és egyszer megszakadt. Ez a szám elsőre ijesztőnek tűnhet — miért fut 36-szor hibára egy rendszer, ami állítólag jól működik?
A válasz: mert ez a szám látható. Nem az a cél, hogy nulla hiba legyen — az azt jelentené, hogy vagy tökéletes a rendszer (valószínűtlen), vagy nem mérsz semmit. A cél az, hogy a hiba azonnal, explicit módon megjelenjen, ne pedig csendben elsüllyedjen egy „sikeresnek” látszó log-sor mögött. Egy job, ami őszintén jelenti a 36 hibáját, megbízhatóbb, mint egy, ami sosem hibázik — mert az előbbiről tudod, hogy mér, az utóbbiról nem tudod, hogy csak nem vetted észre.
Nem egyedi eset
Ami igazán meggyőzött arról, hogy ez nem egyszeri baleset, hanem mintázat: ugyanabban az időszakban egy másik, teljesen független folyamatnál is előjött ugyanaz a tünet, más okból. Egy háttérfolyamat, ami helyi üzenetadatot próbált beolvasni, minden indításkor egy „nem sikerült megnyitni az adatbázis-fájlt” hibával futott le — de mivel a keretrendszer maga nem állt le, kívülről ez is „lefutott, majd befejeződött” állapotnak tűnt. Két különböző technikai ok (lejárt hitelesítés vs. lezárt fájl-hozzáférés), de ugyanaz a felszíni álca: a folyamat technikailag végigment, miközben belül semmi hasznosat nem ért el. Ez erősítette meg bennem, hogy a „csendes hiba” nem kivétel, hanem egy egész kategória, amire külön oda kell figyelni — nem elég egyszer kijavítani egy konkrét esetet, a detektálási mintát kell általánosan beépíteni.
Gyakorlati ellenőrzőlista halott jobok kiszűrésére
Ha most szeretnéd átnézni a saját ütemezett folyamataidat, három kérdést tegyél fel mindegyikre:
- Mikor volt az utolsó olyan futás, ami ténylegesen valamit csinált — nem csak elindult és lefutott, hanem mérhető eredményt hozott (feldolgozott elem, elküldött üzenet, frissített adat)? Ha ezt nem tudod megválaszolni a log alapján, az önmagában jelzés: a logod nem elég részletes.
- Van-e a folyamatnak explicit hiba-számlálója? Ha a hibakezelés csendben elnyeli a kivételt és „sikeresként” zárja a futást, a legrosszabb fajta hibát csináltad — olyat, ami soha nem fog magától felszínre kerülni.
- Van-e riasztás arra, ha X napig nincs valódi siker? Nem elég, hogy a folyamat fut — legyen egy külön mechanizmus, ami jelez, ha „fut, de hetek óta nem csinál semmit” állapotba kerül.
Egy jó gyakorlat, amit érdemes bevezetni: tarts egy egyszerű táblázatot minden ütemezett folyamatodról — mikor fut, mit csinál, hová ír naplót, mikor vetted fel, és mi a döntés mögötte. Nem kell bonyolult eszköz, egy jól karbantartott lista is elég. A lényeg, hogy amikor felmerül a kérdés „ez tényleg működik még?”, legyen hova nézned, ahol a válasz a tartalomból jön, nem a feltételezésből.
A tanulság, ami mindenre igaz
A csendben hibázó automatizáció nem technikai bug — megfigyelési hiba. Nem az volt a probléma, hogy a token lejárt (ez bárkivel megtörténik). A probléma az volt, hogy két hónapig senki nem vette észre, mert a mérés a rossz kérdésre válaszolt: „fut-e” ahelyett, hogy „dolgozik-e”. Minél több automatizációt bízol AI-ra, annál fontosabb, hogy ezt a különbséget explicit módon beépítsd — mert az AI maga nem fogja szólni, hogy „amúgy két hónapja nem csinálok semmit”. Miért is tenné, ha a log szerint minden rendben van.
Ha szeretnéd látni, hogyan néz ki egy konkrét, importálható napló-séma, ami ezt a különbséget rögtön megmutatja, nézz körül a Blueprint-ek között.