Sirikata
libcore/include/sirikata/core/util/Logging.hpp
Go to the documentation of this file.
00001 /*  Sirikata Utilities -- Sirikata Logging Utility
00002  *  Logging.hpp
00003  *
00004  *  Copyright (c) 2009, Daniel Reiter Horn
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_LOGGING_HPP_
00034 #define _SIRIKATA_LOGGING_HPP_
00035 
00036 #include <sirikata/core/util/Timer.hpp>
00037 #include <iomanip>
00038 
00039 extern "C" SIRIKATA_EXPORT void* Sirikata_Logging_OptionValue_defaultLevel;
00040 extern "C" SIRIKATA_EXPORT void* Sirikata_Logging_OptionValue_atLeastLevel;
00041 extern "C" SIRIKATA_EXPORT void* Sirikata_Logging_OptionValue_moduleLevel;
00042 namespace Sirikata {
00043 class OptionValue;
00044 namespace Logging {
00045 enum LOGGING_LEVEL {
00046     fatal=1,
00047     error=8,
00048     warning=64,
00049     warn=warning,
00050     info=512,
00051     debug=4096,
00052     detailed=8192,
00053     insane=32768
00054 };
00055 
00056 SIRIKATA_FUNCTION_EXPORT const String& LogModuleString(const char* base);
00057 SIRIKATA_FUNCTION_EXPORT const char* LogLevelString(LOGGING_LEVEL lvl, const char* lvl_as_string);
00058 
00059 // Public so the macros work efficiently instead of another call
00060 extern "C" SIRIKATA_EXPORT std::ostream* SirikataLogStream;
00061 
00065 SIRIKATA_FUNCTION_EXPORT void setOutputFP(FILE* fp);
00069 SIRIKATA_FUNCTION_EXPORT void setLogStream(std::ostream* logfs);
00073 SIRIKATA_FUNCTION_EXPORT void finishLog();
00074 
00075 } }
00076 #if 1
00077 # ifdef DEBUG_ALL
00078 #  define SILOGP(module,lvl) true
00079 # else
00080 //needs to use unsafeAs because the LOGGING_LEVEL typeinfos are not preserved across dll lines
00081 #  define SILOGP(module,lvl) \
00082     ( \
00083      std::max( reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_atLeastLevel)->unsafeAs<Sirikata::Logging::LOGGING_LEVEL>(), \
00084            reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_defaultLevel)->unsafeAs<Sirikata::Logging::LOGGING_LEVEL>()) \
00085      >=Sirikata::Logging::lvl &&                    \
00086         ( (reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_moduleLevel)->unsafeAs<std::tr1::unordered_map<std::string,Sirikata::Logging::LOGGING_LEVEL> >().find(#module)==reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_moduleLevel)->unsafeAs<std::tr1::unordered_map<std::string,Sirikata::Logging::LOGGING_LEVEL> >().end() && \
00087            reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_defaultLevel)->unsafeAs<Sirikata::Logging::LOGGING_LEVEL>()>=(Sirikata::Logging::lvl)) \
00088            || (reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_moduleLevel)->unsafeAs<std::tr1::unordered_map<std::string,Sirikata::Logging::LOGGING_LEVEL> >().find(#module)!=reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_moduleLevel)->unsafeAs<std::tr1::unordered_map<std::string,Sirikata::Logging::LOGGING_LEVEL> >().end() && \
00089               reinterpret_cast<Sirikata::OptionValue*>(Sirikata_Logging_OptionValue_moduleLevel)->unsafeAs<std::tr1::unordered_map<std::string,Sirikata::Logging::LOGGING_LEVEL> >()[#module]>=Sirikata::Logging::lvl)))
00090 # endif
00091 # define SILOGBARE(module,lvl,value)                                    \
00092     do {                                                                \
00093         if (SILOGP(module,lvl)) {                                       \
00094             std::ostringstream __log_stream;                            \
00095             __log_stream << value;                                      \
00096             (*Sirikata::Logging::SirikataLogStream) << __log_stream.str() << std::endl; \
00097         }                                                               \
00098     } while (0)
00099 #else
00100 # define SILOGP(module,lvl) false
00101 # define SILOGBARE(module,lvl,value)
00102 #endif
00103 
00104 #define SILOG(module,lvl,value) SILOGBARE(module,lvl, "[" << std::setw(9) << std::setprecision(3) << std::fixed << Sirikata::Timer::processElapsed().seconds() << ":" << Sirikata::Logging::LogModuleString(#module) << "] " << Sirikata::Logging::LogLevelString(Sirikata::Logging::lvl, #lvl) << ": " << std::resetiosflags(std::ios_base::floatfield | std::ios_base::adjustfield) << value)
00105 
00106 #if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX
00107 // FIXME only works on GCC
00108 #define NOT_IMPLEMENTED_MSG (Sirikata::String("Not implemented reached in ") + Sirikata::String(__PRETTY_FUNCTION__))
00109 #else
00110 #define NOT_IMPLEMENTED_MSG (Sirikata::String("NOT IMPLEMENTED"))
00111 #endif
00112 
00113 #define NOT_IMPLEMENTED(module) SILOG(module,error,NOT_IMPLEMENTED_MSG)
00114 
00115 
00116 #if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_LINUX
00117 // FIXME only works on GCC
00118 #define DEPRECATED_MSG (Sirikata::String("DEPRECATED reached in ") + Sirikata::String(__PRETTY_FUNCTION__))
00119 #else
00120 #define DEPRECATED_MSG (Sirikata::String("DEPRECATED"))
00121 #endif
00122 
00123 #define DEPRECATED(module) SILOG(module,warning,DEPRECATED_MSG)
00124 
00125 
00126 #endif