Observability Landscape in Java

Vipin Menon

Introduction

Java has become a well-established and widely adopted language. As software systems became more complex with the shift to microservices, Java observability tools evolved to meet new demands. It has evolved to address these new challenges, offering improved capabilities for monitoring, tracing, and debugging. This article explores the evolution of Java observability and its adaptation to modern cloud-native solutions. Lets discuss how they have shaped into the landscape of observability in Java applications today.

First Generation: Standard debugging

When Java was first released in 1995 the tools for observing and debugging applications were minimal. The developers could only rely on standard system calls, debugging tools, and performance monitoring frameworks.

Standard Output

The most straightforward way to check what was happening inside a Java application was using System.out.println. The concept was simple to implement and understand.

class Demo {
    public static void main(String[] args)
    {
        System.out.println("Welcome to JavaPro");
    }
}
$java Demo
Welcome to JavaPro

It quickly became impractical for larger applications or production systems. It made the code messy and hard to maintain.

Java’s exception-handling mechanism which automatically generates stack traces when exceptions occur, was a key feature of the language from the very beginning. When a Java application throws an exception, the Java Virtual Machine (JVM) generates a stack trace that provides a detailed report of the method calls leading up to the exception, including the exact line numbers where the error occurred. This was a significant advantage over many other programming languages at the time, as it allowed developers to easily trace the root cause of errors without needing to manually track down the source of the issue.

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Demo.main(Demo.java:5)

This don’t provide real-time insights and was not sufficient for monitoring complex systems.

Logging

Logging in Java was first introduced with the inclusion of the java.util.logging package. The primary goal of java.util.logging was to allow developers to log messages at different levels (INFO, WARNING, ERROR) and to control the output such as to the console or to log files.

Mar 09, 2025 8:26:13 PM Demo main
INFO: This is an INFO message
Mar 09, 2025 8:26:13 PM Demo main
SEVERE: This is a SEVERE message 

At this stage, developers primarily write text-based logs to trace the application state and errors manually. Hence, the external libraries like Log4j, SLF4J, and Logback became more popular due to their enhanced features and flexibility.

Profilers

a). jstat (JVM Statistics Monitoring Tool)

This tool provides users real-time JVM statictics. It collects various performance metrics like GC, memory usage and class loading.

# Usage:
# JIT compiler performance 
# jstat -compiler <process id> <interval>
#
% jstat -compiler 95150 10000
Compiled Failed Invalid   Time   FailedType FailedMethod
    3449      1       0     1.44          1 jdk/nio/zipfs/ZipFileSystem iteratorOf
b). jstack (Java Stack Trace Tool)

jstack extracts thread dumps from a running JVM. It helped in diagnosing issues like deadlocks, blocked and long-running methods in a multi-threaded application.

# Usage:
# thread dump of a running process compiler performance 
# jstack <process id>

% jstack 95150
Full thread dump OpenJDK 64-Bit Server VM (21.0.3+9-LTS mixed mode, sharing):
..
}

"main" #1 [8451] prio=5 os_prio=31 cpu=206.64ms elapsed=12808.27s 
   ..
	at java.util.concurrent.locks.LockSupport.park(java.base@21.0.3/LockSupport.java:221)

c). jinfo

jinfo provides information about the JVM configuration and runtime environment.

# Usage:
# Display JVM Properties
# jinfo <process id>

% jinfo 95150 
Java System Properties:
file.separator=/
...
java.vm.specification.name=Java Virtual Machine Specification
..
path.separator=\:
stdout.encoding=UTF-8

These builtin tools were very handy and useful in basic monitoring and troubleshooting. However, they had limitations when it comes to complex applications.

Second Generation: Focused on Production

The second generation built-in observability tools in Java typically refers to tools that offer more advanced features and improved monitoring capabilities compared to the first. These tools are more focused on performance analysis, real-time monitoring, diagnostics and profiling with enhanced capabilities for production environments.

a). jconsole:

jconsole provides information about performance and resource consumption of applications running on a JVM. It complies to the JMX specification. You can connect to either a local or remote process. It helps capture memory monitoring, thread monitoring and information about registered mbeans.

# jconsole usage
# jconsole <process id>
# jconsole 95150
jconsole window that showcase jvm performance metrics
b). jvisualVM

jvisualVM provides a more detailed analytics on JVMs internal behavior and can event detect memory leaks by providing an extensive analysis on heap. JVisualVM is no longer comes with the standard JVM installation and comes separate.

Visual VM JVM performance metrics window.
c). Java Flight Recorder

Java Flight Recorder is a tool that is capable of collecting both diagnostic and profiling data from a running java application. It has low performance overhead. It can collect data on events, and is even capable of providing black box analysis.

% java -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=myrecording.jfr Demo
OpenJDK 64-Bit Server VM warning: Option FlightRecorder was deprecated in version 13.0 and will likely be removed in a future release.
[0.190s][info][jfr,startup] Started recording 1. The result will be written to:
[0.190s][info][jfr,startup] 
[0.190s][info][jfr,startup] /Users/vipinmenon/Downloads/myrecording.jfr
The application is running. Press Ctrl+C to stop.


Third Generation: Cloud Native Observability

The rise of cloud-native architectures, containerization, and orchestration has marked the last decade. These technologies introduced new complexities into Java application observability. Developers required a more dynamic and decentralized approach to keep up, even though the inbuilt tools remained useful. This led to the rise of modern APM tools like Instana, DynaTrace and New Relic that could automatically instrument java applications to track their performance.

Distributed tracing was another revolutionary approach, enabling the correlation of logs, metrics, and traces across distributed systems. Consequently, this provided deeper insights into application health, performance and improved troubleshooting capabilities.

Modern tracing also introduced an open source framework for collecting, processing and exporting telemetry data including logs, metrics and traces. OpenTelemetry’s Java SDK allows developers to easily instrument their applications for distributed tracing and metrics collection. This has made observability more standardized, simplifying the process of collecting telemetry data from Java applications running in cloud-native environments.

A Java agent attaches itself to any Java application and automatically collects the data without requiring any code changes to the application. Below steps demonstrates the configuration of open telemetry java agent.

  1. Download the open telemetry java agent.
Download the open telemetry java agent.

2. Set the agent and environment variables.

 Set the agent and environment variables.

3. Start the application

Start the sample application

4. Visualize the open telemetry traces from your application

Visualize the open telemetry traces from your application

Open telemetry is introduced to standardize the traces logs. This means it can be fed into any monitoring tools like Instana, dynatrace which is capable of providing a visualization experience with it along with the performance metrics on a single pane of glass.

Observability Instana backend server visualises open telemetry traces.

Since the data format will remain consistent, any tool that supports OpenTelemetry will be able to read and visualize the data. As a result, this interoperability ensures seamless integration across various observability platforms and prevents vendor locking.

The Future of Observability in Java

As Java applications continue to evolve in the cloud-native era several emerging trends are expected to shape the next phase of observability

AIOps (Artificial Intelligence for IT Operations) is making its way into observability. It can analyze telemetry data to detect anomalies, predict failures, and automatically trigger responses to potential issues.

Observability tools integrated with AI could provide insights directly to developers through chat interfaces allowing developers to fix problems in real time.

Machine learning models could always bring concerns with potential risk to data privacy and security. While these trends are expected to grow and bring more convenience, it is crucial to ensure that we collect only the relevant information. Moreover, we must focus on extracting the maximum throughput from the data gathered.

Conclusion

Java observability has come a long way since its inception, and its evolution truly reflects the spirit of enhancing system reliability, performance, and continuous improvement. As cloud-native technologies evolve, Java’s observability tools are likely to continue innovating. This ongoing progress will further empower developers to maintain robust, performant, and reliable applications in an increasingly complex world. The future of Java observability is exciting, with AI, machine learning, and predictive analytics shaping the next generation of monitoring tools. These innovations will empower developers to maintain robust, performant, and reliable applications, ultimately ensuring that Java remains a vital part of the software ecosystem for years to come.

Total
0
Shares
Previous Post

Breakpoints – The Lifeline of Debugging – An Eclipse Features Guide

Next Post
SoftwareArchitectureStyles

Demystifying Software Architecture: Styles/Patterns – PART 1

Related Posts