Structured Logging — essenza, formati di dati e principio di funzionamento nelle applicazioni

Autore: IT Sectr Pubblicato: 2026-05-28 Tempo di lettura: 8 min

Structured Logging è un approccio alla registrazione dei log in cui ogni messaggio è rappresentato in un formato leggibile dalla macchina con coppie chiave-valore, anziché come testo non strutturato. A differenza delle stringhe piatte, i log strutturati contengono metadati: timestamp, livello, modulo, ID richiesta — e possono essere indicizzati da sistemi di analisi. Secondo O'Reilly Effective Logging, il passaggio a formati strutturati riduce i tempi di ricerca degli incidenti da ore a minuti grazie alla possibilità di filtrare per campi. Questo è lo standard de facto nello sviluppo mobile e server moderno: JSON e logfmt consentono di elaborare i log con programmi, non con gli occhi.

Punti chiave

  • Structured Logging — rappresentazione dei log in formato chiave-valore invece di testo semplice, adatto per l’elaborazione automatica
  • JSON — il formato di log strutturati più comune, supportato da tutti i moderni sistemi di raccolta e analisi
  • Logfmt — un formato compatto di Heroku, comodo per la lettura umana e l’analisi con grep
  • ELK Stack — Elasticsearch, Logstash, Kibana — l’infrastruttura standard per memorizzare e visualizzare log strutturati
  • Contesto — ID richiesta, sessione utente, versione dell’app — campi obbligatori di ogni messaggio strutturato

Cos’è Structured Logging

Structured Logging è un metodo di registrazione dei log in cui ogni messaggio contiene campi nominati con valori tipizzati. Invece di una stringa come User 42 logged in from device ABC, un log strutturato appare come un insieme di campi: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.

Il vantaggio principale dei log strutturati rispetto a quelli testuali è la possibilità di elaborazione programmatica. L’analisi dei log testuali richiede espressioni regolari e ipotesi sul formato della stringa. I log strutturati vengono analizzati senza perdite: ogni campo ha un tipo e un nome noti, consentendo di costruire query come trovare tutti gli errori di autenticazione nell’ultima ora per l’utente 42 senza elaborazione aggiuntiva.

Secondo Honeycomb.io (2023), i team che utilizzano structured logging in produzione rilevano gli incidenti in media 4 volte più velocemente rispetto ai team che si affidano a log testuali e grep.

Formati dei log strutturati

Structured Logging supporta diversi formati di serializzazione. La scelta del formato dipende dall’infrastruttura: JSON è comodo per l’integrazione con Elasticsearch e sistemi cloud, logfmt per la visualizzazione in console tramite tail e grep, Protocol Buffers per sistemi ad alte prestazioni con limiti di larghezza di banda.

FormatoEsempioQuando usarlo
JSON{"event":"login","user_id":42}ELK Stack, raccoglitori cloud, microservizi
Logfmtevent=login user_id=42 duration_ms=150Console, tail, heroku logs
MessagePackEquivalente binario di JSONSistemi ad alto carico, IoT

JSON — formato universale

JSON è il formato più comune per i log strutturati. È nativamente supportato da tutti i sistemi di raccolta: Logstash, Fluentd, Amazon CloudWatch, Google Cloud Logging. I log JSON sono facili da leggere per gli umani e da analizzare con qualsiasi linguaggio di programmazione senza librerie aggiuntive. Lo svantaggio principale è la verbosità: ogni coppia chiave-valore richiede virgolette e due punti, aumentando il volume dei dati memorizzati del 30–50% rispetto a logfmt.

Logfmt — formato compatto

Logfmt è stato sviluppato in Heroku per la visibilità in console. È più compatto di JSON, mantiene la leggibilità umana e può essere facilmente elaborato con cut e awk. Esempio: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt non richiede l’escape della maggior parte dei caratteri ed è adatto per il logging su stdout nei container.

Perché Structured Logging nello sviluppo mobile

Nelle applicazioni mobili, Structured Logging risolve tre problemi chiave: trovare le cause dei crash senza riproduzione sul dispositivo, tracciare le sessioni utente e analizzare le prestazioni per versione dell’app.

I log testuali sui dispositivi mobili sono quasi inutili — uno sviluppatore non può fare grep sui log del dispositivo dell’utente. I log strutturati vengono inviati a sistemi cloud (Firebase, Sentry, Datadog) e lì indicizzati. Si può costruire una query come mostra tutti i crash con iOS 17.4, versione app 3.2, nel modulo checkout e ottenere una selezione precisa in secondi.

Secondo Sentry (2024), le app che utilizzano breadcrumbs strutturati hanno il 60% in più di contesto in ogni report di crash rispetto alle app che registrano solo il testo dell’errore. Questo influisce direttamente sulla velocità di correzione dei bug.

Strumenti di raccolta e analisi

ELK Stack — Elasticsearch, Logstash, Kibana — rimane l’infrastruttura standard per lavorare con log strutturati. Logstash riceve i log in JSON, li trasforma e li invia a Elasticsearch per l’indicizzazione, Kibana fornisce un’interfaccia visiva per query e dashboard.

Per le applicazioni mobili, le soluzioni cloud sono popolari: Firebase Crashlytics con log personalizzati, Sentry con breadcrumbs, Datadog con monitoraggio APM. Accettano log strutturati direttamente dall’SDK mobile e non richiedono la distribuzione di un backend proprio. Firebase offre un pacchetto gratuito per i report di crash, Sentry aggiunge tracing distribuito e Datadog si integra con APM per tracciare le prestazioni delle richieste sia sul client che sul server contemporaneamente.

Grafana Loki — un’alternativa a Elasticsearch ottimizzata per i log. Loki non indicizza il contenuto dei messaggi per impostazione predefinita ma utilizza etichette (labels) per il filtraggio. Ciò è significativamente più economico in termini di archiviazione e più veloce per query su un insieme fisso di campi.

swift
// Logging strutturato tramite Swift Logger in 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
    }
}

Migliori pratiche di Structured Logging

La prima regola del logging strutturato: ogni messaggio deve contenere un identificatore di richiesta o sessione. Senza contesto, un singolo log è inutile — è impossibile sapere a quale utente o richiesta appartiene. Aggiungi un correlation ID all’inizio della sessione e passalo attraverso tutti i livelli dell’applicazione.

La seconda regola: tipizzazione dei campi. I campi numerici (duration_ms, status_code, retry_count) devono essere trasmessi come numeri, non come stringhe. Elasticsearch e sistemi simili indicizzano numeri e stringhe in modo diverso: i numeri possono essere aggregati (media, mediana, percentile), le stringhe supportano la ricerca full-text. Una tipizzazione errata impedisce la creazione di dashboard analitiche.

La terza regola: evita oggetti annidati. I log JSON con profondità di annidamento superiore a 2 livelli sono difficili da filtrare e visualizzare. Invece di {"user": {"name": "Alice", "role": "admin"}}, usa chiavi piatte: user_name=Alice user_role=admin.

kotlin
// Logging strutturato su Android tramite 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)
    }
}

Campi obbligatori

L’insieme minimo di campi per ogni messaggio strutturato: timestamp in formato ISO 8601, level (debug/info/warn/error/fatal), logger (nome del modulo o classe), message (descrizione leggibile dell’evento). Inoltre: correlation_id, user_id (se noto), version (versione dell’app), platform (iOS/Android), environment (dev/staging/prod).

Senza correlation_id, i log strutturati diventano un insieme di record scollegati che non possono essere legati in un unico scenario utente. Genera un UUID all’avvio dell’applicazione e aggiungilo a tutti i log di sessione. In pratica, il correlation_id deve essere trasmesso attraverso tutti i livelli: dagli eventi UI alle richieste di rete e ai task in background — altrimenti alcuni log rimarranno senza contesto e non parteciperanno all’analisi. Con il monitoraggio end-to-end, un singolo UUID consente di raccogliere il quadro completo del percorso dell’utente.

Esempi di logging strutturato in Swift e Kotlin

Su iOS, il logging strutturato può essere implementato tramite un wrapper su os_log che serializza i campi in formato logfmt. Su Android, tramite Timber con un Tree personalizzato che converte i messaggi in JSON o logfmt prima di inviarli al 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: confronto degli approcci

La scelta tra log strutturati e testuali dipende dalla fase del progetto. Nelle fasi iniziali dello sviluppo, i log testuali sono più semplici e veloci — lo sviluppatore scrive un messaggio direttamente senza wrapper aggiuntivi. Ma quando il progetto supera i limiti di un singolo team o server, i log strutturati diventano obbligatori.

CriterioLog testualiLog strutturati
LeggibilitàAlta in consoleMedia (richiede pretty-print)
Ricercagrep per sottostringaQuery per campi e valori
AggregazioneNon supportataMedia, mediana, percentili
IntegrazioneRichiede analisiNativa in ELK/Loki/Datadog
Volume di archiviazioneMinore (senza metadati)Maggiore (campi + valori)

Domande frequenti

Quale formato è migliore per il logging mobile?

Per l’invio al server, usa JSON — è nativamente supportato da Firebase Crashlytics, Sentry e Datadog. Per la visualizzazione locale nei log di Xcode o Android Studio, usa logfmt — è più compatto e leggibile senza formattazione.

È necessario registrare in formato strutturato sul client?

Sì, i log strutturati sul client consentono di aggiungere contesto a ogni report di crash: versione del SO, stato della rete, ultime azioni dell’utente. Senza breadcrumbs strutturati, un report di crash contiene solo lo stack delle chiamate senza lo scenario utente.

In che cosa logfmt differisce da JSON?

Logfmt è più compatto (30–50% di volume in meno) e più facile da leggere in un terminale. JSON supporta oggetti e array annidati ma richiede l’escape delle virgolette. La scelta dipende dall’infrastruttura: per ELK — JSON, per la visualizzazione in console — logfmt.

Come aggiungere un correlation ID a tutti i log?

Crea una singola istanza di UUID all’avvio dell’applicazione, memorizzala in un singleton o contenitore DI e passala a tutti i logger tramite il costruttore. Alternativa — usa l’archiviazione locale del thread o Continuation Local Storage nelle coroutine Kotlin.

Si possono mescolare log strutturati e testuali?

Si può, ma non è raccomandato — mescolando si perde la capacità di indicizzazione automatica. Se alcuni log sono testuali, devono essere analizzati con espressioni regolari, riducendo le prestazioni e l’affidabilità della ricerca. È meglio migrare tutti i log al formato strutturato.

Riepilogo

  • Structured Logging — formato di log con coppie chiave-valore, adatto per indicizzazione e query automatiche, a differenza delle stringhe di testo
  • JSON e logfmt — i formati principali: JSON è universale per i sistemi di raccolta, logfmt è compatto per la visualizzazione in console e log docker
  • Correlation ID — campo obbligatorio di ogni messaggio strutturato, senza di esso i log non possono essere collegati in una sessione utente
  • ELK Stack e Grafana Loki — soluzioni infrastrutturali standard per memorizzare, indicizzare e visualizzare log strutturati
  • Prestazioni — i team con structured logging rilevano incidenti 4 volte più velocemente grazie a query per campi invece di grep per testo
  • Tipizzazione — i numeri devono essere trasmessi come numeri, non come stringhe, per consentire aggregazioni (media, mediana, percentili) nei sistemi di analisi

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche