我想使用log4j将一个字符串(用户名和线程号)附加到我的java应用程序中的每条日志消息中。有什么简单干净的方法吗?要覆盖的任何一种方法吗?
答案 0 :(得分:1)
您还可以查看log4j的嵌套诊断上下文功能。
答案 1 :(得分:1)
如果您准备使用某些框架作为AspectJ,那么它非常简单。在这里,我将举一个使用Maven的例子。
首先是pom:
<?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>dummy-log</groupId>
<artifactId>dummy-log</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>
How to append a string to all log messages
http://stackoverflow.com/questions/34973214/how-to-append-a-string-to-all-log-messages
</description>
<properties>
<main.class>dummy.log.MainApp</main.class>
<jdk.version>1.7</jdk.version>
<project.encoding>UTF-8</project.encoding>
<project.build.sourceEncoding>${project.encoding}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.encoding}</project.reporting.outputEncoding>
<maven.compiler.source>${jdk.version}</maven.compiler.source>
<maven.compiler.target>${jdk.version}</maven.compiler.target>
<maven.compiler.compilerVersion>${jdk.version}</maven.compiler.compilerVersion>
<maven.compiler.fork>true</maven.compiler.fork>
<maven.compiler.verbose>true</maven.compiler.verbose>
<maven.compiler.optimize>true</maven.compiler.optimize>
<maven.compiler.debug>true</maven.compiler.debug>
<maven.jar.plugin.version>2.6</maven.jar.plugin.version>
<maven.antrun.plugin.version>1.8</maven.antrun.plugin.version>
<aspectj.maven.plugin.version>1.8</aspectj.maven.plugin.version>
<aspectj.version>1.8.7</aspectj.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- compile time weaving -->
<!-- required to avoid warning from aspectj-maven-plugin, even if aspectjweaver
is also a dependency -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- aspectjrt is only a subset of aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>${aspectj.maven.plugin.version}</version>
<configuration>
<complianceLevel>${jdk.version}</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>class-antrun</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven.antrun.plugin.version}</version>
<configuration>
<target>
<java fork="true" classname="${main.class}">
<classpath refid="maven.compile.classpath" />
</java>
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>only-under-eclipse</id>
<activation>
<property>
<name>m2e.version</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<versionRange>[${aspectj.maven.plugin.version},)</versionRange>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
</project>
然后在消息中包含线程名称的log4j配置文件:
log4j.rootLogger=ERROR,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n
现在是一个主要的课程:
package dummy.log;
import org.apache.log4j.Logger;
public final class MainApp {
private static final Logger LOG = Logger.getLogger(MainApp.class);
public static void main(final String[] args) {
LOG.info("Hello!");
LOG.debug("Hello!");
LOG.error("Hello!");
LOG.fatal("Hello!");
LOG.trace("Hello!");
LOG.warn("Hello!");
}
}
用于获取用户名的编织作业由以下内容完成:
package dummy.log;
import static java.lang.String.format;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectjDemo {
@Around("call(public void org.apache.log4j.Logger.*(Object)) && args(msg) && !within(AspectjDemo)")
public Object formatMessageLog(final Object msg,
final ProceedingJoinPoint invocation,
final JoinPoint.EnclosingStaticPart callerContext) throws Throwable {
return formatLogAndProceed(msg, null, invocation, callerContext);
}
@Around("call(public void org.apache.log4j.Logger.*(Object, Throwable)) && args(msg, exception) && !within(AspectjDemo)")
public Object formatMessageLog(final Object msg,
final Throwable exception,
final ProceedingJoinPoint invocation,
final JoinPoint.EnclosingStaticPart callerContext) throws Throwable {
return formatLogAndProceed(msg, exception, invocation, callerContext);
}
private Object formatLogAndProceed(final Object msg, final Throwable exception,
final ProceedingJoinPoint invocation, final JoinPoint.EnclosingStaticPart callerContext) throws Throwable {
final Object[] arguments = invocation.getArgs();
final String user = System.getProperty("user.name");
arguments[0] = formatMessage(user, msg);
return invocation.proceed(arguments);
}
private String formatMessage(final String user, final Object originalMessage) {
return format("Log (user is \'%s\'): %s", user, originalMessage);
}
}
试一试:
mvn clean compile antrun:run -Pclass-antrun
你会得到类似的东西:
[INFO] --- aspectj-maven-plugin:1.8:compile (default) @ dummy-log ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO] Join point 'method-call(void org.apache.log4j.Logger.info(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:11) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[INFO] Join point 'method-call(void org.apache.log4j.Logger.debug(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:12) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[INFO] Join point 'method-call(void org.apache.log4j.Logger.error(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:13) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[INFO] Join point 'method-call(void org.apache.log4j.Logger.fatal(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:14) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[INFO] Join point 'method-call(void org.apache.log4j.Logger.trace(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:15) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[INFO] Join point 'method-call(void org.apache.log4j.Logger.warn(java.lang.Object))' in Type 'dummy.log.MainApp' (MainApp.java:16) advised by around advice from 'dummy.log.AspectjDemo' (AspectjDemo.java:14)
[WARNING] advice defined in dummy.log.AspectjDemo has not been applied [Xlint:adviceDidNotMatch]
/home/pierre/workspace-js/dummy-log/src/main/java/dummy/log/AspectjDemo.java:21
[INFO]
[INFO] --- maven-antrun-plugin:1.8:run (default-cli) @ dummy-log ---
[INFO] Executing tasks
main:
[java] ERROR 2016-01-24 10:57:37,379 1 dummy.log.MainApp [main] Log (user is 'pierre'): Hello!
[java] FATAL 2016-01-24 10:57:37,380 2 dummy.log.MainApp [main] Log (user is 'pierre'): Hello!
[INFO] Executed tasks
这里的用户名是操作系统名称。您可以根据需要更换它,例如使用servlet过滤器检索的用户名。
就是这样。希望它会有所帮助。