Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023
00024 #ifdef USE_POCO
00025 #include <Poco/Logger.h>
00026 #include <Poco/LogStream.h>
00027 #include <Poco/PatternFormatter.h>
00028 #include <Poco/FormattingChannel.h>
00029 #include <Poco/ConsoleChannel.h>
00030 #include <Poco/FileChannel.h>
00031 #include <Poco/TemporaryFile.h>
00032 #include <Poco/Process.h>
00033 #include <Poco/Path.h>
00034 #endif
00035
00036 #include <OpenKarto/Logger.h>
00037
00038 namespace karto
00039 {
00040
00041 static kt_bool s_FileLoggingEnabled = false;
00042 static LogLevel s_LogLevel = LOG_NONE;
00043
00044 BasicEvent<LogMessageArguments> LogMessage;
00045
00046 void InitializeLogger(const String& rApplicationName, const String& rLogLevel)
00047 {
00048 LogLevel logLevel = LOG_NONE;
00049
00050 if (rLogLevel.Find("NONE") != -1)
00051 {
00052 logLevel = LOG_NONE;
00053 }
00054 else if (rLogLevel.Find("FATAL") != -1)
00055 {
00056 logLevel = LOG_FATAL;
00057 }
00058 else if (rLogLevel.Find("ERROR") != -1)
00059 {
00060 logLevel = LOG_ERROR;
00061 }
00062 else if (rLogLevel.Find("WARNING") != -1)
00063 {
00064 logLevel = LOG_WARNING;
00065 }
00066 else if (rLogLevel.Find("INFORMATION") != -1)
00067 {
00068 logLevel = LOG_INFORMATION;
00069 }
00070 else if (rLogLevel.Find("DEBUG") != -1)
00071 {
00072 logLevel = LOG_DEBUG;
00073 }
00074 else
00075 {
00076 std::cerr << "Warning: invalid KARTO_LOG_LEVEL [" << rLogLevel << "] using NONE as default!"<<std::endl;
00077 }
00078
00079 karto::String logName;
00080 if (logLevel != LOG_NONE)
00081 {
00082 if (s_FileLoggingEnabled == true)
00083 {
00084
00085 logName = rApplicationName + ".log";
00086
00087 #ifdef USE_POCO
00088 {
00089
00090 try
00091 {
00092 std::ostringstream name;
00093 unsigned long n = 1;
00094
00095 name << "tmp" << Poco::Process::id();
00096 for (int i = 0; i < 6; ++i)
00097 {
00098 name << char('a' + (n % 26));
00099 n /= 26;
00100 }
00101
00102 Poco::File dummyFile(Poco::Path::current() + name.str());
00103
00104
00105 dummyFile.createFile();
00106 dummyFile.remove();
00107 s_FileLoggingEnabled = true;
00108 }
00109 catch (Poco::FileAccessDeniedException error)
00110 {
00111 s_FileLoggingEnabled = false;
00112 }
00113 }
00114 }
00115
00116
00117 Poco::FormattingChannel* pFCConsole = new Poco::FormattingChannel(new Poco::PatternFormatter("%t"));
00118 pFCConsole->setChannel(new Poco::ConsoleChannel);
00119 pFCConsole->open();
00120
00121 Poco::FormattingChannel* pFCFile = NULL;
00122 if (s_FileLoggingEnabled == true)
00123 {
00124 Poco::PatternFormatter* pFormatter = new Poco::PatternFormatter("%Y-%m-%d %H:%M:%S.%c %N[%P]:%q:%t");
00125 pFormatter->setProperty("times", "local");
00126 pFCFile = new Poco::FormattingChannel(pFormatter);
00127 pFCFile->setChannel(new Poco::FileChannel(logName.ToCString()));
00128 pFCFile->open();
00129 }
00130
00131 #ifdef _DEBUG
00132 Poco::Logger::create("ConsoleLogger", pFCConsole, Poco::Message::PRIO_DEBUG);
00133 if (pFCFile)
00134 {
00135 Poco::Logger::create("FileLogger", pFCFile, Poco::Message::PRIO_DEBUG);
00136 }
00137 #else
00138 Poco::Logger::create("ConsoleLogger", pFCConsole, Poco::Message::PRIO_INFORMATION);
00139 if (pFCFile)
00140 {
00141 Poco::Logger::create("FileLogger", pFCFile, Poco::Message::PRIO_INFORMATION);
00142 }
00143 #endif // _DEBUG
00144 #else
00145 }
00146 #endif // USE_POCO
00147 }
00148
00149 SetLogLevel(logLevel);
00150
00151 if (logLevel != LOG_NONE)
00152 {
00153 if (s_FileLoggingEnabled)
00154 {
00155 Log(LOG_DEBUG, "Karto created log file: " + logName);
00156 }
00157 else
00158 {
00159 if (logName != "")
00160 Log(LOG_INFORMATION, "Karto unable to create log file [" + logName + "]. No write permission to log directory.");
00161 }
00162 }
00163 }
00164
00165 void SetLogLevel(LogLevel level)
00166 {
00167 s_LogLevel = level;
00168
00169 if (s_LogLevel != LOG_NONE)
00170 {
00171 #ifdef USE_POCO
00172 Poco::Logger::get("ConsoleLogger").setLevel(level);
00173 Poco::Logger::get("FileLogger").setLevel(level);
00174 #endif // USE_POCO
00175 }
00176 }
00177
00178 LogLevel GetLogLevel()
00179 {
00180 return s_LogLevel;
00181 }
00182
00183 void Log(LogLevel level, const karto::String& rMessage)
00184 {
00185 if (s_LogLevel != LOG_NONE)
00186 {
00187 #ifdef USE_POCO
00188 if (level == LOG_FATAL)
00189 {
00190 Poco::Logger::get("ConsoleLogger").fatal(rMessage.ToCString());
00191 Poco::Logger::get("FileLogger").fatal(rMessage.ToCString());
00192 }
00193 else if (level == LOG_ERROR)
00194 {
00195 Poco::Logger::get("ConsoleLogger").error(rMessage.ToCString());
00196 Poco::Logger::get("FileLogger").error(rMessage.ToCString());
00197 }
00198 else if (level == LOG_WARNING)
00199 {
00200 Poco::Logger::get("ConsoleLogger").warning(rMessage.ToCString());
00201 Poco::Logger::get("FileLogger").warning(rMessage.ToCString());
00202 }
00203 else if (level == LOG_INFORMATION)
00204 {
00205 Poco::Logger::get("ConsoleLogger").information(rMessage.ToCString());
00206 Poco::Logger::get("FileLogger").information(rMessage.ToCString());
00207 }
00208 else if (level == LOG_DEBUG)
00209 {
00210 Poco::Logger::get("ConsoleLogger").debug(rMessage.ToCString());
00211 Poco::Logger::get("FileLogger").debug(rMessage.ToCString());
00212 }
00213 else
00214 {
00215 Poco::Logger::get("ConsoleLogger").information(rMessage.ToCString());
00216 Poco::Logger::get("FileLogger").information(rMessage.ToCString());
00217 }
00218 #else
00219 std::cout << "Warning OpenKarto is compiled without POCO, so no logging enabled! Compile with POCO and define USE_POCO to enable logging." << std::endl;
00220 std::cout << rMessage << std::endl;
00221 #endif // USE_POCO
00222
00223 LogMessageArguments eventArguments(level, rMessage);
00224 LogMessage.Notify(NULL, eventArguments);
00225 }
00226 }
00227
00228 void TerminateLogger()
00229 {
00230 if (s_LogLevel != LOG_NONE)
00231 {
00232 #ifdef USE_POCO
00233 Poco::Logger::get("ConsoleLogger").close();
00234
00235 Poco::Channel* pChannel = Poco::Logger::get("FileLogger").getChannel();
00236 if (pChannel != NULL)
00237 {
00238 pChannel->close();
00239 }
00240
00241 Poco::Logger::get("ConsoleLogger").shutdown();
00242 Poco::Logger::get("FileLogger").shutdown();
00243 Poco::Logger::shutdown();
00244 #endif // USE_POCO
00245 }
00246 }
00247
00248 }