Log Level in applicatieontwikkeling: wat het is, soorten niveaus en configuratie

Auteur: IT Sectr Gepubliceerd: 2026-05-28 Leestijd: 8 min

Log Level — classificatie van logberichten op basis van kritiekheid, waarmee ontwikkelaars de hoeveelheid uitvoerinformatie in verschillende stadia van de applicatie kunnen beheersen. Volgens gegevens van Google Android Developers, 2024 vermindert de juiste keuze van het logniveau het volume van logs in productie met 85–95% en versnelt het diagnosticeren van fouten. Elk niveau lost zijn eigen taak op — van debuggen tijdens de ontwikkeling tot het monitoren van kritieke storingen in productie.

Belangrijkste punten

  • Log Level — gestandaardiseerde kritiekheidsschaal van Verbose (gedetailleerd debuggen) tot Error (kritieke storingen)
  • Verbose en Debug — niveaus voor ontwikkeling, uitgeschakeld in productiebuilds voor prestaties
  • Info — informatieve berichten over belangrijke gebeurtenissen: opstarten, autorisatie, navigatie
  • Warn — waarschuwingen over potentiële problemen die niet onmiddellijk tot een storing leiden
  • Error — kritieke fouten die onmiddellijke aandacht en analyse van de ontwikkelaar vereisen

Wat is Log Level?

Log Level — een attribuut van elk logbericht dat het belang en de urgentie van verwerking bepaalt. Moderne iOS- en Android-platforms ondersteunen een uniforme schaal van 6–7 niveaus: van maximaal gedetailleerd (Verbose/Trace) tot kritiek (Error/Assert). De keuze van het niveau bepaalt of het bericht wordt geschreven in het log bij de huidige configuratie van de applicatie.

Het concept van Log Level is gebaseerd op het principe van de kritiekheidspiramide: hoe hoger het niveau, hoe minder berichten erop worden weergegeven. Volgens gegevens van Semaphore CI, 2024 ziet de verdeling in een productieapplicatie er als volgt uit: Info — 60% berichten, Warn — 25%, Error — 10%, Debug — 5%. Verbose-berichten moeten volledig worden uitgeschakeld in productie.

Elk platform implementeert Log Level via zijn eigen API. Android gebruikt android.util.Log met methoden v(), d(), i(), w(), e(). Apple — OSLog met niveaus default, info, debug, error, fault. Bibliotheken zoals Timber en CocoaLumberjack bouwen extra functionaliteit bovenop deze standaard API's.

Volgens gegevens van Google I/O 2023 is een onjuiste keuze van Log Level de oorzaak van 40% van de prestatieproblemen in productie. Ontwikkelaars laten Debug-logs achter in de release-build, wat leidt tot overmatig schrijven naar schijf en versnelde batterijontlading.

Soorten logniveaus: van Verbose tot Assert

Verbose (TRACE) — het meest gedetailleerde niveau, uitsluitend bedoeld voor ontwikkeling. Op dit niveau worden alle tussenberekeningen, lusiteraties, resultaten van elke stap van het algoritme weergegeven. Op Android komt dit niveau overeen met Log.v(), op iOS — OSLog met type debug (vóór iOS 14 werd os_trace gebruikt).

Debug — debugberichten, nuttig tijdens ontwikkeling en testen. Bevat informatie over de status van belangrijke objecten, resultaten van SQL-query's, parameters van API-aanroepen. In tegenstelling tot Verbose zijn Debug-berichten gestructureerd en semantisch betekenisvol. Op iOS komt dit niveau overeen met OSLogType.debug.

Info — informatieve berichten over normale gebeurtenissen van de applicatie: SDK-initialisatie, succesvolle autorisatie, schermopenen, gegevensontvangst van de server. Info-berichten mogen geen persoonlijke gegevens van gebruikers bevatten en moeten veilig zijn voor productieanalyse. Op iOS wordt OSLogType.info gebruikt, op Android — Log.i().

Warn — waarschuwingen over potentiële problemen. De applicatie blijft werken, maar de situatie vereist aandacht: cachegrootte bijna op limiet, verouderde API-versie, traag netwerkantwoord, opnieuw proberen verbinding te maken. Op Android — Log.w(), op iOS — OSLogType.default (voor waarschuwingen).

Error — kritieke fouten waarbij de applicatie de gevraagde bewerking niet kan uitvoeren, maar blijft werken: mislukt API-verzoek, verbindingsverlies, schrijffout in database, ontbrekende machtigingen. Op iOS wordt voor fouten OSLogType.error gebruikt, op Android — Log.e().

Assert (WTF) — het hoogste niveau, dat een situatie „dit kan niet gebeuren” aangeeft. Wordt gebruikt voor het loggen van bugs die fundamentele invarianten van het systeem schenden. Op Android worden Assert-berichten standaard niet weergegeven in release-builds. Op iOS wordt WTF (What a Terrible Failure) verwerkt via OSLogType.fault.

Log Level gebruiken op Android

Android Log API — het ingebouwde logmechanisme uit het pakket android.util.Log. Het biedt 6 statische methoden: Log.v(), Log.d(), Log.i(), Log.w(), Log.e() en Log.wtf(). Elke methode ontvangt een tag (identificatiereeks van de bron) en msg (berichttekst).

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

    suspend fun loadUser(id: String): User {
        Log.d(TAG, "Gebruiker laden met id: $id")

        return try {
            val response = api.fetchUser(id)
            Log.i(TAG, "Gebruiker succesvol geladen")
            response.toUser()
        } catch (e: Exception) {
            Log.e(TAG, "Kan gebruiker niet laden: ${e.message}")
            throw e
        }
    }
}

Filteren op niveaus in Android Logcat gebeurt via ADB: adb logcat *:E toont alleen Error-berichten. In productiebuilds worden alle Log.v()- en Log.d()-aanroepen verwijderd door ProGuard/R8 wanneer minificatie is ingeschakeld. Log.i(), Log.w() en Log.e() blijven, dus het is belangrijk om geen gevoelige gegevens via deze methoden uit te voeren.

Voor aangepast filteren tijdens runtime biedt Android Log.isLoggable(tag, level) — een methode die controleert of het opgegeven niveau is ingeschakeld voor een bepaalde tag. Dit maakt het mogelijk om dynamisch gedetailleerde logging voor een specifieke module in te schakelen zonder de applicatie opnieuw te bouwen.

Log Level gebruiken op iOS en macOS

OSLog — het uniforme logsysteem van Apple, dat de verouderde NSLog heeft vervangen. OSLog biedt 5 niveaus: debug, info, default (notice), error en fault. Het belangrijkste voordeel is gestructureerde logging met ondersteuning voor geformatteerde strings en dynamische filtering via de console.

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

Het filtersysteem van OSLog werkt op het niveau van het besturingssysteem. Debug-berichten worden alleen geschreven wanneer de debugger is aangesloten of wanneer het argument -com.apple.CoreData.Logging.debug 1 is ingeschakeld. Info-berichten worden verzameld in het geheugen van het apparaat (tot 512 KB) en zijn toegankelijk via Console.app. Error en fault worden constant geschreven en zijn beschikbaar voor verzameling via crash-rapportagesystemen.

Een belangrijk kenmerk van OSLog: geformatteerde strings met placeholders. In plaats van stringinterpolatie van Swift (die altijd wordt berekend, ongeacht het niveau), gebruikt OSLog os_log formaat met %{public}@ en %{private}@ voor het scheiden van gevoelige gegevens. Private parameters worden gemaskeerd in productielogs.

Productie vs Debug: hoe niveaufiltering in te stellen

De basisregel — minimale set niveaus in productie: Info, Warn, Error, Assert. Debug en Verbose moeten worden uitgeschakeld. De reden is niet zozeer beveiliging, maar prestaties: elke logaanroep kost processortijd voor het formatteren van de string, zelfs als het bericht niet wordt weergegeven.

Lazy string formattering

Kritieke optimalisatie — gebruik nooit stringinterpolatie in logaanroepen. Als de string wordt gevormd vóór de log()-aanroep, wordt processortijd verspild, zelfs wanneer het niveau is uitgeschakeld. Gebruik lazy formattering via lambda's of guard-voorwaarden.

Op Android dient de methode Log.isLoggable() dit doel, in OSLog — native ondersteuning voor geformatteerde strings met placeholders. Timber voor Android lost het probleem op via timber.log.Tree met niveaucontrole binnen de boom.

Dynamisch niveau wijzigen tijdens runtime

Remote Log Level — een praktijk waarbij het logniveau wordt beheerd vanaf de server via Firebase Remote Config of een vergelijkbare service. Als er in productie een complexe fout optreedt, kan de ontwikkelaar op afstand Debug-logging inschakelen voor een specifieke module op apparaten van een geselecteerde gebruikersgroep.

Volgens gegevens van Firebase, 2024 verkort deze praktijk de diagnose tijd van zeldzame bugs met 60% en maakt het mogelijk een volledig beeld van het probleem te krijgen zonder een debug-build te installeren. De belangrijkste beperking is dat logs pas worden ingeschakeld bij de volgende start van de applicatie na ontvangst van de configuratie.

Automatisch filteren op build-type

BuildConfig.DEBUG op Android en #if DEBUG in Swift — standaard mechanismen voor voorwaardelijke compilatie die debug-niveaus uitschakelen in release-builds. Voor een schone architectuur wordt aanbevolen om de keuze van Log Level naar een DI-container of loggerfabriek te verplaatsen, om de bedrijfslogica niet te belasten met voorwaardelijke richtlijnen.

Best practices bij het kiezen van een logniveau

Eerste regel — elke logaanroep moet de vraag „wie, wat, wanneer” beantwoorden. Wie — component of module (tag op Android, category op iOS). Wat — specifieke gebeurtenis of statuswijziging. Wanneer — tijdstempel, automatisch ingesteld door het logsysteem.

Tweede regel — log geen gevoelige gegevens via Info en hoger. Wachtwoorden, tokens, e-mails, telefoonnummers, exacte geo-coördinaten — zijn ten strengste verboden in elke log die in productie terechtkomt. Gebruik indien nodig maskering: „email: us***@example.com”.

Derde regel — niveau Warn is de verantwoordelijkheidszone van de ontwikkelaar, Error — van het team. Warn betekent „hier is een potentieel probleem, houd in de gaten”. Error — „hier is een probleem, los het op”. Gebruik Error niet voor situaties die verwacht en afgehandeld zijn (bijvoorbeeld een 404 API-fout).

Vierde regel — consistentie. Het hele project moet uniforme naamgevingsconventies gebruiken voor tags en categorieën. Aanbevolen wordt ClassName.methodName voor Android-tags en module.subsystem voor iOS-categorieën. Dit maakt het mogelijk om logs snel te filteren op component.

Vijfde regel — test logs. Controleer in unit tests of in bepaalde scenario's het juiste Log Level wordt aangeroepen. Hiervoor bestaan mock-logbibliotheken: Mockito voor Android, Cuckoo voor iOS. Het controleren van niveaus in tests voorkomt dat debug-berichten in productie lekken.

Veelgestelde vragen

Wat gebeurt er als ik Debug-logs in productie laat staan?

Versnelde batterijontlading en overmatig schrijven naar schijf. Elke Debug-log formatteert de string en schrijft gegevens naar de buffer. Op apparaten met Flash-geheugen versnelt dit de slijtage van de opslag. Bovendien kunnen Debug-logs gevoelige gegevens bevatten die niet beschikbaar zijn voor weergave in productie.

Welk Log Level moet ik gebruiken voor het loggen van netwerkverzoeken?

Debug — voor de body van verzoek en antwoord, headers en statuscode. Info — voor het feit van uitvoering van het verzoek (URL, methode, duur). Error — voor mislukte verzoeken met code 4xx/5xx. Gebruik nooit Verbose voor netwerklogs in productie.

Wat is het verschil tussen OSLogType.default en OSLogType.info?

OSLogType.default (niveau notice) — berichten van gemiddeld belang, opgeslagen in het systeemlog en zichtbaar in Console.app. OSLogType.info — technische berichten, niet permanent opgeslagen, alleen beschikbaar bij actieve profilering via Instruments.

Hoe verwerkt ProGuard Log-aanroepen op Android?

R8/ProGuard verwijdert Log.v() en Log.d() wanneer minificatie is ingeschakeld in de release-build. Log.i(), Log.w(), Log.e() worden behouden. Voor volledige verwijdering van alle logs is een aangepaste regel -assumenosideeffects class android.util.Log met vermelding van alle niveaus vereist.

Moet elke methode het begin en einde loggen?

Nee — overmatige logging verslechtert de leesbaarheid en prestaties. Log de invoer alleen in complexe of asynchrone methoden. Voor synchrone methoden is één log op het punt van terugkeer of fout voldoende. Gebruik Debug-niveau voor het traceren van aanroepen.

Samenvatting

  • Log Level — kritiekheidsschaal van Verbose tot Assert, die de zichtbaarheid van elk logbericht bepaalt
  • Verbose en Debug — bedoeld voor ontwikkeling en moeten worden uitgeschakeld in productiebuilds
  • Info — belangrijke gebeurtenissen van de applicatie, veilig voor productieanalyse
  • Warn — potentiële problemen die geen onmiddellijke correctie vereisen
  • Error — kritieke storingen die interventie van het ontwikkelingsteam vereisen
  • Android Log API gebruikt tag + level, OSLog op iOS — subsystem + category + level
  • Lazy formattering en voorwaardelijke compilatie — sleuteltechnieken voor optimalisatie van logging in productie

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook