Denis
Denis

Reputation: 12077

Log4Net printing "ThreadID" and "Thread Name" in the log

In our apps we usually name the threads that we create. For example, we would create a thread and give it a name like "WorkerThread".

Let's say this is part of my log4net config file:

 <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value="C:\Logs\MyApp\myapp.log" />
      <param name="AppendToFile" value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="1000MB" />
      <staticLogFileName value="true" />
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="DEBUG" />
        <levelMax value="FATAL" />
      </filter>
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c :: %m%n" />
      </layout>
    </appender>

This configuration will print the following in my log:

2017-03-07 17:00:00,003 [MessagePump Worker] DEBUG MyApp.App :: Blah Blah Blah

I would like it to print:

2017-03-07 17:00:00,003 [MessagePump Worker: 2380] DEBUG MyApp.App :: Blah Blah Blah

I am just trying to figure out what I need to put in my Conversion Pattern to also include the ThreadID (2380) as in my example above. I have done some google searches but I can't seem to find a way to print both the "Thread Name" and "Thread ID". Anyone have any ideas?

Upvotes: 5

Views: 13356

Answers (3)

Gil
Gil

Reputation: 21

  1. Add a hook

    public class Log4NetLogLevelTranslator : ILog4NetLogLevelTranslator
    {
     public Level TranslateLogLevel(LogLevel logLevel, Log4NetProviderOptions options)
     {
       //To use the real threadId
       //if (ThreadContext.Properties["threadId"] == null)
       //    ThreadContext.Properties["threadId"] = Environment.CurrentManagedThreadId;
    
       if (ThreadContext.Properties["threadId"] == null)
          ThreadContext.Properties["threadId"] = Guid.NewGuid().ToString("N").ToLower();
    
       return logLevel switch
       {
         LogLevel.Trace => Level.Trace,
          LogLevel.Debug => Level.Debug,
          LogLevel.Information => Level.Info,
          LogLevel.Warning => Level.Warn,
          LogLevel.Error => Level.Error,
          LogLevel.Critical => Level.Critical,
          LogLevel.None => Level.Off,
          _ => Level.Error
       };
     }
    }
    
  2. Startup

    Logging.AddLog4Net(new Log4NetProviderOptions { Log4NetConfigFileName = path, LogLevelTranslator = new Log4NetLogLevelTranslator() });
    
  3. Conversion pattern config %property{threadId}

Upvotes: 0

BobbyA
BobbyA

Reputation: 2260

It may be impossible outside of manually adding a ThreadContext.Property, like in @Wouter's answer.

See the documentation here:

PatternLayout Class

thread | Used to output the name of the thread that generated the logging event. Uses the thread number if no name is available.

So you only get a thread id if the thread name doesn't exist. I'm frustrated with this myself, as I only want thread ids, even when a thread is named.

Upvotes: 4

Wouter
Wouter

Reputation: 2948

In your application thread use:

ThreadContext.Properties["threadid"] = Thread.CurrentThread.ManagedThreadId;

in the conversion pattern:

%property{threadid}

Upvotes: 9

Related Questions