2016-01-24 3 views
1

Я хочу добавить строку (имя пользователя и номер потока) к каждому сообщению журнала в моем приложении Java с помощью log4j. Любой простой способ сделать это? Любой единственный метод для переопределения?Как добавить строку ко всем сообщениям журнала

+0

Что значит «имя пользователя»? Вы можете добавить имя потока в свой шаблон (google any log4j manual) – coolguy

+0

Спасибо. После успешного входа в систему я могу извлечь имя пользователя из сеанса пользовательского интерфейса, вызвав метод getCurrentUsername(). – user3399000

+0

Я не думаю, что это хорошая идея добавить некоторые результаты метода к шаблону макета регистратора. – coolguy

ответ

1

Вы также можете проверить вложенную диагностическую контекстную функцию log4j.

+0

Кажется, что работает. Найдена некоторая полезная информация [здесь] (https://wiki.apache.org/logging-log4j/NDCvsMDC). – user3399000

1

Если вы готовы использовать какую-то фреймворк как AspectJ, это довольно просто. Приведу пример с помощью Maven.

Сначала ПОМ:

<?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 

Здесь имя пользователя является OS один. Вы можете заменить его тем, что хотите, например. имя пользователя, полученное с помощью фильтра сервлетов.

Все. Надеюсь, это поможет.

Смежные вопросы