/** @file

    $Id$

    $Date$
    $Author$

    @copy &copy; Marc W&auml;ckerlin
    @license LGPL, see file <a href="license.html">COPYING</a>

    $Log$
    Revision 1.3  2005/11/29 12:39:42  marc
    make it compilable with gcc 4.0.2 and newer doxygen

    Revision 1.2  2005/04/14 19:06:37  marc
    no more duplicated traces, better filtering for Qt

    Revision 1.1  2005/04/07 20:57:36  marc
    initial version


         1         2         3         4         5         6         7         8
    5678901234567890123456789012345678901234567890123456789012345678901234567890
*/

#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/helpers/properties.h>
#include <fstream>

#if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) && _REENTRANT && !_MT
#define _MT
#endif

namespace mrw {

  /** @addtogroup debug
      */
  //@{

  /** @defgroup AutoInitLog4cxx Automatically initialize log4cxx

      If you want to enable log4cxx
      (http://logging.apache.org/log4cxx), you have to configure it in
      your application, normally in the main. If you want to configure
      it automatically, without changing a single line in your code
      (e.g. for temporary debugging), simply link to @c
      libmrwlog4cxxconfiguration, either with option @c
      -lmrwlog4cxxconfiguration for single threaded, or with @c
      -lmrwlog4cxxconfiguration-mt for multi threaded applications.

      With @ref trclog4cxx and @ref
      AutoFunctionTrace, you can add tracing based on @c log4cxx,
      without even change a single line in your code. But your code
      still has to initialize @c log4cxx. If you even want to
      automatically initialize @c log4cxx, use this library!

      Configures @c log4cxx in the following way:
       -# if available, read @c log4cxx property file
          (read first file found, in this order)
           -# file specified in environment variable
              @c $MRW_LOG4CXX_CONFIGFILE
           -# <code>.mrwlog4cxx</code> (local file)
           -# <code>~/.mrwlog4cxx</code> (file in user's home)
           -# <code>/etc/mrwlog4cxx</code> (global configuration)
       -# if no configuration file is found, use default configuration:
          @verbatim
log4j.rootLogger = DEBUG, A1
log4j.logger.mrw.fn = DEBUG
log4j.logger.mrw.fn.log4cxx = OFF
log4j.logger.mrw.fn.boost = OFF
log4j.logger.mrw.fn.Thread = OFF
log4j.logger.mrw.fn.QString = OFF
log4j.logger.mrw.fn.QShared = OFF
log4j.logger.mrw.fn.QWidget = OFF
log4j.logger.mrw.fn.QRect = OFF
log4j.logger.mrw.fn.qstrcmp = OFF
log4j.logger.mrw.fn.*.qt_cast = OFF
log4j.logger.mrw.fn.mrw = OFF
log4j.logger.mrw.fn.std = OFF
log4j.logger.mrw.fn.CppUnit = OFF
log4j.logger.mrw.fn.__gnu_cxx = OFF
log4j.appender.A1 = org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout = org.apache.log4j.PatternLayout
@endverbatim
          and for multi threaded programs in addition:
          @verbatim
log4j.appender.A1.layout.ConversionPattern = t-%-60c%m%n
@endverbatim
          on the other hand, single threaded programs are formatted as:
          @verbatim
log4j.appender.A1.layout.ConversionPattern = 60c%m%n
@endverbatim
          This results in the following behaviour:
           - trace to console
           - format as...
              - @c "%t-%-60c%m%n" if threaded
              - @c "%-60c%m%n" if not threaded
           - enable all tracing to @c DEBUG
           - enable tracing of @ref AutoFunctionTrace
              - disable function trace for @c log4cxx
              - disable function trace for @c boost
              - disable function trace for @c Qt base classes
              - disable function trace for @c libmrw
              - disable function trace for @c std
              - disable function trace for @c CppUnit
              - disable function trace for @c gcc internals
      */
  //@{

  class InitLog4cxx {
    public:
      InitLog4cxx() {
        std::string logconfigfile;
        char* c(getenv("MRW_LOG4CXX_CONFIGFILE"));
        if (c && std::ifstream(c))
          logconfigfile = c;
        else if (std::ifstream(".mrwlog4cxx"))
          logconfigfile = ".mrwlog4cxx";
        else if ((c=getenv("HOME")) &&
                 std::ifstream((std::string(c)+"/.mrwlog4cxx").c_str()))
          logconfigfile = std::string(c)+"/.mrwlog4cxx";
        else if (std::ifstream("/etc/mrwlog4cxx"))
          logconfigfile = "/etc/mrwlog4cxx";
        if (logconfigfile.size()) {
          log4cxx::PropertyConfigurator::configure(logconfigfile);
          return;
        }
        log4cxx::helpers::Properties properties;
        properties.setProperty("log4j.rootLogger",
                               "DEBUG, A1");
        properties.setProperty("log4j.logger.mrw.fn",
                               "DEBUG");
        properties.setProperty("log4j.logger.mrw.fn.log4cxx",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.boost",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.Thread",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.QString",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.QShared",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.QWidget",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.QRect",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.qstrcmp",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.*.qt_cast",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.mrw",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.std",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.CppUnit",
                               "OFF");
        properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx",
                               "OFF");
        properties.setProperty("log4j.appender.A1",
                               "org.apache.log4j.ConsoleAppender");
        properties.setProperty("log4j.appender.A1.layout",
                               "org.apache.log4j.PatternLayout");
#ifdef _MT
        properties.setProperty("log4j.appender.A1.layout.ConversionPattern",
                               "%t-%-60c%m%n");
#else
        properties.setProperty("log4j.appender.A1.layout.ConversionPattern",
                               "%-60c%m%n");
#endif
        log4cxx::PropertyConfigurator::configure(properties);
      }
  };
  static InitLog4cxx INIT_LOG4CXX;

  //@}
  //@}
}
