logmanager.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /******************************************************************************
  2. *
  3. * package: Log4Qt
  4. * file: logmanager.h
  5. * created: September 2007
  6. * author: Martin Heinrich
  7. *
  8. *
  9. * Copyright 2007 Martin Heinrich
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. *
  23. ******************************************************************************/
  24. #ifndef LOG4QT_LOGMANAGER_H
  25. #define LOG4QT_LOGMANAGER_H
  26. /******************************************************************************
  27. * Dependencies
  28. ******************************************************************************/
  29. #include <QtCore/QObject>
  30. #include <QtCore/QHash>
  31. #include <QtCore/QList>
  32. #include <QtCore/QMutex>
  33. #include <QtCore/QString>
  34. #include "log4qt/level.h"
  35. #include "log4qt/logger.h"
  36. /******************************************************************************
  37. * Declarations
  38. ******************************************************************************/
  39. namespace Log4Qt
  40. {
  41. class LoggerRepository;
  42. /*!
  43. * \brief The class LogManager manages Logger in the default
  44. * LoggerRepository.
  45. *
  46. * The LogManager manages logger in a single Hierarchy instance. It
  47. * provides access to special logger over the logLogger(), qtLogger()
  48. * and rootLogger() member functions.
  49. *
  50. * The LogManager is handling the initialisation on startup. The
  51. * initialisation procedure will first attempt to configure the package
  52. * based on environment variables. If the attempt fails it will check for
  53. * the existence of configuration files in several location. For detailed
  54. * description of the initialisation procedure see \ref Init
  55. * "Initialization procedure".
  56. *
  57. * Messages created by qDebug(), qWarning(), qCritical() and qFatal() can
  58. * be can be handled by the LogManager. By default the message handling
  59. * is disabled. It can be enabled by calling setHandleQtMessages(). Once
  60. * enabled all messages are logged using the logger qtLogger().
  61. *
  62. * The Log4Qt runtime version is accessible over version(). The macros
  63. * \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION" and
  64. * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR" provide the
  65. * compile time version.
  66. *
  67. * \note All the functions declared in this class are thread-safe.
  68. */
  69. class LogManager
  70. {
  71. private:
  72. LogManager();
  73. LogManager(const LogManager &rOther); // Not implemented
  74. virtual ~LogManager();
  75. LogManager &operator=(const LogManager &rOther); // Not implemented
  76. public:
  77. /*!
  78. * Returns if the handling of messages created by calls to qDebug(),
  79. * qWarning(), qCritical() and qFatal() is activated.
  80. *
  81. * \sa setHandleQtMessages()
  82. */
  83. static bool handleQtMessages();
  84. static LoggerRepository *loggerRepository();
  85. /*!
  86. * Returns the logger used for logging internal messages. See
  87. * \ref LogLog "Logging within the package" for more details.
  88. *
  89. * Calling this function is equivalent to calling logger("Log4Qt").
  90. */
  91. static Logger *logLogger();
  92. /*!
  93. * Returns a pointer to the logger used for logging messages created by
  94. * calls to qDebug(), qWarning(), qCritical() and qFatal().
  95. *
  96. * Calling this function is equivalent to calling logger("Qt").
  97. *
  98. * \sa setHandleQtMessages()
  99. */
  100. static Logger *qtLogger();
  101. static Logger *rootLogger();
  102. static QList<Logger*> loggers();
  103. static Level threshold();
  104. static void setThreshold(Level level);
  105. /*!
  106. * Activates or deactivates the handling of messages created by calls
  107. * to qDebug(), qWarning(), qCritical() and qFatal() is activated.
  108. *
  109. * If activated, a Qt message handler is installed. Messages are logged
  110. * using the logger returned by qtLogger(). For fatal messages the same
  111. * exit procedure is implemented as for qFatal().
  112. *
  113. * The following mappping is used from QtMsgType to Level:
  114. *
  115. * <table align="center" border="1" cellpadding="2" cellspacing="0" bordercolor="#84b0c7">
  116. * <tr bgcolor="#d5e1e8">
  117. * <th> &nbsp;&nbsp;&nbsp; QtMsgType &nbsp;&nbsp;&nbsp;</th>
  118. * <th> %Level </th>
  119. * </tr><tr>
  120. * <td> QtDebugMsg </td>
  121. * <td> Level::DEBUG_INT </td>
  122. * </tr><tr bgcolor="#ffffff">
  123. * <td> QtWarningMsg </td>
  124. * <td> Level::WARN_INT </td>
  125. * </tr><tr>
  126. * <td> QtCriticalMsg </td>
  127. * <td> Level::ERROR_INT </td>
  128. * </tr><tr bgcolor="#ffffff">
  129. * <td> QtFatalMsg </td>
  130. * <td> Level::FATAL_INT </td>
  131. * </tr><tr>
  132. * <td> QtSystemMsg </td>
  133. * <td> Level::TRACE_INT </td>
  134. * </tr>
  135. * </table>
  136. *
  137. * The default value is false for not handling Qt messages.
  138. *
  139. * \sa handleQtMessages(), qInstallMsgHandler(), qFatal()
  140. */
  141. static void setHandleQtMessages(bool handleQtMessages);
  142. /*!
  143. * Configures the logging for the package to its default behaviour.
  144. *
  145. * The logger logLogger() is configured to be not additive. Messages
  146. * with the level Level::ERROR_INT and Level::FATAL_INT are written
  147. * to \c stderr using a ConsoleAppender. The remaining messages are
  148. * written to \c stdout using a second ConsoleAppender. The level is
  149. * read from the system environment or application settings using
  150. * InitialisationHelper::setting() with the key \c Debug. If a level
  151. * value is found, but it is not a valid Level string,
  152. * Level::DEBUG_INT is used. If no level string is found
  153. * Level::ERROR_INT is used.
  154. *
  155. * The function does not remove any appender from the logger
  156. * logLogger().
  157. *
  158. * \sa \ref LogLog "Logging within the package",
  159. * \ref Env "Environment Variables",
  160. * resetConfiguration(), InitialisationHelper::setting()
  161. */
  162. static void configureLogLogger();
  163. static bool exists(const char *pName);
  164. // JAVA: void fireAddAppenderEvent(Logger *pLogger, Appender *pAppender);
  165. /*!
  166. * Returns the LogManager instance.
  167. */
  168. static LogManager *instance();
  169. static Logger *logger(const QString &rName);
  170. /*!
  171. * Reset all values contained in logger repository to their default.
  172. *
  173. * All appenders are removed from all loggers. The loggers are handled
  174. * in no particular order. The last loggers to be reset are qtLogger(),
  175. * logLogger() and rootLogger() in that order.
  176. *
  177. * The handling of messages created by calls to qDebug(), qWarning(),
  178. * qCritical() and qFatal() is deactivated.
  179. *
  180. * The internal logging is initialised to its default bahaviour
  181. * using configureLogLogger().
  182. *
  183. * \sa LoggerRepository::resetConfiguration(), setHandleQtMessages(),
  184. * configureLogLogger()
  185. */
  186. static void resetConfiguration();
  187. static void shutdown();
  188. /*!
  189. * Executes the default initialisation procedure of the package.
  190. *
  191. * The function will test for the setting \c DefaultInitOverride in
  192. * the system environment and application settings using
  193. * \ref InitialisationHelper::setting(). If the value is present and
  194. * set to anything else then \c false, the initialisation is aborted.
  195. * <br>
  196. * The system environment and application settings are tested for the
  197. * setting \c Configuration. If it is found and it is a valid path to
  198. * a file, the package is configured with the file using
  199. * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *)
  200. * "PropertyConfigurator::doConfigure()". If the setting
  201. * \c Configuration is not available and a QCoreApplication object is
  202. * present, the application settings are tested for a group
  203. * \c Log4Qt/Properties. If the group exists, the package is configured
  204. * with the setting using the
  205. * \ref PropertyConfigurator::doConfigure(const QSettings &r, LoggerRepository *)
  206. * "PropertyConfiguratordoConfigure()". If neither a configuration
  207. * file nor configuration settings could be found, the current working
  208. * directory is searched for the file \c "log4qt.properties". If it is
  209. * found, the package is configured with the file using
  210. * \ref PropertyConfigurator::doConfigure(const QString &, LoggerRepository *)
  211. * "PropertyConfigurator::doConfigure()".
  212. *
  213. * \sa \ref Init "Initialization procedure",
  214. * \ref Env "Environment Variables",
  215. * InitialisationHelper::setting()
  216. */
  217. static void startup();
  218. /*!
  219. * Returns the version number of Log4Qt at run-time. This may be a
  220. * different version than the version the application was compiled
  221. * against.
  222. *
  223. * \sa \ref Log4Qt::LOG4QT_VERSION "LOG4QT_VERSION",
  224. * \ref Log4Qt::LOG4QT_VERSION_STR "LOG4QT_VERSION_STR"
  225. */
  226. static const char* version();
  227. private:
  228. void doSetHandleQtMessages(bool handleQtMessages);
  229. void doConfigureLogLogger();
  230. void doStartup();
  231. void welcome();
  232. #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
  233. static void qtMessageHandler(QtMsgType type,
  234. const char *pMessage);
  235. #else
  236. static void qtMessageHandler(QtMsgType type,
  237. const QMessageLogContext &context,
  238. const QString &message);
  239. #endif
  240. private:
  241. mutable QMutex mObjectGuard;
  242. LoggerRepository *mpLoggerRepository;
  243. Logger *mpNullLogger;
  244. bool mHandleQtMessages;
  245. #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
  246. QtMsgHandler mOldQtMsgHandler;
  247. #else
  248. QtMessageHandler mOldQtMsgHandler;
  249. #endif
  250. static LogManager *mspInstance;
  251. };
  252. /***************************************************************************
  253. * Operators, Helper
  254. ***************************************************************************/
  255. #ifndef QT_NO_DEBUG_STREAM
  256. /*!
  257. * \relates LogManager
  258. *
  259. * Writes all object member variables to the given debug stream \a rDebug and
  260. * returns the stream.
  261. *
  262. * <tt>
  263. * %LogManager(loggerrepository:Hierarchy(loggers:6 root-level:"DEBUG"
  264. * root-appenders:0 log-level: "NULL" log-appenders:0
  265. * qt-level: "NULL" qt-appenders:0 handleqtmessages: false )
  266. * </tt>
  267. * \sa QDebug
  268. */
  269. QDebug operator<<(QDebug debug,
  270. const LogManager &rLogManager);
  271. #endif // QT_NO_DEBUG_STREAM
  272. /**************************************************************************
  273. * Inline
  274. **************************************************************************/
  275. inline LoggerRepository *LogManager::loggerRepository()
  276. { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime
  277. return instance()->mpLoggerRepository; }
  278. inline bool LogManager::handleQtMessages()
  279. { // QMutexLocker locker(&instance()->mObjectGuard); // Read/Write of bool is safe
  280. return instance()->mHandleQtMessages; }
  281. inline Logger *LogManager::logLogger()
  282. { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime
  283. return logger(QLatin1String("Log4Qt")); }
  284. inline Logger *LogManager::qtLogger()
  285. { // QMutexLocker locker(&instance()->mObjectGuard); // Constant for object lifetime
  286. return logger(QLatin1String("Qt")); }
  287. inline void LogManager::setHandleQtMessages(bool handleQtMessages)
  288. { instance()->doSetHandleQtMessages(handleQtMessages); }
  289. inline void LogManager::configureLogLogger()
  290. { instance()->doConfigureLogLogger(); }
  291. inline void LogManager::startup()
  292. { instance()->doStartup(); }
  293. } // namespace Log4Qt
  294. // Q_DECLARE_TYPEINFO(Log4Qt::LogManager, Q_COMPLEX_TYPE); // Use default
  295. #endif // LOG4QT_LOGMANAGER_H