The revolution will be verbosely {,b}logged

Monitoring Java Application Logs with SolarWinds Papertrail

Posted by Jason Skowronski on

Logging is the process of recording messages during the execution of a program, typically for troubleshooting operational problems or software bugs. Logs save valuable hours for both the support team and the developers by giving them contextual information to determine the cause of problems and how to fix them.

Log4J and Logback are two well-known libraries for logging in Java applications. These libraries work fine for recording logs, but don’t offer a way to monitor or analyze the logs. Developers creating huge amounts of logs on a production system need to quickly analyze logs generated by many machines and applications. SolarWinds® Papertrail™ is a cloud-hosted log management tool for viewing log files from multiple machines in a single, easy-to-use interface. It is extremely useful to look at log files in aggregate using features such as fast search, filtering on system groups, and more.

In this tutorial, you will see how a typical Java application conducts logging. Later, we’ll show you how to send those logs to the Papertrail solution.

There are a number of Java logging libraries and frameworks available, and most developers commonly use one of them every day. Log4j and Logback are popular and easy to use. They send logs to configurable destinations, such as console, file, database, SMTP server, or JMS queue. In this section, we will show you how to use Logback for logging.

There are several reasons Logback is a better choice for a logging framework than Log4j. Among other reasons, it is faster and has native support for slf4j and automatic reloading of configuration files. The Logback installation guide instructs you on how to include Logback in your app or J2EE servlet container.

To start, you need to create a configuration file named logback.xml under the resource directory of your project root:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

This will send logs to your console. Logback automatically considers the log level DEBUG if you haven’t mentioned otherwise in the configuration file. You can change it with the different levels of importance, such as ERROR, WARN, INFO, and DEBUG.

Let’s have a look at how different kinds of logs are generated in the example below:

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Logger;
public class LogbackExample {
    public static void main(String[] args) {
        Logger logger = (Logger) LoggerFactory.getLogger(LogbackExample.class);
        logger.debug("debug logging");
        logger.info("info logging");
        logger.warn("warning logging");
        logger.error("error logging", new RuntimeException("help"));
    }
}

The following code will produce the output below, showing you the log data with different levels:

2018-09-07 23:45:32 [main] INFO  com.example.LogbackExample - info logging
2018-09-07 23:45:32 [main] WARN  com.example.LogbackExample - warning logging
2018-09-07 23:45:32 [main] ERROR com.example.LogbackExample - error logging
java.lang.RuntimeException: Run time exception
  at com.example.LogbackExample.main(LogbackExample.java:12)

Logging unhandled exceptions

Logging unhandled exceptions is important because if the event is thrown and there is no error handler, it will print the stack trace and exit ungracefully. To avoid this, you can make a global error handler to catch and log unhandled exceptions.

public class ExceptionExample {
    public static void main(String[] args) {
        String test = null;
        test.toString();
        // Global Error Handler for unhandled exception
        Thread.setDefaultUncaughtExceptionHandler(
            new Thread.UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();
            };
        });  
    }
}

The need for centralized logs

Each production server can generate millions of log events per day. Because there are so many, it can be a difficult task to troubleshoot problems using those logs. While it’s manageable to review console logs at the time of development, analyzing production logs requires an automated process to help you query and analyze them faster.

A good solution is to stream your logs to a management solution. A log management solution lets you search over aggregated logs to help you identify the source of unexpected errors, as well as bugs that may have been missed earlier in the development cycle.

Troubleshoot problems faster using Papertrail

When an application slows down or crashes, it frustrates the user and much time can be wasted troubleshooting. The support team and developers are forced to spend time searching for errors, checking the code, and much more.

Papertrail is a popular cloud-hosted log management service that integrates with several logging libraries. It centralizes Java and other logs in the cloud. The primary benefits of Papertrail are that it provides near real-time log visibility, along with a fast search, flexible system groups, long-term archives, analytics reporting, and webhook monitoring.

Centralizing logs

Centralizing logs is an overall system process where you can aggregate various logs from different sources, all at a central location. It makes it easier for you to analyze, search, and report your data.

Papertrail is built to help you manage all your logs no matter their source. It helps you centralize all of your Java application logs, syslogs, database logs, Apache logs, and other application logs.

Tail and search logs

The Papertrail Live Tail feature allows you to stream logs from all your machines at once. Pattern-based filtering and color coding help you focus on what matters to you.

Papertrail offers you the ability to tail logs from multiple devices in real time. This will help you troubleshoot the problem quickly even in an environment with multiple load balanced servers. The Papertrail GUI can also speed up the process of identifying critical issues by offering search and velocity graphs.

Papertrail GUI by Papertrail

Receiving an instant alert

Alerts are an important part of any log management system. Rather than constantly searching your log data for specific events, why not let Papertrail monitor for you? Papertrail gives you the liberty to receive alerts via email, Slack, Librato®, PagerDuty, or any custom HTTP webhooks of your choice. You can set an alert using various features such as filter query, alert frequency, event timestamp, and more.

Edit alert in log management system by Papertrail

Log encryption

Generally, data is most vulnerable when it is being moved from one location to another. Papertrail helps protect against malicious activity by performing real-time encryption of log files during transport. It adds an extra layer of application security to your production environment, and supports TLS encryption and certificate-based destination host verification.

Configuring Java to send logs to Papertrail

Logback outputs logs to one or more appenders (such as file, console, or syslog). Papertrail recommends the logback-syslog4j appender because it includes TCP with TLS, as well as relying on syslog4j for message transmission. In order to add logback-syslog4j, you need to follow the simple steps below.

Add the following Maven dependency in the pom.xml. You can find pom.xml under the root project directory. If you are not using Maven, download logback-syslog4j-1.0.0.jar and the latest syslog4j JAR. Place these files in the classpath along with Logback.

<dependency>
  <groupId>com.papertrailapp</groupId>
  <artifactId>logback-syslog4j</artifactId>
  <version>1.0.0</version>
</dependency>

Next, you need to add the Syslog4jAppender to your logback.xml and update the hostname and port number to the ones given to you in your Papertrail log destination settings.

<appender name="SYSLOG-TLS" class="com.papertrailapp.logback.Syslog4jAppender">
  <layout class="ch.qos.logback.classic.PatternLayout">
    <pattern>%-5level %logger{35}: %m%n%xEx</pattern>
  </layout>
  <syslogConfig class="org.productivity.java.syslog4j.impl.net.tcp.ssl.SSLTCPNetSyslogConfig">
    <!-- remote system to log to -->
    <host>logsX.papertrailapp.com</host>
    <!-- remote port to log to -->
    <port>XXXXX</port>
    <!-- program name to log as -->
    <ident>java-app</ident>
    <!-- max log message length in bytes -->
    <maxMessageLength>128000</maxMessageLength>
  </syslogConfig>
</appender>
<root level="DEBUG">
  <appender-ref ref="SYSLOG-TLS" />
</root>

Now run your application to generate some logs. You should see logs show up in your Papertrail account typically in just a few seconds. That’s it! Pretty easy, right?

Conclusion

SolarWinds Papertrail gives you a solution for centralized management of your logs. It is designed to help you troubleshoot customer problems and resolve error messages. Moreover, it gives you analytical tools to analyze and resolve operational issues and application bugs.

Learn more about how Papertrail can give you frustration-free log management in the cloud, then sign up for a trial or the free plan to get started.