PixelLightAPI  .
Log.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: Log.h                                          *
00003  *
00004  *  Copyright (C) 2002-2011 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLCORE_LOG_H__
00024 #define __PLCORE_LOG_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include "PLCore/Core/Singleton.h"
00032 #include "PLCore/String/String.h"
00033 #include "PLCore/Container/Queue.h"
00034 
00035 
00036 //[-------------------------------------------------------]
00037 //[ Macro definitions                                     ]
00038 //[-------------------------------------------------------]
00039 /**
00040 *  @brief
00041 *    Log macro
00042 *
00043 *  @param[in] Level
00044 *    Log level
00045 *  @param[in] Text
00046 *    Text which should be written into the log
00047 */
00048 #define PL_LOG(Level, Text) { \
00049     if (PLCore::Log::HasInstance() && PLCore::Log::GetInstance()->GetLogLevel() >= PLCore::Log::Level) { \
00050         PLCore::Log::LogLevel nLogLevel = PLCore::Log::Level; /* Avoid 'expression is constant' warning */ \
00051         if (nLogLevel >= PLCore::Log::Debug) { \
00052             PLCore::String sLogString = Text; \
00053             PLCore::Log::GetInstance()->Output(PLCore::Log::Level, sLogString + PLCore::String::Format(", %s, %d, %s", __FILE__, __LINE__, __FUNCTION__)); \
00054         } else PLCore::Log::GetInstance()->Output(PLCore::Log::Level, Text); \
00055     } \
00056 }
00057 
00058 
00059 //[-------------------------------------------------------]
00060 //[ Namespace                                             ]
00061 //[-------------------------------------------------------]
00062 namespace PLCore {
00063 
00064 
00065 //[-------------------------------------------------------]
00066 //[ Forward declarations                                  ]
00067 //[-------------------------------------------------------]
00068 class LogFormatter;
00069 
00070 
00071 //[-------------------------------------------------------]
00072 //[ Classes                                               ]
00073 //[-------------------------------------------------------]
00074 /**
00075 *  @brief
00076 *    Log system class
00077 *
00078 *  @note
00079 *    - A configurable amount of messages is hold in a queue (the last n-messages)
00080 *    - When the queue is full a flush is done
00081 *    - A flush is also done if a specified log level is used in the output function (configurable)
00082 *    - A specified log level includes also all log levels with lower values
00083 *      e.g.: if the overall log level is set to info, log messages marked as
00084 *      warning, error or critical are written to the log, too
00085 *    - You can define as many debug log levels as you want
00086 *    - Implementation of the strategy design pattern, this class is the context
00087 */
00088 class Log : public Singleton<Log> {
00089 
00090 
00091     //[-------------------------------------------------------]
00092     //[ Friends                                               ]
00093     //[-------------------------------------------------------]
00094     friend class Singleton<Log>;
00095 
00096 
00097     //[-------------------------------------------------------]
00098     //[ Public definitions                                    ]
00099     //[-------------------------------------------------------]
00100     public:
00101         /**
00102         *  @brief
00103         *    Log levels
00104         *
00105         *  @remarks
00106         *    The log level 0 is reserved for messages which are generated from the
00107         *    log system itself.
00108         */
00109         enum LogLevel {
00110             Quiet = 1,  /**< No log outputs */
00111             Always,     /**< Should be used if the message should be logged always */
00112             Critical,   /**< Should be used if an critical error occurs */
00113             Error,      /**< Should be used if an error occurs */
00114             Warning,    /**< Should be used for warning texts */
00115             Info,       /**< Should be used for info texts */
00116             Debug       /**< Should be used for debug level texts */
00117         };
00118 
00119 
00120     //[-------------------------------------------------------]
00121     //[ Public static PLCore::Singleton functions             ]
00122     //[-------------------------------------------------------]
00123     // This solution enhances the compatibility with legacy compilers like GCC 4.2.1 used on Mac OS X 10.6
00124     // -> The C++11 feature "extern template" (C++11, see e.g. http://www2.research.att.com/~bs/C++0xFAQ.html#extern-templates) can only be used on modern compilers like GCC 4.6
00125     // -> We can't break legacy compiler support, especially when only the singletons are responsible for the break
00126     // -> See PLCore::Singleton for more details about singletons
00127     public:
00128         static PLCORE_API Log *GetInstance();
00129         static PLCORE_API bool HasInstance();
00130 
00131 
00132     //[-------------------------------------------------------]
00133     //[ Public functions                                      ]
00134     //[-------------------------------------------------------]
00135     public:
00136         /**
00137         *  @brief
00138         *    Get verbose mode (write log entries to console)
00139         *
00140         *  @return
00141         *    'true' if the log is writing into the console, else 'false'
00142         *
00143         *  @note
00144         *    - In addition to using an optional log formatter, the log also writes into the console in verbose mode
00145         *    - The log does not need be to be opened to write into the console
00146         *    - Android: Messages are not written into the console, instead the Android in-kernel log buffer is used
00147         *              (use Androids "logcat" utility to access this system log)
00148         *    - By default the log does not write into the console
00149         */
00150         inline bool IsVerbose() const;
00151 
00152         /**
00153         *  @brief
00154         *    Set verbose mode (write log entries to console)
00155         *
00156         *  @param[in] bVerbose
00157         *    'true' if the log is writing into the console, else 'false'
00158         *  @param[in] bVerboseLogLevelPrefix
00159         *    Should the [LogLevel] prefix be shown?
00160         *
00161         *  @see
00162         *    - IsVerbose()
00163         */
00164         inline void SetVerbose(bool bVerbose, bool bVerboseLogLevelPrefix = true);
00165 
00166         /**
00167         *  @brief
00168         *    Open the log file by using a filename
00169         *
00170         *  @param[in] sFilename
00171         *    The log's filename, the log formatter is automatically created by using the filename extension
00172         *
00173         *  @return
00174         *    'true' if all went fine, else 'false' (maybe the log is already opened or the filename extension is not supported?)
00175         *
00176         *  @note
00177         *    - Supported log filename extensions: "txt" (LogFormatterText), "log" (LogFormatterText), "xml" (LogFormatterXml), "html" (LogFormatterHtml)
00178         */
00179         PLCORE_API bool Open(const String &sFilename);
00180 
00181         /**
00182         *  @brief
00183         *    Open the log file by using a filename and an explicit log formatter instance
00184         *
00185         *  @param[in] sFilename
00186         *    The log's filename
00187         *  @param[in] cLogFormatter
00188         *    Log formatter instance to be used, if this method returns successfully, the log takes over
00189         *    the control and is responsible for the destruction of the given instance
00190         *
00191         *  @return
00192         *    'true' if all went fine, else 'false' (maybe the log is already opened?)
00193         */
00194         PLCORE_API bool Open(const String &sFilename, LogFormatter &cLogFormatter);
00195 
00196         /**
00197         *  @brief
00198         *    Close log
00199         *
00200         *  @return
00201         *    'true' if all went fine, else 'false'
00202         */
00203         PLCORE_API bool Close();
00204 
00205         /**
00206         *  @brief
00207         *    Get log filename
00208         *
00209         *  @return
00210         *    The log filename
00211         */
00212         inline String GetFilename() const;
00213 
00214         /**
00215         *  @brief
00216         *    Write a string into the log
00217         *
00218         *  @param[in] nLogLevel
00219         *    Log level
00220         *  @param[in] sText
00221         *    Text which should be written into the log
00222         *
00223         *  @return
00224         *    'true' if all went fine, else 'false'
00225         *
00226         *  @remarks
00227         *    The text is written to the log only if the current
00228         *    log level is greater or equal to the specified value.
00229         */
00230         inline bool Output(uint8 nLogLevel, const String &sText);
00231 
00232         /**
00233         *  @brief
00234         *    Get current log level
00235         *
00236         *  @return
00237         *    The current log level
00238         */
00239         inline uint8 GetLogLevel() const;
00240 
00241         /**
00242         *  @brief
00243         *    Set current log level
00244         *
00245         *  @param[in] nLogLevel
00246         *    New current log level
00247         */
00248         inline void SetLogLevel(uint8 nLogLevel = Info);
00249 
00250         /**
00251         *  @brief
00252         *    Get log level for automatic flush
00253         *
00254         *  @return
00255         *    Log level for explicitly flush
00256         */
00257         inline uint8 GetFlushLogLevel() const;
00258 
00259         /**
00260         *  @brief
00261         *    Set log level for automatic flush
00262         *
00263         *  @param[in] nFlushLogLevel
00264         *    Log level for the explicitly flush
00265         */
00266         inline void SetFlushLogLevel(uint8 nFlushLogLevel = Error);
00267 
00268         /**
00269         *  @brief
00270         *    Flush output buffer to disk
00271         *
00272         *  @return
00273         *    'true' if all went fine, else 'false' (maybe there was nothing to flush?)
00274         *
00275         *  @note
00276         *    - Only call this function if really required!
00277         */
00278         inline bool Flush();
00279 
00280         /**
00281         *  @brief
00282         *    Get current amount of buffered log messages
00283         *
00284         *  @return
00285         *    Amount of buffered log messages
00286         */
00287         inline uint32 GetBufferCount() const;
00288 
00289         /**
00290         *  @brief
00291         *    Set how many log messages should be buffered in memory
00292         *
00293         *  @param[in] nBufferCount
00294         *    Number of messages to buffer
00295         *
00296         *  @note
00297         *    The nBufferCount-last log messages gets buffered
00298         */
00299         PLCORE_API void SetBufferCount(uint32 nBufferCount = 10);
00300 
00301         /**
00302         *  @brief
00303         *    Get a copy of the queue which holds the last log messages
00304         *
00305         *  @return
00306         *    Queue of n-last log messages
00307         */
00308         inline const Queue<String> &GetLastMessages() const;
00309 
00310         /**
00311         *  @brief
00312         *    Get a string representation of the given log level
00313         *
00314         *  @param[in] nLogLevel
00315         *    Log level to return the string representation from
00316         *
00317         *  @return
00318         *    The string representation of the given log level
00319         */
00320         PLCORE_API String LogLevelToString(uint8 nLogLevel) const;
00321 
00322         /**
00323         *  @brief
00324         *    Get log formatter
00325         *
00326         *  @return
00327         *    The current log formatter object, can be a null pointer, do NOT delete the returned instance!
00328         */
00329         inline LogFormatter *GetLogFormatter() const;
00330 
00331 
00332     //[-------------------------------------------------------]
00333     //[ Private functions                                     ]
00334     //[-------------------------------------------------------]
00335     private:
00336         /**
00337         *  @brief
00338         *    Constructor
00339         */
00340         Log();
00341 
00342         /**
00343         *  @brief
00344         *    Copy constructor
00345         *
00346         *  @param[in] cSource
00347         *    Source to copy from
00348         */
00349         Log(const Log &cSource);
00350 
00351         /**
00352         *  @brief
00353         *    Destructor
00354         */
00355         virtual ~Log();
00356 
00357         /**
00358         *  @brief
00359         *    Copy operator
00360         *
00361         *  @param[in] cSource
00362         *    Source to copy from
00363         *
00364         *  @return
00365         *    Reference to this instance
00366         */
00367         Log &operator =(const Log &cSource);
00368 
00369         /**
00370         *  @brief
00371         *    Write a string into the log
00372         *
00373         *  @param[in] nLogLevel
00374         *    Log Level
00375         *  @param[in] sText
00376         *    Text which should be written into the log
00377         *
00378         *  @return
00379         *    'true' if all went fine, else 'false'
00380         */
00381         PLCORE_API bool Write(uint8 nLogLevel, const String &sText);
00382 
00383 
00384     //[-------------------------------------------------------]
00385     //[ Private data                                          ]
00386     //[-------------------------------------------------------]
00387     private:
00388         bool           m_bVerbose;                  /**< Write into the standard OS console? */
00389         bool           m_bVerboseLogLevelPrefix;    /**< Indicates if the [LogLevel] prefix should be shown within the standard OS console output */
00390         String         m_sFilename;                 /**< Filename */
00391         uint8          m_nLogLevel;                 /**< Current log level mode (see LogLevel) */
00392         uint8          m_nFlushLogLevel;            /**< If this log level is used the the flush is explicitly done */
00393         uint32         m_nFlushMessages;            /**< Holds the number of messages since the last flush */
00394         Queue<String>  m_qLastMessages;             /**< Holds the last log messages */
00395         uint32         m_nBufferedMessages;         /**< How much messages should be buffered */
00396         LogFormatter  *m_pLogFormatter;             /**< Holds an instance of a log formatter class, can be a null pointer */
00397 
00398 
00399 };
00400 
00401 
00402 //[-------------------------------------------------------]
00403 //[ Namespace                                             ]
00404 //[-------------------------------------------------------]
00405 } // PLCore
00406 
00407 
00408 //[-------------------------------------------------------]
00409 //[ Implementation                                        ]
00410 //[-------------------------------------------------------]
00411 #include "PLCore/Log/Log.inl"
00412 
00413 
00414 #endif // __PLCORE_LOG_H__


PixelLight PixelLight 0.9.10-R1
Copyright (C) 2002-2011 by The PixelLight Team
Last modified Fri Dec 23 2011 15:50:57
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported