Category Archives: Java Logging

Java :How to convert a stack trace to a string?


In this blog you will learn way to convert a stack trace to a String which includes all the Stack Trace message of an exception or error.

Why this conversion is required?

This conversion is required if you want to save the message in custom log file for further analysis of log message. The e.getMessage() in Java program only returns small portion of the error, but if you want to see the detailed error then StackTrace will give you complete detail about the error in the program.

Example

To convert stackTrace to a string using printWriter as input for stackTrace to convert in String.

import java.io.PrintWriter;
import java.io.StringWriter;

public class TestExample {

	public static void main(String[] args) {
		try
		{
			int y=5/0;
		}
		catch(Exception ex)
		{
			System.out.println(convertStackTraceToString(ex));
		}

	}
    /**
     * method to convert stack trace to String
     * @param ex
     * @return
     */
	private static String convertStackTraceToString(Exception ex) {

		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		ex.printStackTrace(pw);
		String sStackTrace = sw.toString();
		return sStackTrace;
	}

}

Output


java.lang.ArithmeticException: / by zero
    at com.exceptions.errors.TestExample.main(TestExample.java:11)
Advertisements

Log4j2 JSON Configuration for Java Logging Severity Levels, Formatting and Appenders


In below previous post you read about Log4j2 XML configuration for Appenders, formatters and Loggers for Console and File Logging. I have also explained about RollingFile appeneders and there management.

Below is Log4j2 JSON configuration equivalent to XML configuration and dependency required for JSON. For more info in detail and configuration steps follow previous post for Log4J2 XML configuration.

You have to add below JSON dependency in your class path or pom.xml

POM.XML

<!-- basic Log4j2 dependency -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.6.1</version>
</dependency>
<!-- Asynchronous logging for multithreaded env -->
<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

<!-- Jackson JSON Processor -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.4.1</version>
    </dependency>

create file log4j2.json in your root folder or resource folder.

{
   "configuration": {
       "status": "info",
       "monitorInterval": "60",
       "name": "FacingIssuesOnIT",
      "properties": {
         "property": [
            {
               "name": "filename",
               "value": "target/FacingIssueOnIT.log"
            },
            {
               "name": "log-path",
               "value": "C:/logs/"
            }
         ]
      },
      "appenders": {
         "Console": {
            "PatternLayout": {
               "pattern": "%d{yyyyMMdd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
            },
            "name": "STDOUT",
            "target": "SYSTEM_OUT"
         },
         "File": {
            "PatternLayout": {
               "pattern": "%d %p %c{1.} [%t] %m%n"
            },
            "name": "file",
            "fileName": "${filename}"
         },
         "RollingFile": {
            "PatternLayout": {
               "pattern": "%d{yyyyMMdd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
            },

                "Policies": {
               "SizeBasedTriggeringPolicy": {
                  "size": "100 MB"
               },
               "TimeBasedTriggeringPolicy": {
                  "interval": "1",
                  "modulate": "true"
               }
            },
            "DefaultRolloverStrategy": {
               "Delete": {
                  "IfFileName": {
                     "glob": "*/FacingIssueOnIT-*.log.gz"
                  },
                  "IfLastModified": {
                     "age": "1h"
                  },
                  "basePath": "${log-path}",
                  "maxDepth": "2"
               }
            },
            "name": "RollingFile",
            "fileName": "${log-path}/FacingIssueOnIT.log",
            "filePattern": "${log-path}/$${date:yyyy-MM-dd}/FacingIssueOnIT-%d{yyyy-MM-dd}-%i.log.gz"
         }
      },
      "Loggers": {
         "Logger": [
            {
               "name": "com.logging",
               "level": "debug"
            },
            {
               "appender-ref": {
                  "ref": "RollingFile",
                  "level": "debug"
               },
               "name": "root",
               "level": "debug",
               "additivity": "false"
            }
         ],
         "Root": {
            "AppenderRef": [
               {
                  "ref": "file",
                  "level": "error"
               },
               {
                  "ref": "STDOUT",
                  "level": "debug"
               },
               {
                  "ref": "RollingFile"
               }
            ],
            "level": "trace"
         }
      }

   }
}

Log4j2 New Features,Compare with Log4j and other Logging Framework


Log4j2 New Features

  • Java 8-style lambda support for lazy logging.
  • Log4j2 is garbage-free or least low-garbage since version 2.6
  • Log4j2 support configuration via XML, JSON, YAML, properties configuration files or programmatically.
  • Async Loggers – performance similar to logging switched off on multithreaded.
  • Concurrency improvements: log4j2 uses java.util.concurrent libraries to perform locking at the lowest level possible. Log4j-1.x has known deadlock issues.
  • Filtering: filtering based on context data,  regular expressions, markers and other components in the Log event. Filters can be associated with Loggers. You can use a common Filter class in any of these circumstances.
  • Custom Log Level
  • Plugin Architecture – easy to extend by building custom components
    Supported APIs: SLF4J, Commons Logging, Log4j-1.x and java.util.logging.

Why people are moving?

  • Community support: Log4j2 has an active community where question, answered, features are added and bugs are fixed.
  • Automatically reload it’s configuration upon modification without losing log events while reconfiguring.

Drawback

  • log4j 2.0 is very different than log4j 1.x, and the API is mostly incompatible.
  • Java 6 required for version 2.0 to 2.3. Java 7 is required for Log4j 2.4 and later.

Steps to upgrade Log4j1 to Log4j2

  1. add log4j2 dependency  log4j-api-2.6.2.jar and log4j-core-2.6.2.jar in your class path or pom.xml .
  2. Log4j2 looks for file log4j2.xml in config file. Add log4j2.xml file either in the class path or specify path with log4j configuration file system properties.
  3. To debug the log4j.xml configuration use in the beginning of configuration file.
  4. To add more configuration for Console, File and RollingFile appenders follow Log4j2 Tutorial and Configuration.

Comparison with other Logging Framework

Follow the below link to compare different logging framework on benchmark.

https://www.loggly.com/blog/benchmarking-java-logging-frameworks/