TakéLogy, Aplikační logy, Log, Záznam událostíPokročilý
Definice
Logování je průběžné zapisování událostí, které v běžícím programu nastaly, do textového nebo strukturovaného záznamu. Každý zápis obsahuje čas, závažnost a popis události, případně kontext jako identifikátor požadavku. Logy slouží k vyšetřování chyb, sledování provozu a auditu, protože jsou často jedinou stopou po tom, co se v produkci skutečně stalo.
Co log vlastně zaznamenává
Log je posloupnost záznamů seřazených podle času. Minimální užitečný záznam obsahuje časové razítko, úroveň závažnosti, jméno komponenty a zprávu. Bez těchto čtyř položek se v souboru s miliony řádků nedá hledat. Praxe přidává korelační identifikátor požadavku, díky kterému lze poskládat cestu jednoho volání napříč několika službami.
Zásadní rozdíl je mezi textovým a strukturovaným logem. Textový řádek je čitelný pro člověka, ale strojově se z něj špatně filtruje. Strukturovaný log (typicky JSON) má pojmenovaná pole, takže se dá dotazovat jako databáze: „všechny záznamy s úrovní error a status 500 za poslední hodinu“.
Úrovně závažnosti a proč se nastavují
Úrovně tvoří žebříček, obvykle TRACE, DEBUG, INFO, WARN, ERROR a FATAL. Aplikace se konfiguruje prahem: na produkci se často zapisuje od INFO výš, při ladění konkrétního problému se práh dočasně sníží na DEBUG. Smyslem je poměr signálu k šumu. Když je všechno ERROR, nic není ERROR a tým přestane na výstrahy reagovat.
Volba úrovně je rozhodnutí o tom, kdo má záznam číst. WARN znamená „něco není v pořádku, ale systém pokračuje“, ERROR znamená „tenhle požadavek selhal a někdo se na to má podívat“.
Cena logování v provozu
Logování není zadarmo. Každý zápis stojí čas procesoru, zápis na disk nebo do sítě, a hlavně místo v úložišti. U vysoce zatížených služeb se proto používá asynchronní zápis do bufferu, vzorkování opakujících se událostí a rotace souborů s dobou uchování. Synchronní zápis na pomalý disk uvnitř horké smyčky dokáže zpomalit celou aplikaci víc než samotná obsluha požadavku.
V distribuovaném prostředí se logy nesbírají ze strojů ručně. Kontejner zapisuje na standardní výstup a sběrný agent je posílá do centrálního úložiště, kde se indexují a hledají. Tento model je výchozí například v Kubernetes.
Co do logu nikdy nepatří
Logy bývají čitelné pro širší okruh lidí než produkční databáze a často odtékají do služeb třetích stran. Hesla, čísla platebních karet, obsah tokenů a rodná čísla proto do záznamů nepatří. Osobní údaje v logu spadají pod GDPR včetně povinnosti je po uplynutí doby uchování smazat, což se u rozkopírovaných logů dělá obtížně. Bezpečné je citlivé hodnoty maskovat už v okamžiku zápisu, ne až při analýze.
Logy, metriky a trasování
Logy odpovídají na otázku „co se stalo v tomhle konkrétním případě“. Metriky odpovídají „kolik toho bylo“ a trasování „kudy požadavek prošel a kde strávil čas“. Tři pohledy se doplňují: alert obvykle vznikne z metriky, příčinu odhalí trasování a přesný detail dodá log.
Příklady z praxe
Strukturovaný záznam s korelačním ID
Webová služba zapisuje každý neúspěšný požadavek jako jeden řádek JSON. Pole requestId se propaguje HTTP hlavičkou do navazujících služeb, takže po incidentu lze v centrálním úložišti vyfiltrovat celou cestu jednoho volání. Bez tohoto pole by se záznamy z pěti služeb daly spojit jen podle času, což při stovkách požadavků za sekundu nefunguje.
{ "ts": "2024-03-11T09:14:22.318Z", "level": "error", "service": "checkout", "requestId": "b31f9c2a", "userId": 8421, "msg": "payment authorization failed", "gatewayCode": "insufficient_funds", "durationMs": 742 }Maskování citlivého pole při zápisu
Tým zjistil, že se do logu dostávalo celé tělo požadavku včetně hesla. Řešením nebylo logování vypnout, ale doplnit do loggeru seznam polí, která se před zápisem nahradí zástupným textem. Kontext o tom, jaká pole požadavek obsahoval, zůstal zachovaný, hodnoty už se ale nikam neuloží.
const REDACT = new Set(['password', 'cardNumber', 'authorization']); function safeBody(body) { return Object.fromEntries( Object.entries(body).map(([k, v]) => [k, REDACT.has(k) ? '[redacted]' : v]) ); } logger.info({ requestId, body: safeBody(req.body) }, 'incoming request');
Časté omyly
- MýtusLogovat se má radši všechno, ať to pak máme.
- Ve skutečnostiNadměrné logování zdražuje úložiště, zpomaluje aplikaci a hlavně skrývá důležité záznamy v šumu. Užitečnější je logovat méně událostí, ale s bohatým kontextem a konzistentní strukturou.
- MýtusNa logy stačí printf nebo console.log.
- Ve skutečnostiPřímý výpis nemá úroveň závažnosti, časové razítko ani strukturu, takže se nedá filtrovat ani centrálně sbírat. Knihovna pro logování navíc řeší asynchronní zápis a maskování citlivých polí.
- MýtusLogy jsou interní technická data, GDPR se jich netýká.
- Ve skutečnostiJakmile záznam obsahuje IP adresu, e-mail nebo identifikátor uživatele, jde o osobní údaj se vším, co k tomu patří: právním základem, dobou uchování a povinností smazání.
Časté dotazy
- Jak dlouho se mají logy uchovávat?
- Doba uchování logů se odvozuje od účelu. Pro běžné ladění provozu stačí dny až týdny, protože starší záznamy už nikdo neotevře. Bezpečnostní a auditní logy se typicky drží měsíce až roky, někdy podle regulace daného oboru. Pokud záznamy obsahují osobní údaje, musí být doba uchování stanovená předem a po jejím uplynutí se data skutečně mažou. Praktické řešení je oddělit krátkodobé provozní logy od dlouhodobého auditního záznamu a nastavit jim různé retenční politiky, aby cena za úložiště nerostla bez užitku.
- Jaký je rozdíl mezi logováním a monitoringem?
- Logování zapisuje jednotlivé události s plným kontextem, monitoring sleduje agregované hodnoty v čase, jako je počet chyb za minutu nebo doba odezvy. Monitoring odhalí, že se něco děje, a spustí výstrahu. Log pak dodá konkrétní detail, který vysvětlí proč. V praxi se obojí staví nad stejnými daty: z logů se dají odvozovat metriky a naopak z metriky se prokliknete na související záznamy. Nasazovat jedno bez druhého vede buď k slepému provozu, nebo k horám dat, které nikdo nečte.
- Kdy je vhodné použít strukturované logování místo textového?
- Strukturované logování se vyplatí ve chvíli, kdy záznamy čte stroj, ne člověk. To znamená prakticky vždy, když aplikace běží ve více instancích a logy se sbírají centrálně, protože filtrovat podle pojmenovaných polí je nesrovnatelně spolehlivější než regulární výrazy nad volným textem. Textový formát dává smysl při lokálním vývoji, kde je čitelnost v terminálu důležitější než dotazovatelnost. Většina knihoven umí obojí: strukturovaný JSON na produkci a barevný čitelný výstup lokálně, aniž by se měnil kód aplikace.
- Může logování zpomalit aplikaci?
- Logování zpomalit aplikaci může, a v praxi to není vzácné. Synchronní zápis na disk nebo do sítě blokuje vlákno, které obsluhuje požadavek, a při vysoké zátěži se stane úzkým hrdlem. Rizikové je také skládání zpráv a serializace velkých objektů, které proběhne i tehdy, když se záznam kvůli nastavenému prahu nakonec nezapíše. Řešením je asynchronní zápis přes buffer, kontrola úrovně před sestavením zprávy, vzorkování opakujících se událostí a vyhnutí se logování uvnitř horkých smyček.
Zdroje
- logging: Logging facility for Python(otevře se v novém okně)
- RFC 5424: The Syslog Protocol(otevře se v novém okně)
- Logging Architecture(otevře se v novém okně)
- OWASP Cheat Sheet Series: Logging(otevře se v novém okně)