Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastering Logging in Java

Mastering Logging in Java

Logging presentation based on our Real World Java book!

Jeanne Boyarsky

March 05, 2025
Tweet

More Decks by Jeanne Boyarsky

Other Decks in Programming

Transcript

  1. https://linktr.ee/jeanneboyarsky Pause for a Commercial 2 Book giveaway at end!

    Good Java developers learn Java syntax, how to create loops and switches, and can work out a lambda filter stream. But great Java developers need to understand the vast ecosystem of tools and frameworks for collaboration, testing, building, and more. In Real-World Java®: Helping You Navigate the Java Ecosystem, a team of veteran Java developers delivers a concise and authoritative discussion of the most common frameworks, tools, and techniques used in enterprise Java development shops. The authors provide just enough background and examples to allow you to dive right into the expert guidance on annotations, logging frameworks, observability, performance tuning, testing tools, and collaboration, that real-life commercial Java development typically relies on. You’ll expand your Java development toolkit with frameworks and utilities like Spring, Git, Prometheus, and Project Lombok. You’ll also discover links to tested, downloadable code.
  2. https://linktr.ee/jeanneboyarsky Everyone’s First Java Program public class HelloWorld{ public static

    void main(String[] args){ } } System.out.println("Hello, World!");
  3. https://linktr.ee/jeanneboyarsky What’s Wrong with System.out.println?? • No control over what

    is logged in each environment. • Can’t separate audit logging, error logging, and Informational messages. • Logs from related services are only on each server. • Can’t search and filter logs. • No way to aggregate metrics from logs. • Performance impact – synchronous logging. • Output location and log rotation not configurable.
  4. https://linktr.ee/jeanneboyarsky Basic Concepts • Logging Frameworks all share these basics

    • What is a logger? • Naming loggers • Logging levels • Inheriting loggers
  5. https://linktr.ee/jeanneboyarsky ); What is a logger? private final static LOGGER

    = LoggerFactory.getLogger( com.wiley .realworldjava.MyClass.class
  6. https://linktr.ee/jeanneboyarsky Naming and Using Loggers public class MyClass { private

    final static Logger LOGGER = LoggerFactory.getLogger(com.realworldjava.MyClass.class); public static void main(String[] args) { } } LOGGER.debug(“Use to display debug messages usually in non-prod”); LOGGER.info(“This is an info level message”); LOGGER.warn(“Non-critical warnings”); LOGGER.error(“Critical error messages”); com.realworldjava.MyClass.class
  7. https://linktr.ee/jeanneboyarsky Logging levels • TRACE – Very detailed debugging •

    DEBUG – For diagnosing issues in development • INFO – General operational information • WARN – For non-critical unexpected conditions • ERROR – Systemic operational failures • FATAL – Catastrophic failures
  8. https://linktr.ee/jeanneboyarsky Setting logging levels # Set root logging level logging.level.root=WARN

    # Override specific loggers logging.level.com.wiley.realworldjava=INFO # Override inheritance logging.level.com. wiley. realworldjava.util=DEBUG
  9. https://linktr.ee/jeanneboyarsky Java Util Logging import java.util.logging.Logger; public class BasicConfigCommandLine {

    private static final Logger LOGGER = Logger.getLogger( BasicConfigCommandLine.class.getName()); public static void main(String[] args) { LOGGER.severe("this is bad"); LOGGER.warning("be careful"); LOGGER.info("just to let you know"); } }
  10. https://linktr.ee/jeanneboyarsky Java Util Logging public static void main(String[] args) {

    LOGGER.fine(() -> generateMessage()); } private static String generateMessage() { return "This is an expensive message"; }
  11. https://linktr.ee/jeanneboyarsky A Trip Down Memory Lane public static void main(String[]

    args) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(generateMessage()); } } private static String generateMessage() { return "This is an expensive message"; }
  12. https://linktr.ee/jeanneboyarsky Java Util Logging .level= WARNING handlers=java.util.logging.FileHandler java.util.logging.FileHandler.pattern = java-log.log

    java.util.logging.FileHandler.limit = 100000 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format= DATE=%1$tc, MESSAGE=%5$s%n
  13. https://linktr.ee/jeanneboyarsky Log4J • One of the oldest logging frameworks •

    More powerful than built in Java Util Logging Jars • log4j-api – API • log4j-core – implementation • + others based on needs (ex: yaml input, specialized output formats)
  14. https://linktr.ee/jeanneboyarsky Log4J import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class BasicLogging {

    private static final Logger LOGGER = LogManager.getLogger(); public static void main(String[] args) { LOGGER.fatal("this is bad"); } }
  15. https://linktr.ee/jeanneboyarsky Log4J private static final Logger LOGGER = LogManager.getLogger( LoggingWithParameters.class.getName());

    private static final Logger FORMATTER_LOGGER = LogManager.getFormatterLogger( LoggingWithParameters.class.getName()); public static void main(String[] args) { LOGGER.fatal("{}: {} is {}/{}", "Division", 1.5, 3, 2); FORMATTER_LOGGER.fatal( "%s: %.1f is %d/%d", "Division", 1.5, 3, 2); } }
  16. https://linktr.ee/jeanneboyarsky Log4J appenders = console rootLogger.level = error rootLogger.appenderRefs =

    stdout rootLogger.appenderRef.stdout.ref = STDOUT logger.book.name=com.wiley.realworldjava logger.book.level=INFO logger.book.appenderRefs = stdout logger.book.appenderRef.stdout.ref = STDOUT logger.book.additivity = false appender.console.type = Console appender.console.name = STDOUT appender.console.layout.type = PatternLayout appender.console.layout.pattern = %m%n
  17. https://linktr.ee/jeanneboyarsky Log4J <?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp"> <Appenders> <RollingFile

    name="RollingFile" fileName="java-log.log" filePattern="java-log-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout><Pattern>%m%n</Pattern></PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="1 MB" /> </Policies> <DefaultRolloverStrategy max="3"/> </RollingFile> </Appenders> <Loggers> <Root level="error"><AppenderRef ref="RollingFile"/></Root> </Loggers> </Configuration>
  18. https://linktr.ee/jeanneboyarsky Log4J Configuration: status: warn appenders: Console: name: STDOUT target:

    SYSTEM_OUT PatternLayout: Pattern: "%m%n" Loggers: Root: level: error AppenderRef: ref: STDOUT
  19. https://linktr.ee/jeanneboyarsky SLF4J • Simple Logging Façade for Java • Common

    API so easy to switch actual loggers Jars • slf4j-api – API • Your choice of implementation – slf4j-simple - Log4j - Logback - etc
  20. https://linktr.ee/jeanneboyarsky SLF4J import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger

    LOGGER = LoggerFactory.getLogger( Slf4jWithParameters.class); public static void main(String[] args) { LOGGER.error("{}: {} is {}/{}", "Division", 1.5, 3, 2); LOGGER.error(String.format( "%s: %.1f is %d/%d", "Division", 1.5, 3, 2)); }
  21. https://linktr.ee/jeanneboyarsky Logback • Uses SLF4J API • Same founder as

    SLF4J Jars • logback-core – logging • logback-classic – additions including SLF4J provider
  22. https://linktr.ee/jeanneboyarsky Logback import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BasicLogging {

    private static final Logger LOGGER = LoggerFactory.getLogger(BasicLogging.class); public static void main(String[] args) { LOGGER.info("just to let you know"); } }
  23. https://linktr.ee/jeanneboyarsky Logback <configuration> <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>java-log.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>java-log-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>

    <maxFileSize>10KB</maxFileSize> <maxHistory>3</maxHistory> <totalSizeCap>2GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="ROLLING" /> </root> </configuration>
  24. https://linktr.ee/jeanneboyarsky Binding Platform Conflict [INFO] Running com.wiley.realworldjava.loggingconflict.LoggingconflictApplicationTests SLF4J(W): Class path

    contains multiple SLF4J providers. SLF4J(W): SLF4J(W): SLF4J(W): See https://www.slf4j.org/codes.html#multiple_bindings for an explanation. Found provider [org.slf4j.reload4j.Reload4jServiceProvider@31f9b85e] Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider@424e17]
  25. https://linktr.ee/jeanneboyarsky When is Log4J 3 Coming Out? • June 2023:

    Alpha1 • Dec 2023: Beta 1 • Feb 2024: Beta 2 • Nov 2024: Beta 3 • Now: in consensus building phase for release • Delays due to volunteer time and needing 2.24 release • Updates at: https://github.com/apache/logging- log4j2/discussions/2128
  26. https://linktr.ee/jeanneboyarsky Introducing Log4J 3 import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class

    BasicLogging { private static final Logger LOGGER = LogManager.getLogger(); public static void main(String[] args) { LOGGER.fatal("this is bad"); } }
  27. https://linktr.ee/jeanneboyarsky Wait. That looks the Same! • More than backward

    compatible. • API is 2.24 one BOM contains • 2.24 API • 3.0 implementation
  28. https://linktr.ee/jeanneboyarsky Log4J 3: Modules • Smaller core artifact • Less

    common functionality in separate jars (ex: logging bridges for other frameworks, yaml config, etc) • Deprecated code removed • Obsolete code removed (ex: bridge to Log4J 1.X, old Jetty, etc)
  29. https://linktr.ee/jeanneboyarsky Log4J 3: Dependencies • Updated dependencies • No optional

    dependencies • Upgrade your log4j dependency and get third party library automatically
  30. https://linktr.ee/jeanneboyarsky Log4J 3: Properties User facing (wait for examples; didn’t

    work for Jeanne) • Java properties config can use Jackson data format Integration facing • Configurations of internals all changed (ex: log4j2.xxx) All properties backward compatible Appenders.Console.name = CONSOLE Loggers.Root.level = INFO Loggers.Root.AppenderRef.ref = CONSOLE Appenders.Console.name = CONSOLE Loggers.Root.level = INFO Loggers.Root.AppenderRef.ref = CONSOLE
  31. https://linktr.ee/jeanneboyarsky Distributed Logging • Modern applications are microservices based •

    Challenge locating offending service when things break • Logs contain valuable metrics • How to coordinate log messages across service calls? Micrometer Tracing
  32. https://linktr.ee/jeanneboyarsky Elasticsearch –ELK/ Elastic Stack • Elasticsearch – Logging engine

    • Logstash – Log forwarder –Extract, Transform, and Load pipeline for Elasticsearch and other platforms • Kibana – Metrics visualizations – displays charts, tables, maps etc. • Beats - Filebeat, Metricbeat, Packetbeat, Auditbeat, Heartbeat, Winlogbeat
  33. https://linktr.ee/jeanneboyarsky Micrometer Tracing • Critical for problem resolution • Injects

    a trace id into every incoming and outgoing request • Automatically logs the trace id in every log message <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-otel<artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> Logging level Trace ID placeholder
  34. https://linktr.ee/jeanneboyarsky AI Analysis Free ChatGpt (short log snippet) Log Summary:

    This log captures web server requests on February 16, 2025, primarily related to the Coderanch website. Below are the key observations:
  35. https://linktr.ee/jeanneboyarsky AI Analysis •HTTP Status Codes: •503 (Service Unavailable): Several

    requests received this status, indicating possible server overload or maintenance. These include requests for Java-related topics and forum pages. •200 (OK): Some requests were successful, such as accessing discussions about MySQL with JSTL, Java slot machines, and thread-related questions. •301 (Redirect): Internal monitoring requests (from 192.168.30.240) were redirected, suggesting a monitoring system in place.
  36. https://linktr.ee/jeanneboyarsky AI Analysis •Frequent Visitors: •192.168.30.240 made multiple monitoring requests

    at regular intervals, likely an internal server health check. •Various IPs from different regions accessed the site using Chrome browsers. •Common Accessed Topics: •Java programming discussions (Generic Java, MySQL-JSTL connection issues, slot machine creation, JSTL tags, threading). •Forum similarity searches, looking for related discussions. •Monitoring endpoints, possibly for uptime tracking.
  37. https://linktr.ee/jeanneboyarsky AI Analysis •Potential Issues: •High frequency of 503 errors

    might indicate server instability or excessive traffic. •Internal monitoring is functioning, but repeated redirects might need review.
  38. https://linktr.ee/jeanneboyarsky Commercial Tools Capabilities • Monitoring • Alerting • Visualization

    • AI/Anomaly detection Examples • DataDog • GrayLog • SemaText
  39. https://linktr.ee/jeanneboyarsky Java 9 Platform Logging API • For system logging

    (ex: inside JDK) • When can’t have any dependencies (not even java.util) • Does not replace application logging • System.getLogger()