Log Level w tworzeniu aplikacji: co to jest, rodzaje poziomów i konfiguracja

Autor: IT Sectr Opublikowano: 2026-05-28 Czas czytania: 8 min

Log Level — klasyfikacja komunikatów logowania według stopnia krytyczności, pozwalająca programistom kontrolować ilość wyświetlanych informacji na różnych etapach działania aplikacji. Według danych Google Android Developers, 2024, prawidłowy wybór poziomu logowania zmniejsza objętość logów w produkcji o 85–95% i przyspiesza diagnozowanie błędów. Każdy poziom rozwiązuje swoje zadanie — od debugowania na etapie rozwoju po monitorowanie krytycznych awarii w środowisku produkcyjnym.

Najważniejsze

  • Log Level — standaryzowana skala krytyczności od Verbose (szczegółowe debugowanie) do Error (krytyczne awarie)
  • Verbose i Debug — poziomy przeznaczone do rozwoju, wyłączane w kompilacjach produkcyjnych dla wydajności
  • Info — komunikaty informacyjne o kluczowych zdarzeniach: uruchomienie, autoryzacja, nawigacja
  • Warn — ostrzeżenia o potencjalnych problemach, które nie powodują natychmiastowej awarii
  • Error — krytyczne błędy wymagające natychmiastowej uwagi i analizy przez programistę

Co to jest Log Level?

Log Level — to atrybut każdego komunikatu logu określający jego ważność i pilność przetwarzania. Nowoczesne platformy iOS i Android obsługują jednolitą skalę 6–7 poziomów: od maksymalnie szczegółowego (Verbose/Trace) do krytycznego (Error/Assert). Wybór poziomu określa, czy komunikat zostanie zapisany w logu przy bieżącej konfiguracji aplikacji.

Koncepcja Log Level opiera się na zasadzie piramidy krytyczności: im wyższy poziom, tym mniej komunikatów jest na nim wyświetlanych. Według danych Semaphore CI, 2024, w aplikacji produkcyjnej rozkład wygląda następująco: Info — 60% komunikatów, Warn — 25%, Error — 10%, Debug — 5%. Komunikaty Verbose powinny być całkowicie wyłączone w produkcji.

Każda platforma implementuje Log Level poprzez własne API. Android używa android.util.Log z metodami v(), d(), i(), w(), e(). Apple — OSLog z poziomami default, info, debug, error, fault. Biblioteki takie jak Timber i CocoaLumberjack nadbudowują dodatkową funkcjonalność na tych standardowych API.

Według danych Google I/O 2023, nieprawidłowy wybór Log Level jest przyczyną 40% problemów z wydajnością w produkcji. Programiści pozostawiają logi Debug w kompilacji release, co prowadzi do nadmiernego zapisu na dysk i przyspieszonego rozładowania baterii.

Rodzaje poziomów logowania: od Verbose do Assert

Verbose (TRACE) — najbardziej szczegółowy poziom, przeznaczony wyłącznie do rozwoju. Na tym poziomie wyświetlane są wszystkie pośrednie obliczenia, iteracje pętli, wyniki każdego kroku algorytmu. Na Androidzie temu poziomowi odpowiada Log.v(), na iOS — OSLog z typem debug (przed iOS 14 używano os_trace).

Debug — komunikaty debugowania, przydatne podczas tworzenia i testowania. Zawierają informacje o stanie kluczowych obiektów, wyniki zapytań SQL, parametry wywołań API. W przeciwieństwie do Verbose, komunikaty Debug są ustrukturyzowane i semantycznie znaczące. Na iOS temu poziomowi odpowiada OSLogType.debug.

Info — komunikaty informacyjne o standardowych zdarzeniach aplikacji: inicjalizacja SDK, pomyślna autoryzacja, otwarcie ekranu, pobranie danych z serwera. Komunikaty Info nie powinny zawierać danych osobowych użytkowników i powinny być bezpieczne do analizy w produkcji. Na iOS używany jest OSLogType.info, na Androidzie — Log.i().

Warn — ostrzeżenia o potencjalnych problemach. Aplikacja nadal działa, ale sytuacja wymaga uwagi: rozmiar pamięci podręcznej zbliżający się do limitu, przestarzała wersja API, wolna odpowiedź sieciowa, ponowna próba połączenia. Na Androidzie — Log.w(), na iOS — OSLogType.default (dla ostrzeżeń).

Error — krytyczne błędy, przy których aplikacja nie może wykonać żądanej operacji, ale kontynuuje działanie: nieudane żądanie do API, utrata połączenia, błąd zapisu do bazy danych, brak uprawnień. Na iOS dla błędów używany jest OSLogType.error, na Androidzie — Log.e().

Assert (WTF) — najwyższy poziom, oznaczający sytuację „to nie powinno się zdarzyć”. Używany do logowania błędów naruszających fundamentalne niezmienniki systemu. Na Androidzie komunikaty Assert nie są wyświetlane w kompilacjach release domyślnie. Na iOS WTF (What a Terrible Failure) jest obsługiwane przez OSLogType.fault.

Używanie Log Level na Android

Android Log API — wbudowany mechanizm logowania z pakietu android.util.Log. Dostarcza 6 statycznych metod: Log.v(), Log.d(), Log.i(), Log.w(), Log.e() i Log.wtf(). Każda metoda przyjmuje tag (ciąg identyfikujący źródło) i msg (treść komunikatu).

kotlin
class UserRepository {
    companion object {
        private val TAG = "UserRepo"
    }

    suspend fun loadUser(id: String): User {
        Log.d(TAG, "Wczytywanie użytkownika o id: $id")

        return try {
            val response = api.fetchUser(id)
            Log.i(TAG, "Użytkownik wczytany pomyślnie")
            response.toUser()
        } catch (e: Exception) {
            Log.e(TAG, "Nie udało się wczytać użytkownika: ${e.message}")
            throw e
        }
    }
}

Filtrowanie według poziomów w Android Logcat odbywa się przez ADB: adb logcat *:E pokaże tylko komunikaty Error. W kompilacjach produkcyjnych wszystkie wywołania Log.v() i Log.d() są usuwane przez ProGuard/R8 przy włączonej minifikacji. Log.i(), Log.w() i Log.e() pozostają, dlatego ważne jest, aby nie wyświetlać wrażliwych danych przez te metody.

Do niestandardowego filtrowania w czasie wykonania Android udostępnia Log.isLoggable(tag, level) — metodę, która sprawdza, czy określony poziom jest włączony dla danego tagu. Pozwala to dynamicznie włączać szczegółowe logowanie dla konkretnego modułu bez przebudowy aplikacji.

Używanie Log Level na iOS i macOS

OSLog — ujednolicony system logowania Apple, który zastąpił przestarzały NSLog. OSLog udostępnia 5 poziomów: debug, info, default (notice), error i fault. Główną zaletą jest ustrukturyzowane logowanie z obsługą sformatowanych ciągów i dynamicznym filtrowaniem przez konsolę.

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

System filtrowania OSLog działa na poziomie systemu operacyjnego. Komunikaty Debug są zapisywane tylko przy podłączonym debuggerze lub po włączeniu argumentu -com.apple.CoreData.Logging.debug 1. Komunikaty Info są gromadzone w pamięci urządzenia (do 512 KB) i dostępne przez Console.app. Error i fault są zapisywane stale i dostępne do zbierania przez systemy raportowania awarii.

Ważna cecha OSLog: sformatowane ciągi z placeholderami. Zamiast interpolacji ciągów Swift (która jest obliczana zawsze, niezależnie od poziomu), OSLog używa formatu os_log z %{public}@ i %{private}@ do rozgraniczania wrażliwych danych. Prywatne parametry są maskowane w logach produkcyjnych.

Production vs Debug: jak skonfigurować filtrowanie poziomów

Podstawowa zasada — minimalny zestaw poziomów w produkcji: Info, Warn, Error, Assert. Debug i Verbose powinny być wyłączone. Przyczyna nie leży tyle w bezpieczeństwie, co w wydajności: każde wywołanie logu zajmuje czas procesora na formatowanie ciągu, nawet jeśli komunikat nie jest wyświetlany.

Leniwc formatowanie ciągów

Krytyczna optymalizacja — nigdy nie używaj interpolacji ciągów w wywołaniach logu. Jeśli ciąg jest tworzony przed wywołaniem log(), czas procesora jest marnowany nawet przy wyłączonym poziomie. Używaj leniwego formatowania przez lambdy lub warunki ochronne.

W Androidzie temu celowi służy metoda Log.isLoggable(), w OSLog — natywna obsługa sformatowanych ciągów z placeholderami. Timber dla Androida rozwiązuje problem poprzez timber.log.Tree z sprawdzaniem poziomu wewnątrz drzewa.

Dynamiczna zmiana poziomu w locie

Remote Log Level — praktyka, w której poziom logowania jest zarządzany z serwera przez Firebase Remote Config lub podobną usługę. Jeśli w produkcji wystąpi złożony błąd, programista może zdalnie włączyć logowanie Debug dla konkretnego modułu na urządzeniach wybranej grupy użytkowników.

Według danych Firebase, 2024, taka praktyka skraca czas diagnozowania rzadkich błędów o 60% i pozwala uzyskać pełny obraz problemu bez instalowania debugowanej kompilacji. Głównym ograniczeniem jest to, że logi włączają się dopiero przy następnym uruchomieniu aplikacji po otrzymaniu konfiguracji.

Automatyczne filtrowanie według typu kompilacji

BuildConfig.DEBUG na Androidzie i #if DEBUG w Swift — standardowe mechanizmy kompilacji warunkowej, wyłączające poziomy debugowania w kompilacjach release. Dla czystej architektury zaleca się przeniesienie wyboru Log Level do kontenera DI lub fabryki loggerów, aby nie zaśmiecać logiki biznesowej dyrektywami warunkowymi.

Best practices przy wyborze poziomu logowania

Pierwsza zasada — każde wywołanie logu powinno odpowiadać na pytanie „kto, co, kiedy”. Kto — komponent lub moduł (tag na Androidzie, category na iOS). Co — konkretne zdarzenie lub zmiana stanu. Kiedy — znacznik czasu, ustawiany automatycznie przez system logowania.

Druga zasada — nie loguj wrażliwych danych przez Info i wyższe. Hasła, tokeny, emaile, numery telefonów, dokładne współrzędne geograficzne — są kategorycznie zabronione w każdym logu, który trafia do produkcji. W razie potrzeby używaj maskowania: „email: us***@example.com”.

Trzecia zasada — poziom Warn to strefa odpowiedzialności programisty, Error — zespołu. Warn oznacza „tu jest potencjalny problem, obserwuj”. Error — „tu jest problem, naprawiaj”. Nie używaj Error dla sytuacji, które są oczekiwane i obsłużone (na przykład błąd API 404).

Czwarta zasada — konsystentność. Cały projekt powinien używać jednolitych konwencji nazewnictwa tagów i kategorii. Zaleca się ClassName.methodName dla tagów Android i module.subsystem dla kategorii iOS. Pozwala to szybko filtrować logi według komponentu.

Piąta zasada — testuj logi. W testach jednostkowych sprawdzaj, czy w określonych scenariuszach wywoływany jest prawidłowy Log Level. W tym celu istnieją biblioteki mockujące logowanie: Mockito dla Androida, Cuckoo dla iOS. Sprawdzanie poziomów w testach zapobiega wyciekowi komunikatów debugowania do produkcji.

Często zadawane pytania

Co się stanie, jeśli zostawię logi Debug w produkcji?

Przyspieszone rozładowanie baterii i nadmierny zapis na dysk. Każdy log Debug formatuje ciąg i zapisuje dane do bufora. Na urządzeniach z pamięcią Flash przyspiesza to zużycie nośnika. Ponadto logi Debug mogą zawierać wrażliwe dane niedostępne do przeglądania w produkcji.

Jakiego Log Level używać do logowania żądań sieciowych?

Debug — dla treści żądania i odpowiedzi, nagłówków i kodu statusu. Info — dla faktu wykonania żądania (URL, metoda, czas trwania). Error — dla nieudanych żądań z kodem 4xx/5xx. Nigdy nie używaj Verbose dla logów sieciowych w produkcji.

Czym różni się OSLogType.default od OSLogType.info?

OSLogType.default (poziom notice) — komunikaty średniej ważności, zapisywane w logu systemowym i widoczne w Console.app. OSLogType.info — komunikaty techniczne, niezapisywane stale, dostępne tylko przy aktywnym profilowaniu przez Instruments.

Jak ProGuard obsługuje wywołania Log na Androidzie?

R8/ProGuard usuwa Log.v() i Log.d() przy włączonej minifikacji w kompilacji release. Log.i(), Log.w(), Log.e() są zachowywane. Do całkowitego usunięcia wszystkich logów wymagana jest niestandardowa reguła -assumenosideeffects class android.util.Log z określeniem wszystkich poziomów.

Czy każda metoda powinna logować swój początek i koniec?

Nie — nadmierne logowanie pogarsza czytelność i wydajność. Loguj wejście tylko w złożonych lub asynchronicznych metodach. Dla metod synchronicznych wystarczy jeden log w punkcie zwrotu lub błędu. Używaj poziomu Debug do śledzenia wywołań.

Podsumowanie

  • Log Level — skala krytyczności od Verbose do Assert, określająca widoczność każdego komunikatu logu
  • Verbose i Debug — przeznaczone do rozwoju i powinny być wyłączone w kompilacjach produkcyjnych
  • Info — kluczowe zdarzenia aplikacji, bezpieczne do analizy w produkcji
  • Warn — potencjalne problemy niewymagające natychmiastowej naprawy
  • Error — krytyczne awarie wymagające interwencji zespołu programistycznego
  • Android Log API używa tag + level, OSLog na iOS — subsystem + category + level
  • Leniwc formatowanie i kompilacja warunkowa — kluczowe techniki optymalizacji logowania w produkcji

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również