Structured Logging je přístup k zápisu logů, kde je každá zpráva prezentována ve strojem čitelném formátu s páry klíč-hodnota, místo nestrukturovaného textu. Na rozdíl od plochých řetězců obsahují strukturované logy metadata: timestamp, úroveň, modul, identifikátor požadavku — a mohou být indexovány analytickými systémy. Podle údajů O'Reilly Effective Logging, přechod na strukturované formáty zkracuje dobu hledání incidentu z hodin na minuty díky možnosti filtrování podle polí. Toto je de facto standard v moderním mobilním a serverovém vývoji: JSON a logfmt umožňují zpracovávat logy programy, nikoli očima.
Hlavní body
Structured Logging je metoda zápisu logů, při které každá zpráva obsahuje pojmenovaná pole s typovanými hodnotami. Místo řetězce jako User 42 logged in from device ABC vypadá strukturovaný log jako sada polí: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.
Hlavní výhoda strukturovaných logů oproti textovým — možnost programového zpracování. Parsování textových logů vyžaduje regulární výrazy a předpoklady o formátu řetězce. Strukturované logy se parsují beze ztrát: každé pole má známý typ a název, což umožňuje stavbu dotazů úrovně najdi všechny chyby autorizace za poslední hodinu pro uživatele 42 bez dalšího zpracování.
Podle údajů Honeycomb.io (2023), týmy používající structured logging v produkci detekují incidenty v průměru 4krát rychleji ve srovnání s týmy spoléhajícími se na textové logy a grep.
Structured Logging podporuje několik formátů serializace. Výběr formátu závisí na infrastruktuře: JSON je vhodný pro integraci s Elasticsearch a cloudovými systémy, logfmt — pro konzolové prohlížení přes tail a grep, Protocol Buffers — pro vysoce výkonné systémy s omezením šířky pásma.
| Formát | Příklad | Kdy použít |
|---|---|---|
| JSON | {"event":"login","user_id":42} | ELK Stack, cloudové sběrače, mikroslužby |
| Logfmt | event=login user_id=42 duration_ms=150 | Konzole, tail, heroku logs |
| MessagePack | Binární ekvivalent JSON | Vysoce zatížené systémy, IoT |
JSON je nejrozšířenější formát pro strukturované logy. Je nativně podporován všemi systémy sběru: Logstash, Fluentd, Amazon CloudWatch, Google Cloud Logging. JSON logy se snadno čtou člověkem a parsují se jakýmkoli programovacím jazykem bez dalších knihoven. Hlavní nevýhoda — redundance: každý pár klíč-hodnota vyžaduje uvozovky a dvojtečky, což zvyšuje objem ukládaných dat o 30–50 % oproti logfmt.
Logfmt byl vyvinut v Heroku pro konzolovou viditelnost. Je kompaktnější než JSON, zachovává čitelnost pro člověka a snadno se ořezává přes cut a awk. Příklad: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt nevyžaduje escapování většiny znaků a dobře se hodí pro stdout-logování v kontejnerech.
V mobilních aplikacích Structured Logging řeší tři klíčové úkoly: hledání příčin pádů bez reprodukce na zařízení, sledování uživatelských relací a analýzu výkonu podle verzí aplikace.
Textové logy na mobilních zařízeních jsou téměř k ničemu — vývojář nemůže grepovat logy na zařízení uživatele. Strukturované logy se odesílají do cloudových systémů (Firebase, Sentry, Datadog) a tam se indexují. Lze sestavit dotaz: zobraz všechny crash na iOS 17.4, verze aplikace 3.2, v modulu checkouts — a získat přesný výběr během několika sekund.
Podle údajů Sentry (2024), aplikace používající structured breadcrumbs mají o 60 % více kontextu v každém crash reportu ve srovnání s aplikacemi logujícími pouze text chyby. To přímo ovlivňuje rychlost opravy chyby.
ELK Stack — Elasticsearch, Logstash, Kibana — zůstává standardní infrastrukturou pro práci se strukturovanými logy. Logstash přijímá logy v JSON, transformuje je a odesílá do Elasticsearch k indexaci, Kibana poskytuje vizuální rozhraní pro dotazy a dashboardy.
Pro mobilní aplikace jsou populární cloudová řešení: Firebase Crashlytics s vlastními logy, Sentry s breadcrumbs, Datadog s APM sledováním. Přijímají strukturované logy přímo z mobilního SDK a nevyžadují nasazení vlastního backendu. Firebase poskytuje bezplatný balíček pro crash reporty, Sentry přidává distributed tracing a Datadog se integruje s APM pro současné sledování výkonu požadavků na klientovi a serveru.
Grafana Loki — alternativa k Elasticsearch, optimalizovaná pro logy. Loki standardně neindexuje obsah zpráv, ale používá štítky (labels) pro filtrování. To je výrazně levnější na úložiště a rychlejší při dotazech podle pevné sady polí.
// Strukturované logování přes Swift Logger do JSON
struct StructuredLog {
let event: String
let attributes: [String: Any]
let level: String
func serialize() -> String {
var base = "event=\(event) level=\(level)"
for (key, value) in attributes {
base += " \(key)=\(value)"
}
return base
}
}
První pravidlo strukturovaného logování: každá zpráva musí obsahovat identifikátor požadavku nebo relace. Bez kontextu je jednotlivý log k ničemu — nelze pochopit, ke kterému uživateli nebo požadavku patří. Přidávejte correlation ID na začátku relace a přenášejte ho přes všechny vrstvy aplikace.
Druhé pravidlo: typizace polí. Číselná pole (duration_ms, status_code, retry_count) musí být předávána jako čísla, nikoli jako řetězce. Elasticsearch a podobné systémy indexují čísla a řetězce odlišně: na čísla lze aplikovat agregace (průměr, medián, percentil), na řetězce — fulltextové vyhledávání. Falešná typizace znemožňuje stavbu analytických dashboardů.
Třetí pravidlo: vyhýbejte se vnořeným objektům. JSON logy s hloubkou vnoření větší než 2 úrovně se obtížně filtrují a vizualizují. Místo {"user": {"name": "Alice", "role": "admin"}} používejte ploché klíče: user_name=Alice user_role=admin.
// Strukturované logování na Androidu přes Timber + logfmt
class StructuredTree : Timber.Tree() {
override fun log(priority: Int, tag: String?,
message: String?, t: Throwable?) {
val level = priorityToLevel(priority)
val logfmt = "level=$level tag=$tag message=$message"
sendToRemote(logfmt)
}
}
Minimální sada polí pro každou strukturovanou zprávu: timestamp v ISO 8601, level (debug/info/warn/error/fatal), logger (název modulu nebo třídy), message (člověkem čitelný popis události). Doplňkově: correlation_id, user_id (je-li znám), version (verze aplikace), platform (iOS/Android), environment (dev/staging/prod).
Bez correlation_id se strukturované logy mění v soubor nesourodých záznamů, které nelze spojit do jednoho uživatelského scénáře. Generujte UUID při každém spuštění aplikace a přidávejte ho do všech logů relace. V praxi musí být correlation ID přenášen přes všechny vrstvy: od UI událostí po síťové požadavky a úkoly na pozadí — jinak část logů zůstane bez kontextu a nebude se účastnit analýzy. Při end-to-end sledování umožňuje jeden UUID shromáždit úplný obrázek uživatelské cesty.
Na iOS lze strukturované logování implementovat přes obálku nad os_log, která serializuje pole do formátu logfmt. Na Android — přes Timber s vlastním Tree, který převádí zprávy do JSON nebo logfmt před odesláním na server.
import OSLog
struct StructuredLogger {
let subsystem: String
let category: String
func log(level: OSLogType,
event: String,
context: [String: Any]) {
let oslogger = Logger(
subsystem: subsystem,
category: category
)
let fields = context.map {
"\($0.key)=\($0.value)"
}.joined(separator: " ")
oslogger.log(level: level,
"\(event) \(fields)")
}
}
Výběr mezi strukturovanými a textovými logy závisí na fázi projektu. V raných fázích vývoje jsou textové logy jednodušší a rychlejší — vývojář píše zprávu přímo bez dalších obálek. Jakmile ale projekt překročí hranice jednoho týmu nebo jednoho serveru, strukturované logy se stávají povinnými.
| Kritérium | Textové logy | Strukturované logy |
|---|---|---|
| Čitelnost | Vysoká v konzoli | Střední (vyžaduje pretty-print) |
| Vyhledávání | grep podle podřetězce | Dotazy podle polí a hodnot |
| Agregace | Není podporována | Průměr, medián, percentily |
| Integrace | Vyžaduje parsování | Nativní v ELK/Loki/Datadog |
| Objem úložiště | Menší (bez metadat) | Větší (pole + hodnoty) |
Často kladené otázky
Pro odesílání na server používejte JSON — je nativně podporován Firebase Crashlytics, Sentry a Datadog. Pro lokální prohlížení v logech Xcode nebo Android Studio používejte logfmt — je kompaktnější a čitelný bez formátování.
Ano, strukturované logy na klientovi umožňují přidat kontext ke každému crash reportu: verze OS, stav sítě, poslední akce uživatele. Bez strukturovaných breadcrumbs obsahuje crash report pouze zásobník volání bez uživatelského scénáře.
Logfmt je kompaktnější (o 30–50 % menší objem) a snadněji se čte v terminálu. JSON podporuje vnořené objekty a pole, ale vyžaduje escapování uvozovek. Výběr závisí na infrastruktuře: pro ELK — JSON, pro konzolové prohlížení — logfmt.
Vytvořte jednu instanci UUID při spuštění aplikace, uložte ji do singletonu nebo DI kontejneru a přenášejte ji do všech loggerů přes konstruktor. Alternativa — použít threading-local nebo Continuation Local Storage v Kotlin korutinách.
Lze, ale nedoporučuje se — při míchání se ztrácí možnost automatické indexace. Pokud jsou některé logy textové, je nutné je parsovat regulárními výrazy, což snižuje výkon a spolehlivost vyhledávání. Lepší je migrovat všechny logy na strukturovaný formát.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také