Make Your Logs Work for You

The days of logging in to servers and manually viewing log files are over. SolarWinds® Papertrail™ aggregates logs from applications, devices, and platforms to a central location.

View Technology Info

FEATURED TECHNOLOGY

Troubleshoot Fast and Enjoy It

SolarWinds® Papertrail™ provides cloud-based log management that seamlessly aggregates logs from applications, servers, network devices, services, platforms, and much more.

View Capabilities Info

FEATURED CAPABILITIES

Aggregate and Search Any Log

SolarWinds® Papertrail™ provides lightning-fast search, live tail, flexible system groups, team-wide access, and integration with popular communications platforms like PagerDuty and Slack to help you quickly track down customer problems, debug app requests, or troubleshoot slow database queries.

View Languages Info

FEATURED LANGUAGES

TBD - APM Integration Title

TBD - APM Integration Description

TBD Link

APM Integration Feature List

TBD - Built for Collaboration Title

TBD - Built for Collaboration Description

TBD Link

Built for Collaboration Feature List

Tips from the Team

Logging in Java – Best Practices and Tips

START FREE TRIAL

Fully Functional for 30 Days

Last updated: October 2025

Robust application logging is central to any quality strategy. Unfortunately, many quality strategies fall short, implementing logging in a less-than-stellar way. Java application logging is no different. And since we’re discussing one of the most popular programming languages, investments in enhancing the overall Java logging strategy could yield significant dividends in the future.

I wrote this to share what I have learned about logging in Java and how to do it better. I’ll walk you through a list of tips you can start applying today. Some of them will be specific to Java; others will also apply to other tech stacks. After reading, you should be ready to take your logging approach to the next level.

Employ a Logging Framework

I know it’s obvious, but I had to put this on my list. The reason is simple: many people still roll out their homegrown Java logging solutions, and most regret it later.

Even though logging might look like just a matter of recording some text to a destination, there’s much more to it than that. A robust logging approach includes:

  • Properly formatting log messages
  • Handling concurrent access to log files
  • Writing logs to alternate destinations, depending on log level or other criteria
  • Configuring all of this, without needing to alter the code

When you adopt a logging framework, you get all of the above—and more—in a nicely packaged, ready-to-use unit—and most of the time it’s free.

One of the most popular solutions for the Java world is the Apache Log4j2 framework. Maintained by the Apache Foundation, Log4j2 is an improvement on the original Log4j, which was the most popular logging framework in Java for many years. Log4j2 introduces new features, addresses existing issues, and provides an API decoupled from the implementation. This ensures the framework will constantly evolve in a compatible manner, but it also allows the use of other logging frameworks, as long as they adhere to the API contracts.

Use the Proper Log Levels

Logging levels are labels you can attach to each log entry to indicate its severity. Java’s built-in logging framework (java.util.logging) comes with predefined levels—SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST—each serving a specific logging verbosity need​. These are the standard log levels defined by the Java framework. Adding appropriate log levels to messages is essential if you want to make sense of them.

Log4j2, besides supporting standard log levels, also offers custom ones:

LevelValueDescription
OFF0No logging
FATAL100The application is unusable. Action needs to be taken immediately.
ERROR200An error occurred in the application.
WARN300Something unexpected—though not necessarily an error—has happened and needs to be monitored.
INFO400A normal, expected, relevant event occurred.
DEBUG500Used for debugging purposes
TRACE600Used for debugging purposes—includes the most detailed information

Below is a comparison of the Java standard log levels and Log4j2 log levels:

Aspect Java Logging Levels Log4j2 Logging Levels 
Number of Levels 
Highest Severity SEVERE FATAL 
Lowest Severity FINEST TRACE 
Intermediate Levels WARNING, INFO, CONFIG, FINE, FINER ERROR, WARN, INFO, DEBUG 
Customizability No Yes, supports custom log levels 
System Integration Handlers for different outputs Appenders for different outputs 
Configuration Defined in logging.properties Defined in XML, JSON, or properties file 
Community Adoption Less commonly used Widely adopted in the Java community 
Performance Impact Generally lower performance Generally, higher performance due to asynchronous logging 
Exception Handling Limited Rich, with support for stack trace filtering 

Key Differences:

  • Severity levels
    • Java uses SEVERE as its highest severity level while Log4j2 uses FATAL.
    • The lowest severity level in Java is FINEST, whereas in Log4j2 it’s TRACE.
    • The naming of intermediate levels also varies, and Log4j2 provides a custom log level feature not available in Java logging.
  • Configuration
    • Java logging configuration is typically done via a logging.properties file, while Log4j2 supports XML, JSON, or properties file configurations.
  • Output handling
    • Java logging uses Handlers to direct log messages to different outputs, whereas Log4j2 uses Appenders for this purpose. 
  • Community adoption
    • Log4j2 is widely adopted in the Java community due to its rich feature set and performance benefits, including asynchronous logging, which is not a native feature in Java logging. 
  • Exception handling
    • Log4j2 offers more robust exception handling, including support for stack trace filtering, which is not as well-developed in Java logging.
  • Performance
    • Log4j2 generally offers higher performance, especially with asynchronous logging, as compared to Java logging.

    The most obvious benefit of a logging framework is the levels, which enable you to search and filter log entries based on their severity. That way, you can prevent a “needle in a haystack” kind of situation. Imagine having to find the one error entry among thousands of normal events.

    You can take it a step further and configure your logging to write log entries to different destinations according to their levels, which can make it even easier to find the messages you’re looking for.

    Additionally, you can use levels to control the granularity of your logging. In the development environment, you can set the application’s level to the minimum level, so everything is logged. On the other hand, in the production environment, you typically wouldn’t want to record everything, so you’d set the level to INFO.

    Write Meaningful Log Entries 

    There’s nothing more frustrating than trying to troubleshoot unexpected application behavior, only to open the logs and find they contain meaningless, contextless messages.

    Don’t do this to your fellow developers. Create meaningful log messages rich with context, so they provide enough information to understand the event and resolve the issue. Instead of a generic “Operation failed” message, be more specific, such as “Data export to .csv format failed.” You should also include relevant metadata in your event messages. At a minimum, you should include: 

    • A timestamp: It’s not much use knowing something happened, unless you know when it happened. Add a timestamp to your log entries. Spare your fellow developers the pain of trying to figure out time zones by logging in UTC (or local time plus offset). While you’re at it, use the ISO-8601 format for the timestamp.
    • The ID of the thread: This is priceless when logging from a multi-threaded application. It is also critical if you are considering deploying an Application Performance Monitoring tool, such as SolarWinds Observability SaaS.
    • The name of the class from which the event originated.
    • And of course, include the appropriate log level.

    Beware of Performance Impacts

    Over 10 years ago, Jeff Atwood said performance is a feature. He was right then, and he’s still right now.

    Make no mistake: you should expect a performance hit due to logging. But there are steps you can take to minimize performance impacts. Consider the following piece of code:

    logger.info(
      String.format("The result is %d.", superExpensiveMethod())
    );

    As you can see, to construct the log message, we call an extensive method. Now, suppose the current logging level set for the application is WARN. This means the message above will not be logged. However, the call to superExpensiveMethod() will still be made. The advice here is simple: before doing expensive computations, check whether the application’s configured logging level will allow your message to be written. In the case of log4j2, you can easily do it this way:

    if (logger.isEnabled(Level.INFO))
        logger.info(
          String.format("The result is %d.", superExpensiveMethod())
        );

    By performing the check above, you can prevent an unnecessary call to a very expensive method.

    Another way to mitigate the impact of logging on your application’s performance is to avoid logging in the hot path. “Hot path” here means a portion of the application critical for performance and executed frequently. If you can avoid logging in this area, you will prevent a large number of performance-impacting logging calls. You can also leverage asynchronous logging, so the main thread of the application doesn’t get stuck because of expensive logging calls.

    Beware of Sensitive Data

    Many applications handle sensitive data. When it comes to logging, you have to be careful not to log the data. Besides the obvious security implications, failing to handle sensitive data correctly can result in serious financial and legal consequences.

    Here is a non-exhaustive list of data you should not include in logs:

    • Financial information, such as account numbers and credit card numbers
    • Security-sensitive data, such as encryption keys or passwords
    • Personal Identifiable Information (PII), such as full names, email addresses, birthdates, driver’s license numbers, and Social Security numbers

    If you do have a legitimate need to log sensitive information, don’t log it in plain text. Instead, use anonymization and/or pseudonymization techniques, so an eventual attacker can’t read the actual data.

    Include the Stack Trace When Logging Exceptions

    The advice here is short: When logging exceptions, include the whole stack trace. This will make it easier for other developers or IT pros to troubleshoot problems. They’ll be able to track the problem to its root cause and fix it.

    Make Your Logs Machine Parsable

    Last but not least, don’t forget to make your log entries machine-readable.

    Many of the tips on this list could be summarized in one sentence: make your logs human-readable. This makes sense since most of the time, humans are the intended target audience for logs.

    However, it’s becoming increasingly common to use tools to perform analysis on log files, extracting information from the logs to help with decision-making. Parsing plain text logs is doable, but it often requires complex regular expressions to locate and extract the relevant pieces of data.

    So, instead of logging in plain text, leverage structured logging—for instance, outputting your log events as JSON. This will enable you to utilize off-the-shelf tools to parse and extract the necessary information.

    Java Logging: Do It Properly and Profit

    Effective logging is one of the most valuable investments you can make in your application to achieve high-quality software. Unfortunately, it’s easy to get logging in Java—and in other languages —wrong. I wanted to share what I learned so you can avoid these common traps.

    On a final note, if you’re looking for a cloud-based logging tool that’s easy to set up and use, consider SolarWinds Papertrail. SolarWinds Papertrail aggregates all your logs, including Java logs, into a single location and lets you search and filter events in real-time.

    Now that you have the basics, the next step is to make your approach to Java logs more efficient and easier to manage.

    I shared some pointers on how to approach logs with minimal impact on performance, most of them related to making the messages in the log files easily readable and understandable. To sum it up: be considerate of the developers who will be relying on your logs. One of them might even be you.

    Aggregate, organize, and manage your logs

    • Collect real-time log data from your applications, servers, cloud services, and more
    • Search log messages to analyze and troubleshoot incidents, identify trends, and set alerts
    • Create automated backups, and archives of up to a year of historical data
    Start Free Trial

    Fully Functional for 30 Days

    Let's talk it over

    Contact our team, anytime.