0Pricing
Java Academy · Lesson

SLF4J Facade and Loggers

Log at the right level.

SLF4J Facade and Loggers is a free Java Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is SLF4J?

SLF4J (Simple Logging Facade for Java) is an abstraction. You code against its API, and a backend like Logback or Log4j2 does the actual logging.

This lets libraries log without forcing a specific implementation on the application.

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("Application started");
    }
}

Getting a Logger

Create one logger per class with LoggerFactory.getLogger(MyClass.class).

By convention the field is private static final and named log or logger. The class becomes the logger's name, which appears in output.

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

public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    void placeOrder(String id) {
        log.info("Placing order {}", id);
    }
}

The Five Levels

SLF4J loggers expose one method per level:

  • log.trace(...)
  • log.debug(...)
  • log.info(...)
  • log.warn(...)
  • log.error(...)
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.trace("entering main");
        log.debug("args length = {}", args.length);
        log.info("service is up");
        log.warn("cache miss");
        log.error("failed to connect");
    }
}

Choosing the Right Level

Guidelines:

  • ERROR: a real failure a human must look at.
  • WARN: a recoverable anomaly.
  • INFO: significant lifecycle events.
  • DEBUG: developer diagnostics, off in production.
  • TRACE: extremely verbose tracing.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PaymentService {
    private static final Logger log = LoggerFactory.getLogger(PaymentService.class);
    void charge(int cents) {
        if (cents <= 0) { log.warn("non-positive charge: {}", cents); return; }
        log.info("charged {} cents", cents);
    }
}

Logger Names and Hierarchy

Logger names are hierarchical by dot-separated package. A logger named com.example.svc is a child of com.example.

Configuration on a parent applies to children unless overridden, so you can set levels per package.

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

public class Main {
    public static void main(String[] args) {
        Logger a = LoggerFactory.getLogger("com.example.app");
        Logger b = LoggerFactory.getLogger("com.example.app.db");
        a.info("parent logger");
        b.debug("child inherits parent's level unless overridden");
    }
}

Guarding Expensive Calls

For costly message construction, guard with isDebugEnabled() so the work runs only when the level is active.

With parameterized logging (next lesson) you rarely need this, but it is essential when building strings yourself.

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

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String heavyDump() { return "...large state..."; }
    public static void main(String[] args) {
        if (log.isDebugEnabled()) {
            log.debug("state: {}", heavyDump());
        }
    }
}

Logging Exceptions

To log an exception with its full stack trace, pass the Throwable as the last argument.

Do not put the exception in a placeholder; pass it after the message.

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) {
        try {
            throw new IllegalStateException("boom");
        } catch (Exception e) {
            log.error("Operation failed for id {}", 42, e);
        }
    }
}

One Logger Per Class

Declare the logger once as a static final field. Never create a logger inside a method, which wastes work and loses the class name benefit.

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

public class UserRepository {
    // Good: one shared logger named after the class
    private static final Logger log = LoggerFactory.getLogger(UserRepository.class);
    void save(String user) { log.debug("saving {}", user); }
}

SLF4J vs the Backend

SLF4J is just the API. At runtime it binds to whatever backend is on the classpath.

  • Add logback-classic: SLF4J uses Logback.
  • Add log4j-slf4j2-impl: SLF4J uses Log4j2.

Your code never changes.

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) {
        // Same code, different backend depending on classpath
        log.info("backend-agnostic logging");
    }
}

Avoid Logging Sensitive Data

Never log passwords, tokens, or full credit card numbers. Logs are often shipped to many systems and retained for a long time.

Mask or omit sensitive fields before logging.

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

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String mask(String card) { return "****" + card.substring(card.length() - 4); }
    public static void main(String[] args) {
        log.info("charged card {}", mask("4111111111111234"));
    }
}

A Realistic Service

Putting it together: a small service logging at appropriate levels with an exception path.

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

public class EmailService {
    private static final Logger log = LoggerFactory.getLogger(EmailService.class);
    void send(String to) {
        log.debug("preparing email to {}", to);
        try {
            if (to == null) throw new IllegalArgumentException("null recipient");
            log.info("email sent to {}", to);
        } catch (Exception e) {
            log.error("failed to send email", e);
        }
    }
}

Quick Check

Test your SLF4J basics.

Recap

You learned the SLF4J facade:

  • Get one private static final Logger per class.
  • Use the five level methods appropriately.
  • Logger names are hierarchical for per-package control.
  • Pass a Throwable last to log stack traces; never log secrets.

Next, efficient parameterized messages.

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("SLF4J facade recap complete");
    }
}

Frequently asked questions

Is the “SLF4J Facade and Loggers” lesson free?

Yes — the full text of “SLF4J Facade and Loggers” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.

What will I learn in “SLF4J Facade and Loggers”?

Log at the right level. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Java Academy?

No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “SLF4J Facade and Loggers” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Java Academy lesson?

Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Why Structured Logging
  2. SLF4J Facade and Loggers
  3. Parameterized Logging
  4. Configuring Logback
← Back to Java Academy