java - 如何在从 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>
请让我在我的日志输出顶部显示项目版本
解决方案
我更新了我的答案。
使用 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 等的日志。
推荐阅读
- angularjs - Angularjs - 我的应用程序无法在 Safari 浏览器上运行
- php - imap_search 只是确切字符串的消息内容
- css - 将页脚固定到底部但不跟随鼠标滚动
- odata - 获取 OData 选项集值和名称
- kotlin - Kotlin:在对象表达式中调用外部类方法
- python-3.x - 如何使用具有多个内部函数的非本地语句?
- jenkins - 从 Jenkins 中的 FTP 服务器下载文件
- c# - 如何以两种方式将多个字符串绑定到 WPF 中的多个文本框?
- ios - UICollectionView 错误 indexPath.section
- r - 根据班级保持时间顺序折叠常规时间段数据