Ведение журнала с помощью Log4j2 в Java-сервлетах, запущенных на Tomcat

#java #maven #tomcat #servlets #log4j2

Вопрос:

Я немного занимался веб-программированием на других языках, но я новичок в Tomcat, сервлете, Log4j и Maven.

Я завершил свой первый в истории сервлет, следуя этому руководству:

Следующее, что я попытался сделать, — это добавить несколько журналов. С внесенным мной изменением API все еще работает, но я не смог найти файлы журналов, которые пытался сгенерировать. Я пытался отладить это в течение нескольких часов, но все, что я могу найти в Интернете, — это то, что log4j «просто работает» в сервлете 3.0 или новее.

Система

Структура каталогов

 servlet-tutorial
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           ├── ApiServlet.java
        │           └── SomeServlet.java
        └── webapp
            ├── index.jsp
            └── WEB-INF
                ├── classes
                │   └── log4j2.xml
                └── web.xml
 

Зависимости Maven в pom.xml

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>servlet-tutorial</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>servlet-tutorial</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>2.14.1</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>servlet-tutorial</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
          <configuration>
            <release>11</release>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

 

Using Log4j

 package com.example;

...

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@WebServlet("/api")
public class ApiServlet extends HttpServlet {
    private static final Logger logger = LogManager.getLogger(ApiServlet.class);

    @Override
    public void init() throws ServletException {
        logger.warn("ApiServlet.init");
        super.init();
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // None of these gets printed
        logger.warn("ApiServlet.doGet");
        logger.debug("ApiServlet.doGet");
        logger.info("ApiServlet.doGet");
        System.out.println("ApiServlet.doGet");
        ...
    }
    ...
 

log4j2.xml

 <?xml version="1.0" encoding="utf-8"?>
<Configuration status="info">

  <Properties>
    <Property name="logdir">/home/myuser/myfolder/</Property>
    <Property name="layout">%d [%t] %-5p %c- %m%n</Property>
  </Properties>

  <Appenders>
    <RollingFile name="LOCALHOST"
        fileName="${logdir}/localhost.log"
        filePattern="${logdir}/localhost.%d{yyyy-MM-dd}-%i.log">
      <PatternLayout pattern="${layout}"/>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="1 MB" />
      </Policies>
      <DefaultRolloverStrategy max="10" />
    </RollingFile>
  </Appenders>

  <Loggers>
    <Logger name="com.example" level="info" additivity="false">
      <AppenderRef ref="LOCALHOST" />
    </Logger>
    <Root level="error"></Root>
  </Loggers>
</Configuration>
 

I tried to follow another tutorial for this log4j2.xml file.

web.xml

 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

  <display-name>My App</display-name>
</web-app>
 

Build and deploy

I first create a .war file running

 $ mvn package
 

Then I copy the war file to /var/lib/tomcat9/webapps/ , and run

 sudo service tomcat9 start
 

I think by the running this command Tomcat unpacks the .war file and create a directory under /var/lib/tomcat9/webapps/ . The unpacked directory looks like this:

 servlet-tutorial
├── index.jsp
├── META-INF
│   ├── context.xml
│   ├── MANIFEST.MF
│   ├── maven
│   │   └── com.example
│   │       └── servlet-tutorial
│   │           ├── pom.properties
│   │           └── pom.xml
│   └── war-tracker
└── WEB-INF
    ├── classes
    │   ├── com
    │   │   └── example
    │   │       ├── ApiServlet.class
    │   │       └── SomeServlet.class
    │   └── log4j2.xml
    ├── lib
    │   ├── log4j-api-2.14.1.jar
    │   ├── log4j-core-2.14.1.jar
    │   └── log4j-web-2.14.1.jar
    └── web.xml
 

Вопрос

Я сделал http-запрос, чтобы убедиться, что Tomcat запущен и сервлет загружен с последними изменениями, которые я внес, но я не вижу никаких файлов в каталоге журнала, в котором я указал log4j2.xml .

Вместо этого я нашел несколько файлов журналов, которые, как я думаю, были сгенерированы Tomcat, /var/lib/tomcat9/logs/catalina.2021-11-02.log но я все еще не вижу здесь ни журналов, которые я пытался распечатать, ни сообщений об ошибках:

 02-Nov-2021 11:41:22.806 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.31 (Ubuntu)
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Oct 20 2020 12:27:39 UTC
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.31.0
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.11.0-38-generic
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-11-openjdk-amd64
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.11 9-Ubuntu-0ubuntu2.20.04
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Ubuntu
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /var/lib/tomcat9
02-Nov-2021 11:41:22.807 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/share/tomcat9
02-Nov-2021 11:41:22.820 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
02-Nov-2021 11:41:22.820 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/var/lib/tomcat9/conf/logging.properties
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.awt.headless=true
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/var/lib/tomcat9
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/share/tomcat9
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/tmp
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.23] using APR version [1.6.5].
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
02-Nov-2021 11:41:22.821 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
02-Nov-2021 11:41:22.825 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1f  31 Mar 2020]
02-Nov-2021 11:41:23.033 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
02-Nov-2021 11:41:23.055 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [406] milliseconds
02-Nov-2021 11:41:23.097 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
02-Nov-2021 11:41:23.097 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.31 (Ubuntu)]
02-Nov-2021 11:41:23.105 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying deployment descriptor [/etc/tomcat9/Catalina/localhost/host-manager.xml]
02-Nov-2021 11:41:23.115 WARNING [main] org.apache.catalina.startup.HostConfig.deployDescriptor The path attribute with value [/host-manager] in deployment descriptor [/etc/tomcat9/Catalina/localhost/host-manager.xml] has been ignored
02-Nov-2021 11:41:23.745 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
02-Nov-2021 11:41:23.778 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of deployment descriptor [/etc/tomcat9/Catalina/localhost/host-manager.xml] has finished in [673] ms
02-Nov-2021 11:41:23.778 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying deployment descriptor [/etc/tomcat9/Catalina/localhost/manager.xml]
02-Nov-2021 11:41:23.779 WARNING [main] org.apache.catalina.startup.HostConfig.deployDescriptor The path attribute with value [/manager] in deployment descriptor [/etc/tomcat9/Catalina/localhost/manager.xml] has been ignored
02-Nov-2021 11:41:24.157 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
02-Nov-2021 11:41:24.158 INFO [main] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of deployment descriptor [/etc/tomcat9/Catalina/localhost/manager.xml] has finished in [380] ms
02-Nov-2021 11:41:24.162 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/var/lib/tomcat9/webapps/servlet-tutorial.war]
02-Nov-2021 11:41:24.645 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
02-Nov-2021 11:41:24.970 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/var/lib/tomcat9/webapps/servlet-tutorial.war] has finished in [808] ms
02-Nov-2021 11:41:24.970 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/var/lib/tomcat9/webapps/ROOT]
02-Nov-2021 11:41:25.447 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
02-Nov-2021 11:41:25.449 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/var/lib/tomcat9/webapps/ROOT] has finished in [479] ms
02-Nov-2021 11:41:25.454 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
02-Nov-2021 11:41:25.463 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [2,405] milliseconds
 

Комментарии:

1. У вас, вероятно, простая проблема с разрешениями: пользователь, запускающий Tomcat ( tomcat ?), не может писать в папку /home/myuser/myfolder/ . В таком случае Log4j выдаст ошибку stdout/stderr, которая в Ubuntu заканчивается /var/log/tomcat/catalina.out (а также системный журнал и журнал SystemD: journalctl -u tomcat9 -e ).

2. @PiotrP.Karwasz ты был прав. Я протестировал его, предоставив /home/myuser/myfolder/ разрешение 777, и смог просмотреть файлы журналов. Спасибо!