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.
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.
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
DEBUG – For diagnosing issues in development • INFO – General operational information • WARN – For non-critical unexpected conditions • ERROR – Systemic operational failures • FATAL – Catastrophic failures
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"); } }
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)
private static final Logger LOGGER = LoggerFactory.getLogger(BasicLogging.class); public static void main(String[] args) { LOGGER.info("just to let you know"); } }
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]
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
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)
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
Challenge locating offending service when things break • Logs contain valuable metrics • How to coordinate log messages across service calls? Micrometer Tracing
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
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.
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.