Structured Logging — esența, formatele de date și principiul de funcționare în aplicații

Autor: IT Sectr Publicat: 2026-05-28 Timp de citire: 8 min

Structured Logging este o abordare de înregistrare a logurilor în care fiecare mesaj este prezentat într-un format citibil de mașină cu perechi cheie-valoare, nu ca text nestructurat. Spre deosebire de șirurile plate, logurile structurate conțin metadate: timestamp, nivel, modul, identificatorul cererii — și pot fi indexate de sistemele de analiză. Conform datelor O'Reilly Effective Logging, trecerea la formatele structurate reduce timpul de găsire a unui incident de la ore la minute datorită posibilității de filtrare după câmpuri. Acesta este standardul de facto în dezvoltarea modernă mobilă și server: JSON și logfmt permit procesarea logurilor cu programe, nu cu ochiul.

Principalele

  • Structured Logging — reprezentarea logurilor în format cheie-valoare în loc de text plat, potrivit pentru procesare automată
  • JSON — cel mai răspândit format de loguri structurate, acceptat de toate sistemele moderne de colectare și analiză
  • Logfmt — format compact de la Heroku, convenabil pentru citirea umană și parsare prin grep
  • ELK Stack — Elasticsearch, Logstash, Kibana — infrastructura standard pentru stocarea și vizualizarea logurilor structurate
  • Context — identificatorul cererii, sesiunea utilizatorului, versiunea aplicației — câmpuri obligatorii ale fiecărui mesaj structurat

Ce este Structured Logging

Structured Logging este o metodă de înregistrare a logurilor în care fiecare mesaj conține câmpuri denumite cu valori tipizate. În locul unui șir precum User 42 logged in from device ABC, un log structurat arată ca un set de câmpuri: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.

Principalul avantaj al logurilor structurate față de cele text este posibilitatea procesării programatice. Parsarea logurilor text necesită expresii regulate și presupuneri despre formatul șirului. Logurile structurate se parsează fără pierderi: fiecare câmp are un tip și un nume cunoscut, ceea ce permite construirea de interogări de tipul găsește toate erorile de autorizare din ultima oră pentru utilizatorul 42 fără procesare suplimentară.

Conform datelor Honeycomb.io (2023), echipele care folosesc structured logging în producție detectează incidente în medie de 4 ori mai rapid comparativ cu echipele care se bazează pe loguri text și grep.

Formatele logurilor structurate

Structured Logging suportă mai multe formate de serializare. Alegerea formatului depinde de infrastructură: JSON este convenabil pentru integrarea cu Elasticsearch și sistemele cloud, logfmt — pentru vizualizarea în consolă prin tail și grep, Protocol Buffers — pentru sisteme de înaltă performanță cu limitări de bandă.

FormatExempluCând se utilizează
JSON{"event":"login","user_id":42}ELK Stack, colectoare cloud, microservicii
Logfmtevent=login user_id=42 duration_ms=150Consolă, tail, heroku logs
MessagePackEchivalent binar JSONSisteme cu încărcare mare, IoT

JSON — format universal

JSON este cel mai răspândit format pentru loguri structurate. Este suportat nativ de toate sistemele de colectare: Logstash, Fluentd, Amazon CloudWatch, Google Cloud Logging. Logurile JSON sunt ușor de citit de om și parsat de orice limbaj de programare fără biblioteci suplimentare. Principalul dezavantaj — redundanța: fiecare pereche cheie-valoare necesită ghilimele și două puncte, ceea ce crește volumul datelor stocate cu 30–50% comparativ cu logfmt.

Logfmt — format compact

Logfmt a fost dezvoltat la Heroku pentru vizibilitate în consolă. Este mai compact decât JSON, păstrează lizibilitatea umană și se trunchiază ușor cu cut și awk. Exemplu: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt nu necesită escaparea majorității caracterelor și este potrivit pentru logarea stdout în containere.

De ce este nevoie de Structured Logging în dezvoltarea mobilă

În aplicațiile mobile Structured Logging rezolvă trei sarcini cheie: găsirea cauzelor crash-urilor fără reproducere pe dispozitiv, urmărirea sesiunilor utilizatorilor și analiza performanței pe versiuni ale aplicației.

Logurile text pe dispozitivele mobile sunt aproape inutile — dezvoltatorul nu poate grep-ui loguri pe dispozitivul utilizatorului. Logurile structurate sunt trimise în sistemele cloud (Firebase, Sentry, Datadog) și acolo sunt indexate. Se poate construi o interogare: arată toate crash-urile pe iOS 17.4, versiunea aplicației 3.2, în modulul checkouts — și se obține o selecție exactă în câteva secunde.

Conform datelor Sentry (2024), aplicațiile care folosesc structured breadcrumbs au cu 60% mai mult context în fiecare raport de crash comparativ cu aplicațiile care loghează doar textul erorii. Acest lucru influențează direct viteza de remediere a bug-ului.

Unelte de colectare și analiză

ELK Stack — Elasticsearch, Logstash, Kibana — rămâne infrastructura standard pentru lucrul cu loguri structurate. Logstash primește logurile în JSON, le transformă și le trimite în Elasticsearch pentru indexare, Kibana oferă interfață vizuală pentru interogări și dashboard-uri.

Pentru aplicații mobile sunt populare soluțiile cloud: Firebase Crashlytics cu loguri personalizate, Sentry cu breadcrumbs, Datadog cu urmărire APM. Acestea primesc loguri structurate direct din SDK-ul mobil și nu necesită implementarea unui backend propriu. Firebase oferă un pachet gratuit pentru raportarea crash-urilor, Sentry adaugă distributed tracing, iar Datadog se integrează cu APM pentru urmărirea performanței cererilor pe client și server simultan.

Grafana Loki — alternativă la Elasticsearch, optimizată pentru loguri. Loki nu indexează conținutul mesajelor implicit, ci folosește etichete (labels) pentru filtrare. Acest lucru este semnificativ mai ieftin la stocare și mai rapid la interogări după un set fix de câmpuri.

swift
// Structured logging prin Swift Logger în 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
    }
}

Cele mai bune practici Structured Logging

Prima regulă a logării structurate: fiecare mesaj trebuie să conțină un identificator al cererii sau al sesiunii. Fără context, un singur log este inutil — nu se poate înțelege la ce utilizator sau cerere se referă. Adăugați correlation ID la începutul sesiunii și transmiteți-l prin toate straturile aplicației.

A doua regulă: tipizarea câmpurilor. Câmpurile numerice (duration_ms, status_code, retry_count) trebuie transmise ca numere, nu ca șiruri. Elasticsearch și sistemele similare indexează numerele și șirurile diferit: numerelor li se pot aplica agregări (medie, mediană, percentilă), șirurilor — căutare full-text. Tipizarea falsă elimină posibilitatea de a construi dashboard-uri analitice.

A treia regulă: evitați obiectele imbricate. Logurile JSON cu adâncimea de imbricare mai mare de 2 niveluri sunt dificil de filtrat și vizualizat. În loc de {"user": {"name": "Alice", "role": "admin"}} folosiți chei plate: user_name=Alice user_role=admin.

kotlin
// Structured logging pe Android prin 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)
    }
}

Ce câmpuri sunt obligatorii

Setul minim de câmpuri pentru fiecare mesaj structurat: timestamp în ISO 8601, level (debug/info/warn/error/fatal), logger (numele modulului sau clasei), message (descrierea evenimentului citibilă pentru om). Suplimentar: correlation_id, user_id (dacă este cunoscut), version (versiunea aplicației), platform (iOS/Android), environment (dev/staging/prod).

Fără correlation_id logurile structurate se transformă într-un set de înregistrări disparate care nu pot fi conectate într-un singur scenariu de utilizator. Generați un UUID la fiecare pornire a aplicației și adăugați-l în toate logurile sesiunii. În practică, correlation_id trebuie transmis prin toate straturile: de la evenimentele UI până la cererile de rețea și sarcinile de fundal — altfel o parte din loguri rămân fără context și nu vor participa în analitică. În urmărirea end-to-end, un singur UUID permite colectarea imaginii complete a parcursului utilizatorului.

Exemple de logare structurată în Swift și Kotlin

Pe iOS logarea structurată poate fi implementată printr-un wrapper peste os_log care serializă câmpurile în format logfmt. Pe Android — prin Timber cu un Tree personalizat care transformă mesajele în JSON sau logfmt înainte de trimiterea pe server.

swift
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)")
    }
}

Structured vs Unstructured: compararea abordărilor

Alegerea între logurile structurate și cele text depinde de etapa proiectului. În etapele incipiente de dezvoltare, logurile text sunt mai simple și mai rapide — dezvoltatorul scrie mesajul direct, fără wrapper-e suplimentare. Dar de îndată ce proiectul depășește limitele unei echipe sau ale unui server, logurile structurate devin obligatorii.

CriteriuLoguri textLoguri structurate
LizibilitateRidicată în consolăMedie (necesită pretty-print)
Căutaregrep după subșirInterogări după câmpuri și valori
AgregareNu este suportatăMedie, mediană, percentile
IntegrareNecesită parsareNativă în ELK/Loki/Datadog
Volum de stocareMai mic (fără metadate)Mai mare (câmpuri + valori)

Întrebări frecvente

Care format este mai bun pentru logarea mobilă?

Pentru trimiterea pe server folosiți JSON — este suportat nativ de Firebase Crashlytics, Sentry și Datadog. Pentru vizualizarea locală în logurile Xcode sau Android Studio folosiți logfmt — este mai compact și se citește fără formatare.

Trebuie să logăm în format structurat pe client?

Da, logurile structurate pe client permit adăugarea de context la fiecare raport de crash: versiunea OS, starea rețelei, ultimele acțiuni ale utilizatorului. Fără breadcrumbs structurate, raportul de crash conține doar stiva de apeluri fără scenariul utilizatorului.

Cu ce diferă logfmt de JSON?

Logfmt este mai compact (volum cu 30–50% mai mic) și se citește mai ușor în terminal. JSON suportă obiecte imbricate și matrice, dar necesită escaparea ghilimelelor. Alegerea depinde de infrastructură: pentru ELK — JSON, pentru vizualizare în consolă — logfmt.

Cum să adăugăm correlation ID în toate logurile?

Creați o singură instanță UUID la pornirea aplicației, salvați-o într-un singleton sau container DI și transmiteți-o tuturor logger-elor prin constructor. Alternativa — utilizarea threading-local sau Continuation Local Storage în corutinele Kotlin.

Se pot amesteca logurile structurate și text?

Se poate, dar nu este recomandat — amestecarea pierde posibilitatea de indexare automată. Dacă o parte din loguri sunt text, ele trebuie parsat cu expresii regulate, ceea ce reduce performanța și fiabilitatea căutării. Mai bine să migrați toate logurile la format structurat.

Rezumat

  • Structured Logging — format de loguri cu perechi cheie-valoare, potrivit pentru indexare automată și interogări, spre deosebire de șirurile text
  • JSON și logfmt — formatele principale: JSON universal pentru sistemele de colectare, logfmt compact pentru vizualizare în consolă și loguri docker
  • Correlation ID — câmp obligatoriu al fiecărui mesaj structurat, fără el logurile nu pot fi conectate într-o sesiune de utilizator
  • ELK Stack și Grafana Loki — soluții infrastructurale standard pentru stocarea, indexarea și vizualizarea logurilor structurate
  • Performanță — echipele cu structured logging detectează incidente de 4 ori mai rapid datorită interogărilor după câmpuri în loc de grep după text
  • Tipizare — numerele trebuie transmise ca numere, nu ca șiruri, pentru a permite agregări (medie, mediană, percentile) în sistemele de analitică

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și