首页 > 解决方案 > 如何在从 log4j 输出的 Log 中显示标题?

问题描述

我需要在顶部显示项目版本,然后在日志输出中显示项目日志。

像这样,

0.0.1-SNAPSHOT
18:02:33.407 [main] DEBUG c.j.e.l.App - Starting debugging
18:02:33.410 [main] INFO  c.j.e.l.b.Message - The message is: Hello World!
18:02:33.410 [main] INFO  c.j.e.l.b.Message - The message is: Hello World!
18:02:33.412 [main] DEBUG c.j.e.l.App - Ending debugging

但我不能做那个标题部分。

请让我在标题中显示我的项目版本。

这是我的 logback.xml 内容

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

    <!-- Send debug messages to System.out -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- By default, encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->

        <encoder>
        <pattern >%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.javacodegeeks.examples.logbackmavenexample.beans" level="INFO">
        <appender-ref ref="STDOUT" />
    </logger>

    <!-- By default, the level of the root level is set to DEBUG -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

这是我的 pom.xml

<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.javacodegeeks.examples</groupId>
    <artifactId>logbackmavenexample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>logbackmavenexample</name>
    <url>http://maven.apache.org</url>

    <properties>
        <junit.version>4.11</junit.version>
        <logback.version>1.1.2</logback.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <slf4j-api.version>1.7.7</slf4j-api.version>
    </properties>

    <dependencies>
        <!-- SLF4J - API -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j-api.version}</version>
        </dependency>

        <!-- logback -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>

        <!-- JUnit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>${basedir}/src/main/resources</directory>
                <includes>
                    <include>*</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

请让我在我的日志输出顶部显示项目版本

标签: javaspringlog4jlogbacklog4j2

解决方案


我更新了我的答案。

使用 maven-jar-plugin 将您的 project.version 放入构建的 jar 的 MANIFEST.MF。所以把这行放到 Maven 插件中:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                </manifest>
            </archive>
        </configuration>
    </plugin>

这将导致(除其他外)清单中的以下条目:

Implementation-Version: 0.0.1-SNAPSHOT

您可以使用以下代码阅读它:

package com.javacodegeeks.examples.logbackmavenexample.beans;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyBean.class);

    public static String getManifestInfo() {

        try {
            // reading all MANIFEST.MF from the classpath: from every jar/META-INF/MANIFEST.MF and every folder/META-INF/MANIFEST.MF and search for ours
            Enumeration<URL> resEnum = Thread.currentThread().getContextClassLoader()
                    .getResources(JarFile.MANIFEST_NAME);
            while (resEnum.hasMoreElements()) {
                try {
                    URL url = resEnum.nextElement();
                    InputStream is = url.openStream();
                    if (is != null) {
                        Manifest manifest = new Manifest(is);
                        Attributes mainAttribs = manifest.getMainAttributes();
                        // artifactId will be mapped to Implementation-Title
                        // so we can use it to identify our manifest file
                        if (!"logbackmavenexample".equals(mainAttribs.getValue("Implementation-Title"))) {
                            continue;
                        }
                        // found! return the version
                        String version = mainAttribs.getValue("Implementation-Version");
                        if (version != null) {
                            return version;
                        }
                    }
                } catch (Exception e) {
                    // Silently ignore wrong manifests on classpath?
                }
            }
        } catch (IOException e1) {
            // Silently ignore wrong manifests on classpath?
        }
        return null;
    }

    public static void main(String[] args) {
        LOGGER.info("{} started", MyBean.class.getName());
        // to print out the version ONLY without timestamp, classname, etc. I suggest to use sysout
        System.out.println(getManifestInfo());
        // however I would use this form:
        LOGGER.info("Version: {}", getManifestInfo());
    }
}

我对您的 logback.xml 进行了一些修改(我添加了additivity="false"以防止当此记录器和根记录器同时处于活动状态时出现重复的日志行):

<logger name="com.javacodegeeks.examples.logbackmavenexample.beans" level="INFO" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

我注意到您在此处指定的日志级别(INFO)比在根记录器中(您在此处指定了 DEBUG)中的另一件事。这导致我的第一次尝试没有记录任何内容,因为我在调用 MyBean 中指定的记录器时使用了 DEBUG 级别。这通常反向配置,我们希望所有内容都只记录 INFO,并且一些特定的(正在开发/关键部分)包是带有 DEBUG/TRACE 等的日志。


推荐阅读