Structured Logging is een benadering voor het loggen waarbij elk bericht wordt gepresenteerd in een machineleesbaar formaat met sleutel-waardeparen, in plaats van ongestructureerde tekst. In tegenstelling tot platte strings bevatten gestructureerde logs metadata: timestamp, niveau, module, verzoek-ID — en kunnen worden geïndexeerd door analysesystemen. Volgens O'Reilly Effective Logging verkort de overgang naar gestructureerde formaten de tijd om een incident te vinden van uren naar minuten dankzij de mogelijkheid om op velden te filteren. Dit is de de facto standaard in moderne mobiele en serverontwikkeling: JSON en logfmt maken het mogelijk logs te verwerken met programma's in plaats van met het oog.
Belangrijkste
Structured Logging is een methode voor het loggen waarbij elk bericht benoemde velden bevat met getypeerde waarden. In plaats van een string zoals User 42 logged in from device ABC ziet een gestructureerde log eruit als een set velden: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.
Het belangrijkste voordeel van gestructureerde logs ten opzichte van tekstlogs is de mogelijkheid van programmatische verwerking. Het parsen van tekstlogs vereist reguliere expressies en aannames over het stringformaat. Gestructureerde logs worden verliesloos geparsed: elk veld heeft een bekend type en naam, waardoor queries van het type vind alle autorisatiefouten van het laatste uur voor gebruiker 42 kunnen worden gebouwd zonder extra verwerking.
Volgens Honeycomb.io (2023) detecteren teams die structured logging in productie gebruiken incidenten gemiddeld 4 keer sneller in vergelijking met teams die vertrouwen op tekstlogs en grep.
Structured Logging ondersteunt meerdere serialisatieformaten. De keuze van formaat hangt af van de infrastructuur: JSON is handig voor integratie met Elasticsearch en cloudsystemen, logfmt — voor consoleweergave via tail en grep, Protocol Buffers — voor hoogwaardige systemen met bandbreedtebeperkingen.
| Formaat | Voorbeeld | Wanneer gebruiken |
|---|---|---|
| JSON | {"event":"login","user_id":42} | ELK Stack, cloud verzamelaars, microservices |
| Logfmt | event=login user_id=42 duration_ms=150 | Console, tail, heroku logs |
| MessagePack | Binair equivalent van JSON | Hoogbelaste systemen, IoT |
JSON is het meest voorkomende formaat voor gestructureerde logs. Het wordt natively ondersteund door alle verzamelsystemen: Logstash, Fluentd, Amazon CloudWatch, Google Cloud Logging. JSON-logs zijn gemakkelijk leesbaar voor mensen en worden geparsed door elke programmeertaal zonder extra bibliotheken. Het belangrijkste nadeel — redundantie: elk sleutel-waardepaar vereist aanhalingstekens en dubbele punten, wat de opslagruimte met 30–50% verhoogt in vergelijking met logfmt.
Logfmt is ontwikkeld bij Heroku voor consolezichtbaarheid. Het is compacter dan JSON, behoudt menselijke leesbaarheid en kan gemakkelijk worden afgeknipt met cut en awk. Voorbeeld: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt vereist geen escaping van de meeste tekens en is goed geschikt voor stdout-logging in containers.
In mobiele applicaties lost Structured Logging drie belangrijke taken op: het vinden van crashoorzaken zonder reproductie op het apparaat, het volgen van gebruikerssessies en het analyseren van prestaties per applicatieversie.
Tekstlogs op mobiele apparaten zijn bijna nutteloos — de ontwikkelaar kan geen grep uitvoeren op logs op het apparaat van de gebruiker. Gestructureerde logs worden naar cloudsystemen (Firebase, Sentry, Datadog) gestuurd en daar geïndexeerd. Er kan een query worden gebouwd: toon alle crashes op iOS 17.4, app-versie 3.2, in de module checkouts — en binnen enkele seconden een exacte selectie krijgen.
Volgens Sentry (2024) hebben applicaties die structured breadcrumbs gebruiken 60% meer context in elk crashrapport in vergelijking met applicaties die alleen de fouttekst loggen. Dit heeft direct invloed op de snelheid van bugfixes.
ELK Stack — Elasticsearch, Logstash, Kibana — blijft de standaardinfrastructuur voor het werken met gestructureerde logs. Logstash ontvangt logs in JSON, transformeert en stuurt ze naar Elasticsearch voor indexering, Kibana biedt een visuele interface voor queries en dashboards.
Voor mobiele applicaties zijn cloudoplossingen populair: Firebase Crashlytics met aangepaste logs, Sentry met breadcrumbs, Datadog met APM-tracking. Ze ontvangen gestructureerde logs direct van de mobiele SDK en vereisen geen implementatie van een eigen backend. Firebase biedt een gratis pakket voor crashrapportage, Sentry voegt distributed tracing toe en Datadog integreert met APM voor gelijktijdige prestatiebewaking van verzoeken op client en server.
Grafana Loki — een alternatief voor Elasticsearch, geoptimaliseerd voor logs. Loki indexeert standaard niet de inhoud van berichten, maar gebruikt labels voor filtering. Dit is aanzienlijk goedkoper in opslag en sneller bij queries op een vaste set velden.
// Structured logging via Swift Logger naar 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
}
}
De eerste regel van gestructureerd loggen: elk bericht moet een verzoek- of sessie-ID bevatten. Zonder context is een enkele log nutteloos — het is onmogelijk te begrijpen bij welke gebruiker of welk verzoek het hoort. Voeg een correlation ID toe aan het begin van de sessie en geef het door alle lagen van de applicatie.
De tweede regel: typering van velden. Numerieke velden (duration_ms, status_code, retry_count) moeten als getallen worden doorgegeven, niet als strings. Elasticsearch en vergelijkbare systemen indexeren getallen en strings verschillend: op getallen kunnen aggregaties worden toegepast (gemiddelde, mediaan, percentiel), op strings — full-text zoeken. Verkeerde typering maakt het onmogelijk om analytische dashboards te bouwen.
De derde regel: vermijd geneste objecten. JSON-logs met een nestdiepte van meer dan 2 niveaus zijn moeilijk te filteren en visualiseren. Gebruik in plaats van {"user": {"name": "Alice", "role": "admin"}} platte sleutels: user_name=Alice user_role=admin.
// Structured logging op Android via 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)
}
}
Minimale set velden voor elk gestructureerd bericht: timestamp in ISO 8601, level (debug/info/warn/error/fatal), logger (naam van module of klasse), message (mensleesbare beschrijving van de gebeurtenis). Aanvullend: correlation_id, user_id (indien bekend), version (app-versie), platform (iOS/Android), environment (dev/staging/prod).
Zonder correlation_id worden gestructureerde logs een verzameling losstaande records die niet kunnen worden verbonden in énén gebruikersscenario. Genereer een UUID bij elke start van de applicatie en voeg het toe aan alle sessielogs. In de praktijk moet correlation_id door alle lagen worden doorgegeven: van UI-gebeurtenissen tot netwerkverzoeken en achtergrondtaken — anders blijft een deel van de logs zonder context en neemt niet deel aan de analyse. Bij end-to-end tracking maakt één UUID het mogelijk een compleet beeld van het gebruikerspad te verzamelen.
Op iOS kan gestructureerd loggen worden geïmplementeerd via een wrapper rond os_log die velden serialiseert naar logfmt-formaat. Op Android — via Timber met een aangepaste Tree die berichten omzet naar JSON of logfmt voordat ze naar de server worden gestuurd.
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)")
}
}
De keuze tussen gestructureerde en tekstlogs hangt af van de projectfase. In vroege ontwikkelingsfasen zijn tekstlogs eenvoudiger en sneller — de ontwikkelaar schrijft het bericht direct zonder extra wrappers. Maar zodra het project de grenzen van één team of één server overschrijdt, worden gestructureerde logs verplicht.
| Criterium | Tekstlogs | Gestructureerde logs |
|---|---|---|
| Leesbaarheid | Hoog in console | Gemiddeld (vereist pretty-print) |
| Zoeken | grep op substring | Queries op velden en waarden |
| Aggregatie | Niet ondersteund | Gemiddelde, mediaan, percentielen |
| Integratie | Vereist parsing | Native in ELK/Loki/Datadog |
| Opslagvolume | Minder (zonder metadata) | Meer (velden + waarden) |
Veelgestelde vragen
Gebruik voor verzending naar de server JSON — het wordt natively ondersteund door Firebase Crashlytics, Sentry en Datadog. Gebruik voor lokale weergave in Xcode of Android Studio logs logfmt — het is compacter en leesbaar zonder formattering.
Ja, gestructureerde logs op de client maken het mogelijk context toe te voegen aan elk crashrapport: OS-versie, netwerkstatus, laatste acties van de gebruiker. Zonder gestructureerde breadcrumbs bevat het crashrapport alleen de call stack zonder gebruikersscenario.
Logfmt is compacter (30–50% minder volume) en gemakkelijker te lezen in de terminal. JSON ondersteunt geneste objecten en arrays, maar vereist escaping van aanhalingstekens. De keuze hangt af van de infrastructuur: voor ELK — JSON, voor consoleweergave — logfmt.
Maak één instantie van UUID aan bij het starten van de applicatie, sla deze op in een singleton of DI-container en geef deze door aan alle loggers via de constructor. Alternatief — gebruik van threading-local of Continuation Local Storage in Kotlin coroutines.
Het kan, maar wordt niet aanbevolen — mengen verliest de mogelijkheid van automatische indexering. Als een deel van de logs tekst is, moeten ze worden geparsed met reguliere expressies, wat de prestaties en betrouwbaarheid van zoeken vermindert. Het is beter om alle logs te migreren naar gestructureerd formaat.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook