Display thread id instead thread name in log

后端 未结 10 573
南笙
南笙 2020-12-31 00:34

I have a Struts application with log4j to display information about application.

The pattern to format log\'s output is as follows:

log4j.appender.RA         


        
相关标签:
10条回答
  • 2020-12-31 01:00

    It is possible but not so easy as just using some preconfigured patterns.

    Log4j 1.X and Log4j 2.x don't have any preconfigured patterns for printing Thread ID but you can always use some "magic trick".

    PatternLayout is using PatternParser class which is mark as final class and has static map of "patterns" as keys and Converters classes as values. Everytime when Parses finds pattern using for logging pattern format starting with % it uses converter matched with this pattern key in map.

    You cannot add your own rule to that map, but you can still write your own MyOwnPatternLayout:

    public class MyOwnPatternLayout extends PatternLayout
    

    which will in it's format method do such trick:

    public String format(LoggingEvent event) {
       String log = super.format(event);
       /*
       Now you just have to replace with regex all occurences of %i or 
       any mark you would like to use as mark to represent Thread ID 
       with Thread ID value.
       Only thing you have to be sure to not use any mark as your Thread ID
       that already is defined by PatterParser class
       */
       return log.replaceAll("%i", someThreadID);
    }
    

    The only problem is that you have to get that thread ID in some way. Sometimes all you have to do is to parse Thread name which can you easily collect:

    String threadName = event.getThreadName();
    

    For example Apache-Tomcat put thread ID at the end of thread name http-nio-/127.0.0.1-8084"-exec-41.

    To be sure that thread ID is correct you can also make your own subclass of LogginEvent and Logger (MyLoggingEvent and MyLogger) and inside MyLogger create MyLoggingEvent witch will also take as argument Thread ID not only Thread Name. Then you can easly collect it in code above.

    Sorry for long answer and I hope this will at least give you some help.

    0 讨论(0)
  • 2020-12-31 01:02

    I don't know when it is introduced but in log4j2 we have %tid for

    Outputs the ID of the thread that generated the logging event.

    https://logging.apache.org/log4j/2.x/manual/layouts.html

    0 讨论(0)
  • 2020-12-31 01:02

    I create my own appender and set Thread.currentThread().getId() to the MDC property. %X{threadId} should give me the thread id. This solution is working since 1.2.15. You can then attach AsyncAppender to this.

    public class CurrentThreadIdAppender extends AppenderSkeleton implements AppenderAttachable {
    
        private final AppenderAttachableImpl appenders = new AppenderAttachableImpl();
    
    ...
    
        @Override
        protected void append(LoggingEvent event) {   
            synchronized (appenders) {
                event.setProperty("threadId", String.valueOf(Thread.currentThread().getId()));
                appenders.appendLoopOnAppenders(event);
            }
        }
    
    ...
    
    }
    
    0 讨论(0)
  • 2020-12-31 01:07

    One way you can do it is to add it yourself using log4j MDC. We use it for adding the username for web requests. We do this in a filter at the start of each request. Eg.

    import org.apache.log4j.MDC;
    
    ...
    
      // Add username to MDC
      String username = ...;
      MDC.put("user", username);
    

    Then add [%X{user}] to your conversion pattern.

    0 讨论(0)
  • 2020-12-31 01:08

    You can use the ThreadContext Map to supply meta-data to log4j2. This is a String Map of values that you CAN add through normal formatting.

    String threadId = String.valueOf(Thread.currentThread().getId());
    ThreadContext.put("TId", threadId);
    

    And a much more reasonable Pattern:

        <PatternLayout pattern="%d{yyyyMMdd}T%d{HHmmss.SSS} %-5level [%t] [%5X{TId}] %15c{1} - %msg%n"/>
    

    Full Log4j2 documentation on "Fish Tagging"

    0 讨论(0)
  • 2020-12-31 01:11

    I think it is not possible to show thread id with standard log4j formatting. I also investigated through code of PatterParser class an found nothing which can be useful. I found some custom solutions, but only for IBM server which has %i option:

    %i: Inserts the thread ID. Unlike the thread name (indicated by %t), this is thread's numeric ID. Note that this parameter is particular to Initiate, while the other parameters listed here are standard with log4j.

    See this link

    0 讨论(0)
提交回复
热议问题