I tried using Log4j2 on a Java EE server

About the environment

The environment is the same as in the article I wrote earlier. Prepare the execution environment of Tomcat in IntelliJ Community

To summarize it roughly, it looks like the following.

type software
language Java SE 8
Server API JavaEE
Log API Log4j2
IDE IntelliJ Community
Build tool Gradle
container Tomcat

Create a webapp folder

If it is a JavaEE project, it may have already been created, but create a directory as follows. -> src-> main-> webapp ()-> WEB-INF () (*) Directory to create Also, let's set the directories to "webapp" and "WEB-INF" properly.

Also, create directories "classes" and "lib" in WEB-INF.

Added log4j2 to the project

Add the following to the dependencies of build.gradle.

dependencies {
    //Make log4j available
    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.1'
    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.1'
    compile group: 'org.apache.logging.log4j', name: 'log4j-web', version: '2.11.1'
}

Create a Logger class

When writing Log, it is troublesome to write the preparation code every time, so create a wrap class as follows. For the code, I referred to the link below. Small diameter of Spring MVC, a little detour, small diameter of logging

import org.apache.logging.log4j.LogManager;

import java.io.File;

/**
 *Perform logging process
 */
public class Log4j {

    private static Log4j logger = null;

    private Log4j() {
    }

    public static synchronized Log4j getInstance() {
        if (logger == null) {
            logger = new Log4j();
        }
        return logger;
    }

    private String getMessage(final String msg) {
        String thisClassName = this.getClass().getName();
        //Get class name
        String SuperClassName = Logger.class.getName();
        Thread t = Thread.currentThread();
        StackTraceElement[] stackTraceElements = t.getStackTrace();
        int pos = 0;
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            String steClassName = stackTraceElement.getClassName();
            if (thisClassName.equals(steClassName) || SuperClassName.equals(steClassName)){
                break;
            }
            pos++;
        }
        pos += 2;
        StackTraceElement m = stackTraceElements[pos];
        return m.getClassName() + ":" + m.getMethodName() + "() \n" + msg;
    }

    private String getErrorMessage(final Exception e) {
        StringBuilder sb = new StringBuilder();
        StackTraceElement[] st = e.getStackTrace();
        if (st != null && st.length > 0) {
            sb.append("Class:")
                    .append(e.getClass().getName())
                    .append("¥n")
                    .append("Detail:")
                    .append(e.getMessage())
                    .append("¥n");
            for (StackTraceElement s : st) {
                sb.append(s.toString())
                        .append("¥n");
            }
        }
        return sb.toString();
    }

    public void debug(final String msg) {
        LogManager.getLogger(this.getClass()).debug(getMessage(msg));
    }

    public void info(final String msg) {
        LogManager.getLogger(this.getClass()).info(getMessage(msg));
    }

    public void info(final Object obj, final String msg) {
        LogManager.getLogger(obj.getClass()).info(msg);
    }
    public void warn(final String msg) {
        LogManager.getLogger(this.getClass()).warn(getMessage(msg));
    }

    public void error(final Exception e) {
        LogManager.getLogger(e.getClass()).error(getErrorMessage(e));
    }

    public void trace(final String msg) {
        LogManager.getLogger(this.getClass()).trace(getMessage(msg));
    }

    public void fatal(final String msg) {
        LogManager.getLogger(this.getClass()).fatal(getMessage(msg));
    }
}

In EndPoint, call and use as follows.

Log4j logger = Log4j.getInstance();
logger.info("Write the log contents here");

The following levels of logs are prepared in log4j, and the wrap method is defined accordingly.

fatal > error > warn > info > debug > trace

Log4J thorough explanation

Create log4j2 configuration file

The log4j2 configuration file is described in an xml file named "log4j2.xml". Also, in Tomcat, you can load it automatically by placing it in the webapp-> WEB-INF-> classes folder. Here is an example of how to fill in log4j2.xml.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off">

    <Properties>
        <Property name="loglayout">[%d{yyyy-MM-dd HH:mm:ss.SSS}], %-5p, %t, %c, %m%n</Property>
    </Properties>

    <Appenders>
        <!--
            fileName:File name to output the log
            filePattern:File pattern to compress when logs are accumulated
        -->
        <RollingFile name="rolling" fileName="./log/webapp.log" filePattern="./log/webapp-%d{yyyy-MM-dd}-%i.zip">
            <PatternLayout pattern="${loglayout}"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="${ptn}" />
        </Console>
    </Appenders>

    <Loggers>
        <!--
            name:Package name for log output
            level:Log output level
            additivity:Whether to output the upper log
        -->
        <Logger name="Logger" level="info" additivity="true">
            <AppenderRef ref="rolling"/>
        </Logger>
    </Loggers>
</Configuration>

More information can be found at the links below.

Log output with Log4j2

Change the file path when it becomes a war

In the Gradle project, the relative path is directly under the project, so the file directory . -> log However, in Tomcat, the root of the relative path is the tomcat installation folder, so .-> webapps-> -> WEB-INF-> log Must be. There seemed to be a way to specify it in xml, but log4j2.xml // for development log4j2_exe.xml // For production Only when making this a war log4j2_test.xml // for development log4j2.xml // for production It corresponded by changing the name to.

Actually, add the following code to build.gradle.

//Run before running the war task
war.doFirst {
    //Get child files
    java.io.File[] flist = (new java.io.File("./src/main/webapp/WEB-INF/classes")).listFiles();
    for(i in flist) {
        //File name judgment
        switch (i.getName()) {
            case "log4j2.xml":
                //rename
                i.renameTo(new java.io.File("./src/main/webapp/WEB-INF/classes/log4j2_test.xml"));
                break;

            case "log4j2_exe.xml":
                i.renameTo(new java.io.File("./src/main/webapp/WEB-INF/classes/log4j2.xml"));
                break;
        }
    }
}

//Run after war task execution
war.doLast {
    java.io.File[] flist = (new java.io.File("./src/main/webapp/WEB-INF/classes")).listFiles();
    for(i in flist) {
        switch (i.getName()) {
            case "log4j2_test.xml":
                i.renameTo(new java.io.File("./src/main/webapp/WEB-INF/classes/log4j2.xml"));
                break;

            case "log4j2.xml":
                i.renameTo(new java.io.File("./src/main/webapp/WEB-INF/classes/log4j2_exe.xml"));
                break;
        }
    }
}

problem

When I create a file for each war task execution, it is not recognized as a managed file by git -> You should be able to set it in one xml

Recommended Posts

I tried using Log4j2 on a Java EE server
I tried to implement a server using Netty
I tried running Java on a Mac terminal
I tried using Java REPL
I tried scraping a stock chart using Java (Jsoup)
I built a Java EE environment on AWS and tried running a web application
I tried using Java8 Stream API
I tried using JWT in Java
I tried using Java memo LocalDate
I tried using GoogleHttpClient of Java
I tried using the GitHub repository as a library server
I tried using Elasticsearch API in Java
I tried running Docker on Windows Server 2019
I tried using OpenCV with Java + Tomcat
I tried to display the calendar on the Eclipse console using Java.
I tried to make a talk application in Java using AI "A3RT"
I tried using Junit on Mac VScode Maven
I tried putting Java on my Mac easily
java I tried to break a simple block
I tried hitting a Java method from ABCL
I tried running Ansible on a Docker container
Try communication using gRPC on Android + Java server
I tried to break a block with java (1)
I tried using Gson
I tried using TestNG
I tried using Galasa
[Java] I tried to connect using a connection pool with Servlet (tomcat) & MySQL & Java
Create a Java development environment using jenv on Mac
I tried using a database connection in Android development
I tried using Google Cloud Vision API in Java
I tried to operate SQS using AWS Java SDK
I tried to create a Clova skill in Java
I tried to make a login function in Java
I tried using YOLO v4 on Ubuntu and ROS
I tried using Docker Desktop for Windows on Windows 10 Home
I tried OCR processing a PDF file with Java
Using the database (SQL Server 2014) from a Java program 2018/01/04
What I learned when building a server in Java
I tried using an extended for statement in Java
I tried running a DB access application on IKS + Db2 on IBM Cloud (6. Preparation of DB access application (java))
I want to implement it additionally while using kotlin on a site running Java
I tried using azure cloud-init
I tried using Apache Wicket
Make a rhombus using Java
I tried metaprogramming in Java
I tried to create a java8 development environment with Chocolatey
I tried adding a separator line to TabLayout on Android
I tried using Hotwire to make Rails 6.1 scaffold a SPA
Try launching a webAP server on the micro using Helidon
I tried to convert a string to a LocalDate type in Java
I tried running a Docker container on AWS IoT Greengrass 2.0
I tried using Dapr in Java to facilitate microservice development
Try Hello World using plain Java on a Docker container
I tried to make a client of RESAS-API in Java
I tried OCR processing a PDF file with Java part2
I tried using the CameraX library with Android Java Fragment
I made a Dockerfile to start Glassfish 5 using Oracle Java
[Java] I tried to make a rock-paper-scissors game that beginners can run on the console.
I tried using anakia + Jing now
Run Java EE applications on CICS
Using Java on OSX 10.15 (Catalina) β