A Remote Logging egy olyan mechanizmus, amely naplókat küld egy mobileszközről egy távoli szerverre központosított elemzés és monitorozás céljából. Ellentétben a helyi naplózással, amely az adatokat az eszközön tárolja, a távoli gyűjtés lehetővé teszi a hibák és anomáliák valós idejű megtekintését az összes felhasználói eszközről. A Sentry Resource Library adatai szerint a remote logginggal rendelkező alkalmazások a kiadást követő első órában a termelési hibák 92%-át megtalálják, szemben a csak crash jelentéseket használó 15%-kal. Ez kötelező eszköz minden mobilfejlesztő csapat számára: a Firebase Crashlytics, a Sentry és a Datadog kész SDK-kat biztosít iOS-re és Androidra.
Főbb pontok
Remote Logging a naplók távoli eszközökről történő gyűjtésének és központi szerverre küldésének folyamata elemzés céljából. A mobilfejlesztés kontextusában a remote logging nem csak a crash jelentéseket (crash reporting) foglalja magában, hanem az egyéni eseményeket, breadcrumbs-eket, teljesítménymutatókat és felhasználói forgatókönyveket is.
A remote logging és a crash reporting közötti fő különbség a proaktivitás. A crash reporting csak a már bekövetkezett alkalmazás-összeomlások adatait gyűjti. A remote logging az összeomlás előtti események sorozatát gyűjti: milyen képernyőket nyitott meg a felhasználó, milyen kéréseket küldött, milyen adatokat vitt be. Ez lehetővé teszi a hiba forgatókönyvének reprodukálását anélkül, hogy kapcsolatba kellene lépni a felhasználóval.
Az Apple beépített mechanizmust biztosít a naplók távoli gyűjtésére a .logarchive-on keresztül, de termelési alkalmazásokhoz szinte mindig külső szolgáltatásokat használnak. Az Android SDK tartalmazza a Logcat-et, amely távolról elérhető ADB-n keresztül, de nem a végfelhasználói eszközök számára hibakeresési mód nélkül.
A remote logging architektúrája három összetevőből áll: a kliens SDK-ból az eszközön, amely gyűjti és puffereli a naplókat, a szállítási protokollból az adatok küldéséhez, és a szerverből a tároláshoz és megjelenítéshez.
| Összetevő | Szerep | Példák |
|---|---|---|
| Kliens SDK | Gyűjtés, pufferelés, batching | Firebase SDK, Sentry Cocoa, Timber |
| Szállítás | Adatküldés HTTPS-en keresztül | REST, gRPC, WebSocket |
| Szerver | Tárolás, indexelés, riasztások | Sentry, Crashlytics, Datadog |
A kliens SDK puffereli a naplókat a RAM-ban, és időszakonként kötegekben (batches) küldi őket a szerverre. Ha az eszköz offline, a naplók egy helyi fájlba kerülnek, és a következő hálózati csatlakozáskor küldődnek el. A puffer mérete és a küldési intervallum konfigurálható: tipikus értékek 50 esemény vagy 30 másodperc.
HTTPS REST — a legelterjedtebb protokoll a remote logging számára. Az SDK szerializálja a naplókat JSON formátumba, és POST kérésekkel küldi a szerver végpontjára. gRPC — alternatíva bináris szerializációval (Protocol Buffers), amely 30–40%-kal kompaktabb, mint a JSON, és gyorsabb az instabil kapcsolattal rendelkező mobileszközökön. WebSocket valós idejű naplózásra használatos hibakeresés során, de ritkán élesben az energiafogyasztás miatt.
Firebase Crashlytics — a Google ingyenes szolgáltatása crash jelentések és egyéni naplók gyűjtésére. Be van építve a Firebase SDK-ba, és nem igényel külön szervert. A Crashlytics automatikusan gyűjti a stack trace-t, az eszköz állapotát, az operációs rendszer verzióját és a nyitott képernyőket az összeomlás pillanatában.
Az egyéni naplók a Crashlytics-ben a log() metódussal adhatók hozzá — ezek nem azonnal kerülnek a szerverre, hanem egy körpufferben tárolódnak, és a következő crash jelentéshez csatolódnak. Ez a fő különbség a Sentry-hez képest, ahol minden napló külön esemény. Az egyéni naplók maximális mérete a Crashlytics-ben 64 KB crash-enként.
// Firebase Crashlytics — egyéni naplók Androidon
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 támogatja a setUserIdentifier-t a crash-ek konkrét felhasználókhoz való kapcsolásához. Ez segít meghatározni, hogy a hiba tömeges-e, vagy csak egy felhasználót érint. A setCustomKey tetszőleges kulcsokat ad minden jelentéshez — A/B teszt verzió, régió, tarifacsomag.
Sentry — egy hiba-monitorozó platform, amely nem csak a crash jelentéseket tárolja, hanem az összes egyéni eseményt (breadcrumbs) is független rekordként. A Crashlytics-szel ellentétben a Sentry lehetővé teszi a hiba előtti események sorozatának kronológiai sorrendben történő megtekintését — a breadcrumbs láthatók a felületen anélkül, hogy a crash naplóból kellene rekonstruálni őket.
A Sentry SDK automatikusan gyűjti a breadcrumbs-eket rendszereseményekhez: UIViewController életciklus-változások (viewDidLoad, viewWillAppear), érintések, gombkattintások, HTTP kérések URLSession-en keresztül. Mindezek az események megjelennek a hiba idővonalán az egyéni breadcrumbs-ekkel együtt. Android esetén hasonlóan gyűjtődnek az Activity és Fragment életciklusok, onClick események és hálózati kérések OkHttp-n keresztül.
A Sentry SDK iOS és Android esetén automatikusan gyűjti az UI események breadcrumbs-eit: érintések, navigáció, életciklus. A fejlesztő egyéni breadcrumbs-eket adhat hozzá a addBreadcrumb() segítségével, megadva a típust, kategóriát és szintet. A Sentry támogatja a distributed tracinget: a naplózó összekapcsolja a breadcrumbs-eket a kliensen a backend kérésekkel trace ID-n keresztül.
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 — a szabványos Android naplózórendszer, amely az Android Debug Bridge (ADB) segítségével érhető el. A Logcat összegyűjti az összes rendszer- és alkalmazásüzenetet, szintek (V, D, I, W, E, F) és címkék szerint bontva. A Logcat-hez való távoli hozzáférés ADB-n keresztül USB-n vagy Wi-Fi-n működik, de csak hibakeresési módban lévő eszközök esetén — az USB-kapcsolat nélküli eszközökön futó termelési alkalmazások nem érhetők el.
A távoli naplózáshoz termelésben Androidon alternatívákat használnak: a Logcat önmagában nem tud naplókat küldeni a szerverre. Szerepe a helyi diagnosztika. De léteznek wrapper-ek (Timber, LogcatLive), amelyek továbbítják az üzeneteket a Firebase-be vagy a Sentry-be, megtartva az ismerős Log.d / Log.e API-t. A Timber lehetővé teszi a kezelők váltását az alkalmazáskód módosítása nélkül — a debug fa a Logcat-be ír, a release fa batchinggel és tömörítéssel küld a szerverre.
Batching — több napló egy HTTP kérésbe történő csoportosítása a forgalom és az akkumulátor megtakarítása érdekében. 50 különálló POST kérés helyett az SDK egy JSON tömböt küld. Tipikus stratégiák: küldés ütemezés szerint (30 másodpercenként), darabszám szerint (50 eseményenként) vagy esemény szerint (csak kritikus hiba esetén).
A milliós felhasználói bázissal rendelkező alkalmazásoknál a naplók mennyisége elérheti a terabájtot naponta. A batching 10–50-szeresére csökkenti a kérések számát és mérsékli a szerver terhelését. A Sentry gzip tömörítést használ a szállítási rétegben, ami további 60–70%-kal csökkenti az adatmennyiséget.
// A batching egyszerű megvalósítása Androidon
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 — a szabványos tömörítési módszer a naplók HTTP átviteléhez. A Sentry és Crashlytics SDK-k automatikusan tömörítik a kérés törzsét küldés előtt. Deduplikáció — ismétlődő üzenetek eltávolítása a kliens oldalon: ha ugyanaz az esemény 100-szor fordul elő másodpercenként, az SDK egyszer küldi el a count = 100 mezővel.
A leggyakoribb hiba — érzékeny adatok naplózása. A remote logging SDK adatokat küld a szerverre, és ha a fejlesztő véletlenül naplózza a felhasználó jelszavát, tokenjét vagy e-mail címét, ezek az adatok a felhő infrastruktúrába kerülnek. Mindig használjon PII (Személyazonosításra Alkalmas Információ) szűrést SDK szinten: a Sentry beépített beforeSend-hook-kal rendelkezik az adatok tisztítására küldés előtt.
A második gyakori probléma — túlzott naplózás. Ha minden ujjmozdulat a szerverre kerül, az adatmennyiség exponenciálisan nő, és a szerverköltségek is. Határozzon meg naplózási költségvetést: termelésben ne több, mint 1–5 esemény felhasználónként percenként. Debug naplókat csak olyan jelzővel küldjön, amely adott eszközökön kapcsolható be.
A harmadik hiba — az offline forgatókönyv figyelmen kívül hagyása. Ha az SDK elveszíti a naplókat hálózat hiányában, és nem állítja helyre őket az újracsatlakozáskor, a remote logging haszontalan az instabil kapcsolattal rendelkező felhasználók számára. Az összes SDK (Firebase, Sentry) automatikusan gyorsítótárazza a naplókat egy helyi fájlba, és elküldi őket a hálózat megjelenésekor, de ezt a beállítást ellenőrizni kell.
Gyakran Ismételt Kérdések
A crash reporting csak az alkalmazás összeomlásairól gyűjt információkat. A Remote Logging az összes eseményt gyűjti: egyéni naplók, breadcrumbs, teljesítménymutatók, UI események. A crash reporting a remote logging egy részhalmaza, nem alternatívája.
A Crashlytics ingyenes és elegendő az alapvető crash jelentésekhez. A Sentry jobb, ha breadcrumbs-re, distributed tracing-re, egyéni irányítópultokra és rugalmas riasztásokra van szüksége. Vállalati projektekhez megfelelőségi követelményekkel a Sentry elérhető self-hosted verzióban.
Használjon naplózási szinteket: a debug/info naplókat csak a fejlesztői eszközről küldje az isDebuggable jelzőn keresztül. A többi szintet (warn, error) szűrje a beforeSend-hook segítségével, távolítsa el a PII-t tartalmazó mezőket. Határozza meg a munkamenetenkénti maximális naplóméretet.
A Logcat nem támogatja a távoli küldést szerverre. Távoli naplózáshoz Androidon használja a Timber-t a Firebase-be vagy Sentry-be történő továbbításhoz, a Logcat-et pedig hagyja meg USB-n keresztüli hibakereséshez. A Timber helyettesíti az Android Log API-t, és ültethető fákat ad hozzá.
Eszközönként percenként 50 eseményig nincs észrevehető hatása az akkumulátor fogyasztására, ha batchinget használ (kötegenkénti küldés, nem egyenként). 200+ eseménynél percenként a Wi-Fi/modem folyamatosan aktív lesz — az akkumulátor 15–25%-kal gyorsabban merül.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is