Java Academy · Les

Logging met parameters

Efficiënte opmaak van berichten

Les 3 van 413 stappen

Logging met parameters is een gratis Java Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.

Het probleem met tekenreeksconcatenatie

Bij het samenvoegen van een logboekbericht wordt de volledige tekenreeks vóór de aanroep opgebouwd, zelfs als het niveau is uitgeschakeld.

log.debug("id=" + id + " name=" + name) verspilt CPU-tijd wanneer DEBUG is uitgeschakeld, omdat de tekenreeks toch wordt opgebouwd.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Bad: string is built even if DEBUG is disabled
        log.debug("id=" + id + " name=" + name);
    }
}

Tijdelijke aanduidingen met {}

SLF4J gebruikt {} als tijdelijke aanduiding. Geef de waarden door als extra argumenten.

Het bericht wordt alleen samengesteld als het niveau is ingeschakeld, waardoor uitgeschakelde logboekberichten vrijwel niets kosten.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Good: no string built unless DEBUG is on
        log.debug("id={} name={}", id, name);
    }
}

Meerdere tijdelijke aanduidingen

Tijdelijke aanduidingen worden op volgorde ingevuld. De eerste {} krijgt het eerste argument, de tweede krijgt het tweede argument, enzovoort.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("order {} for user {} totaling {} cents", "A-1", 42, 1599);
    }
}

Waarom dit efficiënt is

Het raamwerk controleert eerst het niveau. Als dat is uitgeschakeld, keert het onmiddellijk terug zonder toString() voor een argument aan te roepen.

Het kostbare deel, de opmaak, gebeurt pas wanneer het bericht daadwerkelijk wordt uitgevoerd.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String describe(Object o) { System.out.println("toString called"); return o.toString(); }
    public static void main(String[] args) {
        // Note: passing describe(...) still evaluates eagerly; pass the raw object instead
        log.trace("value={}", new int[]{1, 2, 3});
    }
}

Geef onbewerkte objecten door, geen vooraf opgemaakte tekenreeksen

Geef voor het voordeel van uitgestelde verwerking het onbewerkte object door, niet een methodeaanroep die het object opmaakt.

Als je log.debug("{}", buildReport()) schrijft, wordt buildReport() nog steeds meteen uitgevoerd. Geef argumenten door die de logger zelf kan opmaken.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        Object user = new Object();
        // Logger calls user.toString() only if DEBUG is enabled
        log.debug("current user: {}", user);
    }
}

Uitgestelde leveranciers voor zwaar werk

Gebruik bij echt kostbare opmaak de fluent API van SLF4J 2.x met een Supplier, zodat het werk wordt uitgesteld.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String heavyReport() { return "...expensive..."; }
    public static void main(String[] args) {
        log.atDebug()
           .setMessage("report: {}")
           .addArgument(() -> heavyReport())
           .log();
    }
}

Een letterlijk accoladeteken escapen

Als je een letterlijk {} in het bericht nodig hebt, escapen je dit met een backslash: \\{}.

Dit komt zelden voor, maar is nuttig bij het registreren van tekst die op JSON lijkt.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Logs a literal {} then the value
        log.info("empty object is \\{} and id is {}", 7);
    }
}

Uitzondering plus tijdelijke aanduidingen

Je kunt tijdelijke aanduidingen combineren met een uitzondering aan het einde. SLF4J detecteert dat het laatste argument een Throwable is en drukt de stacktrace ervan af.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        int id = 99;
        try {
            throw new RuntimeException("db down");
        } catch (Exception e) {
            log.error("failed processing record {}", id, e);
        }
    }
}

Vermijd te veel argumenten

Als het aantal tijdelijke aanduidingen niet overeenkomt met het aantal argumenten, doet SLF4J zijn best, maar kan de uitvoer er verkeerd uitzien.

Houd ze gelijk. Overweeg bij meer dan een paar waarden gestructureerde context (MDC) te gebruiken.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Two placeholders, two arguments: correct
        log.info("user {} did {}", "ada", "login");
    }
}

Context toevoegen met MDC

Zet waarden die in veel regels worden gedeeld, zoals een aanvraag-ID, in de MDC in plaats van in elk bericht.

De patroonindeling kan de MDC-waarde vervolgens automatisch op elke regel afdrukken.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        MDC.put("requestId", "req-1234");
        try {
            log.info("handling request");
            log.info("request done");
        } finally {
            MDC.clear();
        }
    }
}

Samenvatting van aanbevolen werkwijzen

Regels voor efficiënte logboekregistratie:

  • Gebruik altijd tijdelijke aanduidingen met {}, nooit concatenatie met +.
  • Geef onbewerkte objecten door, geen vooraf opgebouwde tekenreeksen.
  • Gebruik leveranciers of isXEnabled() voor echt zwaar werk.
  • Gebruik MDC voor dwarsdoorsnijdende context.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("processed {} items in {} ms", 1000, 42);
    }
}

Korte controle

Controleer je kennis van logboekregistratie met parameters.

Samenvatting

Je hebt logboekregistratie met parameters geleerd:

  • Gebruik tijdelijke aanduidingen met {} en extra argumenten.
  • Berichten worden uitgesteld opgebouwd, alleen wanneer het niveau is ingeschakeld.
  • Geef onbewerkte objecten door en gebruik leveranciers voor zwaar werk.
  • Gebruik MDC voor gedeelde contextwaarden.

Hierna behandel je de configuratie van het achterliggende systeem Logback.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("Parameterized logging recap: {}", "done");
    }
}
Gratis beginnen

Leer Java met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
104
Lessen
374

Veelgestelde vragen

Is de les “Logging met parameters” gratis?

Ja — de volledige tekst van “Logging met parameters” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.

Wat leer ik in “Logging met parameters”?

Efficiënte opmaak van berichten Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Java Academy te beginnen?

Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Logging met parameters”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Java Academy?

Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Waarom structured logging
  2. SLF4J-facade en loggers
  3. Logging met parameters
  4. Logback configureren
← Terug naar Java Academy