Journalisation dans les applications Kotlin : bonnes pratiques
La journalisation ne consiste pas seulement à écrire des messages dans la console. Dans les applications Kotlin modernes (d'Android au backend avec Ktor ou Spring Boot), les journaux deviennent la principale source d'informations pour le débogage, la surveillance et l'audit. Une journalisation mal configurée peut entraîner une perte de données critiques ou, à l'inverse, un remplissage du disque. Dans cet article, nous allons examiner les bonnes pratiques de journalisation en Kotlin, passer en revue les bibliothèques populaires et montrer des exemples de code.
1. Choix d'une bibliothèque de journalisation en Kotlin
Kotlin est entièrement compatible avec l'écosystème Java, vous pouvez donc utiliser n'importe quelle bibliothèque Java pour la journalisation. Cependant, il existe également des wrappers spécifiques à Kotlin qui rendent le code plus idiomatique.
- SLF4J (Simple Logging Facade for Java) — une façade qui permet de connecter différentes implémentations (Logback, Log4j2, java.util.logging). C'est la norme de facto dans le monde Java.
- Logback — l'implémentation SLF4J la plus populaire. Rapide, flexible, avec prise en charge de la journalisation asynchrone.
- kotlin-logging — un wrapper léger pour SLF4J, utilisant les fonctionnalités de Kotlin (fonctions inline, lambdas). Permet d'écrire du code dans le style
logger.debug { "Message" }.
Stack recommandé pour un nouveau projet : SLF4J + Logback + kotlin-logging. Exemple d'ajout dans build.gradle.kts :
dependencies { implementation("ch.qos.logback:logback-classic:1.4.14") implementation("io.github.microutils:kotlin-logging-jvm:3.0.5")}2. Niveaux de journalisation appropriés
Utiliser le bon niveau est la base d'une bonne journalisation. SLF4J propose 5 niveaux (par ordre croissant de gravité) : TRACE, DEBUG, INFO, WARN, ERROR.
- TRACE — informations très détaillées pour le débogage (entrée/sortie des méthodes, valeurs des variables). Activez uniquement en environnement de développement.
- DEBUG — informations utiles pour le développeur (état du système, calculs intermédiaires).
- INFO — événements importants du fonctionnement de l'application (démarrage, traitement d'une requête, connexion à la base de données).
- WARN — situations potentiellement dangereuses (erreurs non critiques, API obsolètes).
- ERROR — erreurs nécessitant une intervention (exceptions, échecs de la logique métier).
Exemple d'utilisation avec kotlin-logging :
import mu.KotlinLogging
private val logger = KotlinLogging.logger {}
fun processOrder(orderId: String) { logger.info { "Début du traitement de la commande $orderId" } try { // logique métier logger.debug { "Commande $orderId : montant = $amount" } } catch (e: Exception) { logger.error(e) { "Erreur lors du traitement de la commande $orderId" } }}Important : Évitez d'utiliser logger.info("Chaîne " + variable) — cela crée une chaîne même si le niveau n'est pas activé. Utilisez les lambdas : logger.info { "Chaîne $variable" }.
3. Journalisation structurée (Structured Logging)
Les journaux textuels sont difficiles à analyser. Il est préférable d'utiliser des formats structurés (JSON, Logstash) qui permettent aux machines d'analyser facilement les données. C'est particulièrement important pour l'architecture de microservices et les systèmes de collecte centralisée de journaux (ELK, Grafana Loki).
Dans Logback, pour le format JSON, on utilise la bibliothèque logstash-logback-encoder :
// build.gradle.ktsimplementation("net.logstash.logback:logstash-logback-encoder:7.4")Configuration de logback.xml :
<configuration> <appender name="JSON" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LogstashEncoder"/> </appender>
<root leve