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?
Novalis
  • 2,265
  • 6
  • 39
  • 63

1 Answers1

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

Appleman1234
  • 15,946
  • 45
  • 67
  • does not work...It create file = "MyApp-%X{pid}.log" Log4cxx think as it like literal string – Novalis Feb 13 '12 at 15:23
  • But second xml tag, works. It writes process id before each log message – Novalis Feb 13 '12 at 15:25
  • Updated my answer to reflect your comment. – Appleman1234 Feb 13 '12 at 20:23
  • 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] – Novalis Feb 14 '12 at 08:00
  • 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. – Appleman1234 Feb 14 '12 at 08:33
  • 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 anyway – Novalis Feb 14 '12 at 08:37
  • 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. – Novalis Feb 14 '12 at 15:45
  • `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. – ceztko Mar 28 '19 at 10:17
  • You could find interesting my other [answer](https://stackoverflow.com/a/55408557/213871) about creating a dynamic appender that uses the `MDC` to pick the right file where to write. – ceztko Mar 29 '19 at 14:04