00001 #ifndef Impala_Basis_LogSystem_h
00002 #define Impala_Basis_LogSystem_h
00003
00004 #include <sstream>
00005
00006 #include "Basis/ILog.h"
00007 #include "Basis/FileExists.h"
00008 #include "Basis/StringList.h"
00009
00015 namespace Impala
00016 {
00017
00018 class LogSystem
00019 {
00020
00021 public:
00022
00023 class LogSystemConfig
00024 {
00025
00026 public:
00027
00028 String mLogProperties;
00029 String mLogFile;
00030 String mLogLayout;
00031 bool mDebug;
00032 int mLogLevel;
00033 String mDebugCat;
00034 bool mNoErrorLog;
00035 String mJobErrorLog;
00036 bool mExitOnError;
00037 bool mLogFlushOutput;
00038
00039 };
00040
00041 static LogSystem&
00042 GetInstance()
00043 {
00044 static LogSystem theLogSystem;
00045 return theLogSystem;
00046 }
00047
00048 virtual
00049 ~LogSystem()
00050 {
00051 #ifdef LOG4CPP_USED
00052 log4cpp::Category::shutdown();
00053 #endif
00054 }
00055
00056
00057 #ifdef LOG4CPP_USED
00058 void
00059 Configure(const LogSystemConfig& config)
00060 {
00061 if (FileExists(config.mLogProperties))
00062 {
00063 const String logPropertiesFile = config.mLogProperties;
00064 log4cpp::PropertyConfigurator::configure(logPropertiesFile);
00065 }
00066 else
00067 {
00068 log4cpp::Appender* appender =
00069 new log4cpp::OstreamAppender("stdout", &std::cout);
00070 AddAppender(appender, config.mLogLayout);
00071 }
00072
00073 if (config.mDebug)
00074 {
00075 log4cpp::Category& root = log4cpp::Category::getRoot();
00076 root.setPriority(log4cpp::Priority::DEBUG);
00077 }
00078
00079 if (!config.mDebugCat.empty())
00080 {
00081 StringList catList(config.mDebugCat, ';');
00082 StringListCI i;
00083 for (i = catList.begin() ; i != catList.end() ; i++)
00084 {
00085 std::cout << "debug cat " << *i << std::endl;
00086 log4cpp::Category& cat = log4cpp::Category::getInstance(*i);
00087 cat.setPriority(log4cpp::Priority::DEBUG);
00088 }
00089 }
00090
00091 if (!config.mLogFile.empty())
00092 {
00093 std::ostringstream oss;
00094 if (Link::Mpi::NrProcs() > 1)
00095 oss << "p" << Link::Mpi::MyId() << "_";
00096 oss << config.mLogFile;
00097 log4cpp::Appender* appender =
00098 new log4cpp::FileAppender("proc_file", oss.str());
00099 AddAppender(appender, config.mLogLayout);
00100 }
00101
00102 if (!config.mNoErrorLog)
00103 {
00104 std::ostringstream oss;
00105 if (Link::Mpi::NrProcs() > 1)
00106 oss << "p" << Link::Mpi::MyId() << "_";
00107 oss << "errors.log";
00108 if(!WritableFile(oss.str()))
00109 {
00110 std::cerr << "WARNING [LogSystem.h] failed to open errors.log for"
00111 << " writing. You can 1) use log properties to write to"
00112 << " another file; 2) run in another folder; 3) use"
00113 << " option noErrorLog to not log to errors.log.\n"
00114 << "Shutting down for now..." << std::endl;
00115 exit(1);
00116 }
00117 log4cpp::Appender* appender =
00118 new log4cpp::FileAppender("err_file", oss.str());
00119 appender->setThreshold(log4cpp::Priority::ERROR);
00120 AddAppender(appender, "%d{%a%d %H:%M:%S,%l} - [%c %x] %m%n");
00121 if (! config.mJobErrorLog.empty())
00122 {
00123 log4cpp::Appender* jobAppender =
00124 new log4cpp::FileAppender("err_file", config.mJobErrorLog);
00125 jobAppender->setThreshold(log4cpp::Priority::ERROR);
00126 AddAppender(jobAppender, "%d{%a%d %H:%M:%S,%l} - [%c %x] %m%n");
00127 }
00128 }
00129 log4cpp::StringQueueAppender* ap =
00130 new log4cpp::StringQueueAppender("err_queue");
00131 ap->setThreshold(log4cpp::Priority::ERROR);
00132 AddAppender(ap, "%d{%a%d %H:%M:%S,%l} - [%c %x] %m%n");
00133 ILogErrors::GetInstance().SetAppender(ap);
00134 gExitOnErrorLogged = config.mExitOnError;
00135 gLog4CppFlushOutput = config.mLogFlushOutput;
00136 }
00137
00138 void
00139 AddAppender(log4cpp::Appender* appender, CString layoutPattern)
00140 {
00141 log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
00142 layout->setConversionPattern(layoutPattern);
00143 appender->setLayout(layout);
00144 log4cpp::Category& root = log4cpp::Category::getRoot();
00145 root.addAppender(appender);
00146 }
00147 #endif // LOG4CPP_USED
00148
00149 #ifdef BASISLOG_USED
00150 void
00151 Configure(const LogSystemConfig& config)
00152 {
00153 Logger::Configure(config.mLogLevel, config.mLogFile, config.mDebug);
00154 gExitOnErrorLogged = config.mExitOnError;
00155 gLog4CppFlushOutput = config.mLogFlushOutput;
00156 }
00157 #endif // BASISLOG_USED
00158
00159 #ifdef STDLOG_USED
00160 void
00161 Configure(const LogSystemConfig& config)
00162 {
00163 gExitOnErrorLogged = config.mExitOnError;
00164 gLog4CppFlushOutput = config.mLogFlushOutput;
00165 }
00166 #endif // STDLOG_USED
00167
00168
00169 private:
00170
00171 LogSystem()
00172 {
00173 }
00174
00175 LogSystem(const LogSystem&)
00176 {
00177 }
00178
00179 LogSystem&
00180 operator=(const LogSystem&)
00181 {
00182 }
00183
00184 };
00185
00186 }
00187
00188 #endif