Add process id to log file name in log4cxx
Asked Answered
C

1

3

In log4net i can easily set process id to to log file name from config easily

<appender name="LogFileAppender" 
type="log4net.Appender.RollingFileAppender,log4net">

<file type="log4net.Util.PatternString" value="Log[%processid]" />
  • Can i do the same for the log4cxx from config file?
  • If yes, how?
Centaur answered 31/1, 2012 at 15:45 Comment(0)
A
2

According to the log4cxx documentation in order to currently do this you need to declare at least one MappedDiagnostic context.

An untested partial snippet of doing so is shown below

   #include <sys/types.h>
   #include <log4cxx/mdc.h>
   #include <iostream>
   #include <sstream>


   int main (int argc, char **argv)
   {
   //at the start of your program
   pid_t pid = getpid(); 
   pid_t tid = gettid();
   std::string pidstring;
   std::string tidstring;
   std::stringstream buffer;   
   buffer << pid << std::endl;
   pidstring = buffer.str();
   buffer.str(std::string());
   buffer << tid << std::endl;
   tidstring = buffer.str();
   buffer.str(std::string());
   MDC::put( "pid", pidstring);
   MDC::put( "tid", tidstring);
   // do actual stuff here

  return 0;   
  }

After further inspection of the log4cxx source, I realised that file doesn't take a ConversionPattern but FileNamePattern does. I believe you can only use FileNamePattern when you have use a TimeBasedRollingPolicy or FixedWindowRollingPolicy.

Now you can add the processid to the log by adding the following parameter in your appender tags in the XML configuration file.

<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
              <param name="FileNamePattern" value="MyApplication-%d{yyyy-MM-dd}- %X{pid}.log"/>
              <param name="activeFileName" value="MyApplication.log"/>
</rollingPolicy>
<param name="file" value="appxDailyLog.log"/>

or you can include it in the pattern layout by specifying the following layout tags also inside your appender tags in the XML configuration file.

 <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%X{pid} %X{tid} %d{yyyy-MM-dd HH:mm:ss,SSS}"/>
 </layout>

There is no simple way from the configuration file only to have each process append its own process to its own log like you are familiar with in log4net.

There were several log4cxx mailing list threads that mention dynamic log renaming, but all of them involved numerous changes in the C++ code and they don't do what you request.

The method they used involves having <param name="file" value="${logfilename}"/> where $logfilename is an environment variable that gets set by

std::string filename ="MyApp-";
filename.append(pidstring);
logger = Logger::getLogger("Nameoflogger");
setenv("logfile.name", "MyApp.log", 1);

calling something like the above snippet in the C++ code, each time you want the log name to change.

Other methods would involve patches to log4cxx as it currently doesn't have the functionality you need.

References

log4cxx Conversion Pattern Wiki

Short introduction to Apache log4cxx

log4cxx Tutorial

MDC log4cxx Class Reference

Abigailabigale answered 13/2, 2012 at 13:20 Comment(9)
<param name="file" value="MyApp-%X{pid}.log"/> does not work...It create file = "MyApp-%X{pid}.log" Log4cxx think as it like literal stringCentaur
But second xml tag, works. It writes process id before each log messageCentaur
Updated my answer to reflect your comment.Abigailabigale
Well I need to "change" file name.So each process writes a file [file name + its process id]. How to do it? [ writing log message process id is not my real inetrest]Centaur
The rolling policy stuff above may not work as you request in your comment, as the process id will be updated based on either the fixed window or time based rolling policy and not on a per thread basis.Abigailabigale
Well, simply what i want is, make log4cxx process safe easily.So when i write in the same process with id PidX, all logs in the same process write to file [fileName+PidX] AND all others in the process PidY will write to [fileName+PidY]...There should an easy way to do...Thanks anywayCentaur
setenv("logfile.name", "MyApp.log", 1); does not work in my case. Since all prcoss writes the same log.Anyway it seems that log4cxx is not capable of those things.Centaur
ActiveFileName doesn't support variables from context state. The support for context state in FileNamePattern doesn't allow to log directly in that file: it's used just when triggering the rolling operation.Dapple
You could find interesting my other answer about creating a dynamic appender that uses the MDC to pick the right file where to write.Dapple

© 2022 - 2024 — McMap. All rights reserved.