Remote Logging este mecanismul de trimitere a logurilor de pe un dispozitiv mobil către un server la distanță pentru analiză și monitorizare centralizată. Spre deosebire de logarea locală, care stochează datele pe dispozitiv, colectarea la distanță permite vizualizarea erorilor și anomalii de pe toate dispozitivele utilizatorilor în timp real. Potrivit Sentry Resource Library, aplicațiile cu remote logging găsesc 92% din bug-urile de producție în prima oră după lansare, față de 15% când se folosesc doar rapoarte de crash. Este un instrument obligatoriu pentru orice echipă de dezvoltare mobilă: Firebase Crashlytics, Sentry și Datadog oferă SDK-uri gata făcute pentru iOS și Android.
Principalele puncte
Remote Logging este procesul de colectare a logurilor de pe dispozitive la distanță și transmiterea lor către un server central pentru analiză. În contextul dezvoltării mobile, remote logging include nu doar rapoartele de crash (crash reporting), ci și evenimente personalizate, breadcrumbs, metrici de performanță și scenarii de utilizator.
Diferența principală dintre remote logging și crash reporting este proactivitatea. Crash reporting colectează doar date despre căderile aplicației care au avut deja loc. Remote logging colectează secvența evenimentelor înainte de crash: ce ecrane a deschis utilizatorul, ce cereri a făcut, ce date a introdus. Acest lucru permite reproducerea scenariului de eroare fără a comunica cu utilizatorul.
Apple oferă un mecanism încorporat de colectare la distanță a logurilor prin .logarchive, dar pentru aplicațiile de producție se folosesc aproape întotdeauna servicii terțe. Android SDK include Logcat, care este accesibil la distanță prin ADB, dar nu pentru dispozitivele utilizatorilor finali fără modul de debug.
Arhitectura remote logging constă din trei componente: SDK-ul client pe dispozitiv, care colectează și buffer-ează logurile, protocolul de transport pentru trimiterea datelor și serverul pentru stocare și vizualizare.
| Componentă | Rol | Exemple |
|---|---|---|
| SDK client | Colectare, bufferizare, batching | Firebase SDK, Sentry Cocoa, Timber |
| Transport | Transmiterea datelor prin HTTPS | REST, gRPC, WebSocket |
| Server | Stocare, indexare, alerte | Sentry, Crashlytics, Datadog |
SDK-ul client buffer-ează logurile în memoria RAM și le trimite periodic pe server în loturi (batches). Dacă dispozitivul este offline, logurile sunt salvate într-un fișier local și trimise la următoarea conectare la rețea. Dimensiunea buffer-ului și intervalul de trimitere sunt configurabile: valorile tipice sunt 50 de evenimente sau 30 de secunde.
HTTPS REST — cel mai răspândit protocol pentru remote logging. SDK-ul serializează logurile în JSON și le trimite prin cereri POST către endpoint-ul serverului. gRPC — o alternativă cu serializare binară (Protocol Buffers), care este cu 30–40% mai compactă decât JSON și mai rapidă pe dispozitive mobile cu conexiune instabilă. WebSocket este utilizat pentru logarea în timp real în debug, dar rar în producție din cauza consumului de energie.
Firebase Crashlytics — serviciul gratuit Google pentru colectarea rapoartelor de crash și a logurilor personalizate. Este încorporat în Firebase SDK și nu necesită un server separat. Crashlytics colectează automat stack trace, starea dispozitivului, versiunea sistemului de operare și ecranele deschise în momentul căderii.
Logurile personalizate în Crashlytics se adaugă prin metoda log() — ele nu sunt trimise imediat pe server, ci sunt stocate într-un buffer circular și atașate la următorul raport de crash. Aceasta este diferența cheie față de Sentry, unde fiecare log este un eveniment separat. Volumul maxim al logurilor personalizate în Crashlytics este de 64 KB per crash.
// Firebase Crashlytics — loguri personalizate pe Android
import com.google.firebase.crashlytics.FirebaseCrashlytics
class CheckoutViewModel {
fun processPayment(amount: Double) {
FirebaseCrashlytics.getInstance()
.log("Payment started: amount=$amount")
try {
process(amount)
} catch (e: Exception) {
FirebaseCrashlytics.getInstance()
.recordException(e)
}
}
}
Firebase Crashlytics suportă setUserIdentifier pentru asocierea crash-urilor cu utilizatori specifici. Acest lucru ajută la determinarea dacă bug-ul este masiv sau afectează doar un singur utilizator. setCustomKey adaugă chei arbitrare la fiecare raport — versiunea testului A/B, regiunea, planul tarifar.
Sentry — platformă de monitorizare a erorilor care stochează nu doar rapoartele de crash, ci și toate evenimentele personalizate (breadcrumbs) ca înregistrări independente. Spre deosebire de Crashlytics, Sentry permite vizualizarea secvenței evenimentelor înainte de eroare în ordine cronologică — breadcrumbs sunt vizibile în interfață fără a fi nevoie să le reconstituiți din logul de crash.
SDK-ul Sentry colectează automat breadcrumbs pentru evenimente sistemice: modificări ale ciclului de viață UIViewController (viewDidLoad, viewWillAppear), touches, clicuri pe butoane, cereri HTTP prin URLSession. Toate aceste evenimente sunt afișate pe timeline-ul erorii împreună cu breadcrumbs personalizate. Pentru Android, în mod similar, se colectează lifecycle Activity și Fragment, evenimente onClick și cereri de rețea prin OkHttp.
SDK-ul Sentry pentru iOS și Android colectează automat breadcrumbs ale evenimentelor UI: touches, navigare, lifecycle. Dezvoltatorul poate adăuga breadcrumbs personalizate prin addBreadcrumb() specificând tipul, categoria și nivelul. Sentry suportă distributed tracing: loggerul leagă breadcrumbs pe client cu cererile pe backend prin trace ID.
import Sentry
func trackCartEvent(action: String, itemId: String) {
let crumb = Breadcrumb()
crumb.level = .info
crumb.category = "cart"
crumb.message = "Cart \(action): \(itemId)"
crumb.data = ["action": action, "item_id": itemId]
SentrySDK.addBreadcrumb(crumb)
}
Logcat — sistemul standard de logare Android, accesibil prin Android Debug Bridge (ADB). Logcat colectează toate mesajele de sistem și ale aplicațiilor, împărțite pe niveluri (V, D, I, W, E, F) și tag-uri. Accesul la distanță la Logcat funcționează prin ADB prin USB sau Wi-Fi, dar numai pentru dispozitivele în modul debug — aplicațiile de producție pe dispozitive fără conexiune USB nu sunt accesibile.
Pentru logarea la distanță în producție pe Android se folosesc alternative: Logcat în sine nu poate trimite loguri pe server. Rolul său este diagnosticarea locală. Dar există wrapper-e (Timber, LogcatLive) care redirecționează mesajele către Firebase sau Sentry, păstrând API-ul familiar Log.d / Log.e. Timber permite schimbarea handler-elor fără modificarea codului aplicației — arborele debug scrie în Logcat, arborele release trimite pe server cu batching și compresie.
Batching — gruparea mai multor loguri într-o singură cerere HTTP pentru economisirea traficului și bateriei. În loc de 50 de cereri POST separate, SDK-ul trimite un singur array JSON. Strategii tipice: trimiterea după un program (la fiecare 30 de secunde), după număr (la fiecare 50 de evenimente) sau după eveniment (doar la o eroare critică).
Pentru aplicațiile cu milioane de utilizatori, volumul logurilor poate atinge terabyte pe zi. Batching reduce numărul de cereri de 10–50 de ori și scade încărcarea serverului. Sentry utilizează compresia gzip la nivel de transport, ceea ce reduce suplimentar volumul datelor cu 60–70%.
// Implementare simplă a batching-ului pe Android
class LogBatcher {
private val buffer = mutableListOf<LogEvent>()
private val maxSize = 50
private val intervalMs = 30_000L
fun append(event: LogEvent) {
buffer.add(event)
if (buffer.size >= maxSize) flush()
}
suspend fun flush() {
val batch = buffer.toList()
buffer.clear()
sendToServer(batch)
}
}
gzip — metoda standard de compresie pentru transmiterea logurilor prin HTTP. SDK-urile Sentry și Crashlytics comprimă automat corpul cererii înainte de trimitere. Deduplicarea — eliminarea mesajelor duplicate pe partea clientului: dacă același eveniment este prins de 100 de ori pe secundă, SDK-ul îl trimite o singură dată cu câmpul count = 100.
Cea mai frecventă eroare — logarea datelor sensibile. Remote logging SDK transmite date pe server, iar dacă dezvoltatorul loghează accidental parola, token-ul sau email-ul utilizatorului, aceste date ajung în infrastructura cloud. Folosiți întotdeauna filtrarea PII (Informații de Identificare Personală) la nivel de SDK: Sentry are un hook beforeSend încorporat pentru curățarea datelor înainte de trimitere.
A doua problemă comună — logarea excesivă. Dacă fiecare mișcare a degetului este trimisă pe server, volumul datelor crește exponențial, iar costurile serverului de asemenea. Stabiliți un buget pentru loguri: nu mai mult de 1–5 evenimente per utilizator pe minut în producție. Logurile de debug trimiteți-le doar cu un flag care se activează pentru anumite dispozitive.
A treia eroare — ignorarea scenariului offline. Dacă SDK-ul pierde logurile în absența rețelei și nu le recuperează la reconectare, remote logging este inutil pentru utilizatorii cu conexiune instabilă. Toate SDK-urile (Firebase, Sentry) cache-uiesc automat logurile într-un fișier local și le trimit la apariția rețelei, dar această setare trebuie verificată.
Întrebări frecvente
Crash reporting colectează doar informații despre căderile aplicației. Remote Logging colectează toate evenimentele: loguri personalizate, breadcrumbs, metrici de performanță, evenimente UI. Crash reporting este un subset al remote logging, nu o alternativă.
Crashlytics este gratuit și suficient pentru rapoarte de crash de bază. Sentry este mai bun dacă aveți nevoie de breadcrumbs, distributed tracing, dashboard-uri personalizate și alerte flexibile. Pentru proiecte enterprise cu cerințe de conformitate, Sentry este disponibil în versiunea self-hosted.
Folosiți niveluri de logare: logurile debug/info trimiteți-le doar de pe dispozitivul dezvoltatorului prin flag-ul isDebuggable. Celelalte niveluri (warn, error) filtrați-le prin hook-ul beforeSend, eliminând câmpurile care conțin PII. Stabiliți dimensiunea maximă a logului pe sesiune.
Logcat nu suportă trimiterea la distanță pe server. Pentru remote logging pe Android, folosiți Timber pentru redirecționarea către Firebase sau Sentry, iar Logcat lăsați-l pentru debug prin USB. Timber înlocuiește Android Log API și adaugă arbori plantabili.
Până la 50 de evenimente pe minut pe dispozitiv nu afectează vizibil consumul bateriei, dacă se folosește batching (trimiterea în loturi, nu individual). La 200+ evenimente pe minut, Wi-Fi/modem-ul va fi activ constant — bateria se descarcă cu 15–25% mai repede.
Concluzii
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.
Citiți și