Log Level — a naplóüzenetek kritikusság szerinti osztályozása, amely lehetővé teszi a fejlesztők számára a kimenő információk mennyiségének szabályozását az alkalmazás működésének különböző szakaszaiban. A Google Android Developers, 2024 adatai szerint a naplózási szint helyes megválasztása 85–95%-kal csökkenti a naplók mennyiségét éles üzemben és felgyorsítja a hibák diagnosztizálását. Minden szint megoldja a saját feladatát — a hibakereséstől a fejlesztési szakaszban a kritikus meghibásodások monitorozásáig éles üzemben.
Főbb pontok
Log Level — minden naplóüzenet attribútuma, amely meghatározza annak fontosságát és feldolgozási sürgősségét. A modern iOS és Android platformok egységes, 6–7 szintű skálát támogatnak: a maximálisan részletes (Verbose/Trace) szinttől a kritikusig (Error/Assert). A szint kiválasztása határozza meg, hogy az üzenet rögzítésre kerül-e a naplóban az alkalmazás aktuális konfigurációja mellett.
A Log Level koncepciója a kritikussági piramis elvén alapul: minél magasabb a szint, annál kevesebb üzenet jelenik meg rajta. A Semaphore CI, 2024 adatai szerint egy éles alkalmazásban az eloszlás a következő: Info — 60% üzenet, Warn — 25%, Error — 10%, Debug — 5%. A Verbose üzeneteket teljesen ki kell kapcsolni éles üzemben.
Minden platform a saját API-ján keresztül valósítja meg a Log Level-t. Az Android a android.util.Log-ot használja a v(), d(), i(), w(), e() metódusokkal. Az Apple — OSLog-ot a default, info, debug, error, fault szintekkel. Az olyan könyvtárak, mint a Timber és a CocoaLumberjack, további funkciókat építenek ezen szabványos API-k fölé.
A Google I/O 2023 adatai szerint a Log Level helytelen megválasztása az éles üzemben előforduló teljesítményproblémák 40%-áért felelős. A fejlesztők a Debug naplókat a release buildben hagyják, ami túlzott lemezírásra és felgyorsult akkumulátor-lemerüléshez vezet.
Verbose (TRACE) — a legrészletesebb szint, kizárólag fejlesztésre szánt. Ezen a szinten minden közbenső számítás, ciklusiteráció, az algoritmus minden lépésének eredménye megjelenik. Androidon ez a szint a Log.v()-nak felel meg, iOS-en — OSLog debug típussal (iOS 14 előtt os_trace-t használtak).
Debug — hibakereső üzenetek, hasznosak a fejlesztés és tesztelés során. Tartalmazzák a kulcsfontosságú objektumok állapotát, SQL-lekérdezések eredményeit, API-hívások paramétereit. A Verbose-tól eltérően a Debug üzenetek strukturáltak és szemantikailag jelentőséggel bírnak. iOS-en ez a szint a OSLogType.debug-nak felel meg.
Info — tájékoztató üzenetek az alkalmazás szokásos eseményeiről: SDK inicializálás, sikeres hitelesítés, képernyő megnyitása, adatok fogadása a szerverről. Az Info üzenetek nem tartalmazhatnak személyes felhasználói adatokat, és biztonságosnak kell lenniük az éles elemzéshez. iOS-en a OSLogType.info-t, Androidon a Log.i()-t használják.
Warn — figyelmeztetések potenciális problémákról. Az alkalmazás tovább működik, de a helyzet figyelmet igényel: a gyorsítótár mérete megközelíti a határt, elavult API-verzió, lassú hálózati válasz, ismételt kapcsolódási kísérlet. Androidon — Log.w(), iOS-en — OSLogType.default (figyelmeztetésekhez).
Error — kritikus hibák, amikor az alkalmazás nem tudja végrehajtani a kért műveletet, de tovább működik: sikertelen API-kérés, kapcsolat megszakadása, adatbázis-írási hiba, hiányzó engedélyek. iOS-en a hibákhoz a OSLogType.error-t, Androidon a Log.e()-t használják.
Assert (WTF) — a legmagasabb szint, amely egy „ez nem történhet meg” helyzetet jelez. Olyan hibák naplózására használják, amelyek megsértik a rendszer alapvető invariánsait. Androidon az Assert üzenetek alapértelmezés szerint nem jelennek meg a release buildben. iOS-en a WTF (What a Terrible Failure) a OSLogType.fault segítségével kerül feldolgozásra.
Android Log API — a beépített naplózási mechanizmus az android.util.Log csomagból. 6 statikus metódust biztosít: Log.v(), Log.d(), Log.i(), Log.w(), Log.e() és Log.wtf(). Minden metódus fogad egy tag-et (forrásazonosító sztring) és msg-t (üzenet szövege).
class UserRepository {
companion object {
private val TAG = "UserRepo"
}
suspend fun loadUser(id: String): User {
Log.d(TAG, "Felhasználó betöltése azonosítóval: $id")
return try {
val response = api.fetchUser(id)
Log.i(TAG, "Felhasználó sikeresen betöltve")
response.toUser()
} catch (e: Exception) {
Log.e(TAG, "Nem sikerült betölteni a felhasználót: ${e.message}")
throw e
}
}
}
Szintek szerinti szűrés az Android Logcat-ben ADB-n keresztül történik: adb logcat *:E csak az Error üzeneteket jeleníti meg. Az éles build-ekben az összes Log.v() és Log.d() hívást eltávolítja a ProGuard/R8, ha a minifikáció be van kapcsolva. A Log.i(), Log.w() és Log.e() megmarad, ezért fontos, hogy ne adjunk ki érzékeny adatokat ezeken a metódusokon keresztül.
Egyéni szűréshez futásidőben az Android a Log.isLoggable(tag, level) metódust biztosítja — amely ellenőrzi, hogy az adott szint be van-e kapcsolva egy adott tag-hez. Ez lehetővé teszi a részletes naplózás dinamikus bekapcsolását egy adott modulhoz az alkalmazás újraépítése nélkül.
OSLog — az Apple egységes naplózási rendszere, amely felváltotta az elavult NSLog-ot. Az OSLog 5 szintet biztosít: debug, info, default (notice), error és fault. A fő előny a strukturált naplózás formázott sztringek támogatásával és dinamikus szűréssel a konzolon keresztül.
import OSLog
let logger = Logger(
subsystem: "com.example.app",
category: "network"
)
func fetchData(from url: URL) {
logger.debug("Starting request to \(url.absoluteString)")
do {
let data = try Data(contentsOf: url)
logger.info("Received \(data.count) bytes")
} catch {
logger.error("Request failed: \(error.localizedDescription)")
}
}
Szűrőrendszere az OSLog-nak az operációs rendszer szintjén működik. A Debug üzenetek csak akkor kerülnek rögzítésre, ha a debugger csatlakoztatva van, vagy ha a -com.apple.CoreData.Logging.debug 1 argumentum be van kapcsolva. Az Info üzenetek az eszköz memóriájában gyűlnek (akár 512 KB-ig), és a Console.app-on keresztül érhetők el. Az Error és fault folyamatosan rögzítésre kerül, és elérhető a crash-reporting rendszereken keresztül történő gyűjtéshez.
Az OSLog fontos jellemzője: formázott sztringek placeholderekkel. A Swift sztringinterpoláció helyett (amely mindig kiszámításra kerül, a szinttől függetlenül) az OSLog az os_log formátumot használja %{public}@ és %{private}@ jelölőkkel az érzékeny adatok elkülönítésére. A privát paraméterek maszkolásra kerülnek az éles naplókban.
Alapszabály — minimális szintkészlet éles üzemben: Info, Warn, Error, Assert. A Debug és Verbose szinteket ki kell kapcsolni. Az ok nem annyira a biztonság, mint a teljesítmény: minden naplóhívás processzoridőt vesz igénybe a sztring formázásához, még akkor is, ha az üzenet nem jelenik meg.
Kritikus optimalizálás — soha ne használjunk sztringinterpolációt naplóhívásokban. Ha a sztring a log() hívása előtt kerül kialakításra, a processzoridő elvész, még akkor is, ha a szint ki van kapcsolva. Használjunk lusta formázást lambda-kifejezéseken vagy védőfeltételeken keresztül.
Androidon a Log.isLoggable() metódus szolgálja ezt a célt, OSLog-ban — a placeholderekkel formázott sztringek natív támogatása. A Timber Androidra a problémát a timber.log.Tree-n keresztül oldja meg a szint ellenőrzésével a fa belsejében.
Remote Log Level — gyakorlat, ahol a naplózási szintet a szerverről vezérlik Firebase Remote Config vagy hasonló szolgáltatáson keresztül. Ha egy összetett hiba lép fel éles üzemben, a fejlesztő távolról bekapcsolhatja a Debug naplózást egy adott modulhoz a kiválasztott felhasználói csoport eszközein.
A Firebase, 2024 adatai szerint ez a gyakorlat 60%-kal csökkenti a ritka hibák diagnosztizálási idejét, és lehetővé teszi a probléma teljes képének megszerzését debug build telepítése nélkül. A fő korlátozás — a naplók csak a konfiguráció kézhezvétele utáni következő alkalmazásindításkor aktiválódnak.
BuildConfig.DEBUG Androidon és #if DEBUG Swift-ben — a feltételes fordítás szabványos mechanizmusai, amelyek kikapcsolják a hibakeresési szinteket a release build-ben. A tiszta architektúrához ajánlott a Log Level kiválasztását egy DI konténerbe vagy logger gyárba kiszervezni, hogy az üzleti logikát ne terheljék feltételes direktívák.
Első szabály — minden naplóhívásnak válaszolnia kell a „ki, mit, mikor” kérdésre. Ki — komponens vagy modul (tag Androidon, category iOS-en). Mi — konkrét esemény vagy állapotváltozás. Mikor — időbélyeg, amelyet a naplózási rendszer automatikusan állít be.
Második szabály — ne naplózzunk érzékeny adatokat Info és magasabb szinteken. Jelszavak, tokenek, e-mailek, telefonszámok, pontos geokoordináták — szigorúan tilosak bármely naplóban, amely éles üzembe kerül. Szükség esetén használjunk maszkolást: „email: us***@example.com”.
Harmadik szabály — a Warn szint a fejlesztő felelősségi területe, az Error a csapaté. Warn azt jelenti: „itt potenciális probléma van, figyeld”. Error — „itt probléma van, javítsd”. Ne használjuk az Error-t olyan helyzetekre, amelyek várhatóak és kezeltek (például 404 API hiba).
Negyedik szabály — konzisztencia. Az egész projektnek egységes elnevezési konvenciókat kell használnia a tag-ek és kategóriák számára. Ajánlott a ClassName.methodName Android tag-ekhez és a module.subsystem iOS kategóriákhoz. Ez lehetővé teszi a naplók gyors szűrését komponens szerint.
Ötödik szabály — teszteljük a naplókat. Az egységtesztekben ellenőrizzük, hogy bizonyos forgatókönyvekben a megfelelő Log Level kerül meghívásra. Erre a célra léteznek mock naplózási könyvtárak: Mockito Androidhoz, Cuckoo iOS-hez. A szintek ellenőrzése a tesztekben megakadályozza a hibakeresési üzenetek éles üzembe szivárgását.
Gyakran ismételt kérdések
Felgyorsult akkumulátorlemerülés és túlzott lemezírás. Minden Debug napló formázza a sztringet és adatokat ír a pufferbe. Flash memóriás eszközökön ez felgyorsítja a tároló kopását. Emellett a Debug naplók érzékeny adatokat tartalmazhatnak, amelyek éles üzemben nem elérhetők megtekintésre.
Debug — a kérés és válasz törzséhez, fejlécekhez és állapotkórhoz. Info — a kérés végrehajtásának tényéhez (URL, metódus, időtartam). Error — a sikertelen kérésekhez 4xx/5xx kóddal. Soha ne használjunk Verbose-t hálózati naplókhoz éles üzemben.
OSLogType.default (notice szint) — közepes fontosságú üzenetek, mentésre kerülnek a rendszernaplóban és láthatók a Console.app-ban. OSLogType.info — technikai üzenetek, nem kerülnek állandó mentésre, csak aktív profilozás során érhetők el az Instruments-en keresztül.
R8/ProGuard eltávolítja a Log.v() és Log.d() hívásokat, ha a minifikáció be van kapcsolva a release build-ben. A Log.i(), Log.w(), Log.e() megmarad. Az összes napló teljes eltávolításához egyéni szabály szükséges: -assumenosideeffects class android.util.Log az összes szint megadásával.
Nem — a túlzott naplózás rontja az olvashatóságot és a teljesítményt. Csak összetett vagy aszinkron metódusokban naplózzuk a belépést. Szinkron metódusokhoz elegendő egyetlen napló a visszatérési ponton vagy hibánál. Használjuk a Debug szintet a hívások nyomon követéséhez.
Ö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