19 #ifndef INCLUDE_UTIL_LOG_HPP
20 #define INCLUDE_UTIL_LOG_HPP
27 #include <boost/config.hpp>
28 #include <boost/current_function.hpp>
29 #include <boost/enable_shared_from_this.hpp>
30 #include <boost/function.hpp>
31 #include <boost/scoped_ptr.hpp>
32 #include <boost/shared_ptr.hpp>
34 #include <RCF/Export.hpp>
35 #include <RCF/ThreadLibrary.hpp>
37 #include <RCF/util/Tchar.hpp>
38 #include <RCF/util/VariableArgMacro.hpp>
51 RCF::MemOstream mTlsUserBuffer;
52 RCF::MemOstream mTlsLoggerBuffer;
53 RCF::MemOstream mTlsVarArgBuffer1;
54 RCF::MemOstream mTlsVarArgBuffer2;
63 typedef boost::shared_ptr<Logger> LoggerPtr;
65 class RCF_EXPORT LogManager
74 static LogManager & instance();
76 void deactivateAllLoggers();
77 void deactivateAllLoggers(
int name);
79 bool isEnabled(
int name,
int level);
81 typedef std::map< int, std::vector< LoggerPtr > > Loggers;
82 ReadWriteMutex mLoggersMutex;
85 void writeToLoggers(
const LogEntry & logEntry);
86 void activateLogger(LoggerPtr loggerPtr);
87 void deactivateLogger(LoggerPtr loggerPtr);
88 bool isLoggerActive(LoggerPtr loggerPtr);
90 const std::string DefaultLogFormat;
92 Mutex DefaultLoggerPtrMutex;
93 LoggerPtr DefaultLoggerPtr;
100 typedef boost::shared_ptr<LogTarget> LogTargetPtr;
109 virtual void write(
const RCF::ByteBuffer & output) = 0;
118 void write(
const RCF::ByteBuffer & output);
120 static RCF::Mutex sIoMutex;
129 class RCF_EXPORT LogToDebugWindow :
public LogTarget
133 void write(
const RCF::ByteBuffer & output);
137 class RCF_EXPORT LogToEventLog :
public LogTarget
140 LogToEventLog(
const std::string & appName,
int eventLogLevel);
143 LogTarget * clone()
const;
144 void write(
const RCF::ByteBuffer & output);
147 std::string mAppName;
158 LogToFile(
const std::string & filePath,
bool flushAfterEachWrite =
false);
161 void write(
const RCF::ByteBuffer & output);
167 std::string mFilePath;
173 typedef boost::function1<void, const RCF::ByteBuffer &> LogFunctor;
175 class RCF_EXPORT LogToFunc :
public LogTarget
178 LogToFunc(LogFunctor logFunctor);
180 void write(
const RCF::ByteBuffer & output);
183 LogFunctor mLogFunctor;
189 class RCF_EXPORT LogEntry
193 LogEntry(
int name,
int level);
194 LogEntry(
int name,
int level,
const char * szFile,
int line,
const char * szFunc);
199 const LogEntry& operator<<(
const T& t)
const
201 const_cast<RCF::MemOstream&
>(*mpOstream) << t;
205 #ifndef BOOST_NO_STD_WSTRING
206 const LogEntry& operator<<(
const std::wstring& t)
const
208 const_cast<RCF::MemOstream&
>(*mpOstream) << RCF::wstringToString(t);
214 typedef std::ostream& (*Pfn)(std::ostream&);
215 const LogEntry& operator<<(Pfn pfn)
const
217 const_cast<RCF::MemOstream&
>(*mpOstream) << pfn;
221 RCF::MemOstream & getOstream()
228 friend class LogManager;
237 RCF::ThreadId mThreadId;
239 boost::uint32_t mTimeMs;
241 RCF::MemOstream * mpOstream;
247 typedef boost::function2<void, const LogEntry &, RCF::ByteBuffer&> LogFormatFunctor;
249 class RCF_EXPORT Logger :
public boost::enable_shared_from_this<Logger>
252 Logger(
int name,
int level,
const LogTarget& logTarget,
const std::string & logFormat =
"");
253 Logger(
int name,
int level,
const LogTarget& logTarget, LogFormatFunctor logFormatFunctor);
255 Logger(
int name,
int level, LogTargetPtr logTargetPtr,
const std::string & logFormat =
"");
256 Logger(
int name,
int level, LogTargetPtr logTargetPtr, LogFormatFunctor logFormatFunctor);
258 void setName(
int name);
259 void setLevel(
int level);
260 void setTarget(
const LogTarget & logTarget);
261 void setFormat(
const std::string & logFormat);
264 int getLevel()
const;
265 const LogTarget& getTarget()
const;
266 std::string getFormat()
const;
268 void write(
const LogEntry & logEntry);
278 LogTargetPtr mTargetPtr;
280 LogFormatFunctor mFormatFunctor;
283 typedef boost::shared_ptr<Logger> LoggerPtr;
289 LogNameValue(
const char * name,
const T & value) :
298 friend std::ostream& operator<<(std::ostream & os,
const LogNameValue& lnv)
300 os <<
"(" << lnv.mName <<
" = " << lnv.mValue <<
")";
306 LogNameValue<T> makeNameValue(
const char * name,
const T & value)
308 return LogNameValue<T>(name, value);
311 #define NAMEVALUE(x) RCF::makeNameValue(#x, x)
313 class LogVarsFunctor :
public util::VariableArgMacroFunctor
317 LogVarsFunctor() : mLogEntry(0, 0, NULL, 0, NULL)
321 LogVarsFunctor(
int name,
int level,
const char * file,
int line,
const char * szFunc) :
322 mLogEntry(name, level, file, line, szFunc)
328 if (mArgs->tellp() > 0)
330 mLogEntry <<
" [Args: ";
331 mLogEntry.getOstream().write(mArgs->str(), mArgs->tellp());
337 const LogVarsFunctor & operator<<(
const T & t)
const
339 const_cast<LogEntry &
>(mLogEntry) << t;
343 typedef std::ostream& (*Pfn)(std::ostream&);
344 const LogVarsFunctor & operator<<(Pfn pfn)
const
346 const_cast<LogEntry &
>(mLogEntry) << pfn;
354 #if defined(_MSC_VER)
355 #pragma warning(push)
356 #pragma warning(disable: 4355) // warning C4355: 'this' : used in base member initializer list
359 DECLARE_VARIABLE_ARG_MACRO( UTIL_LOG, LogVarsFunctor );
361 #if defined(_MSC_VER)
365 #if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
366 #define UTIL_LOG_GCC_33_HACK (const RCF::VariableArgMacro<RCF::LogVarsFunctor> &)
368 #define UTIL_LOG_GCC_33_HACK
371 #define UTIL_LOG(name, level) \
372 if (RCF::LogManager::instance().isEnabled(name, level)) \
373 UTIL_LOG_GCC_33_HACK RCF::VariableArgMacro<RCF::LogVarsFunctor>( \
374 name, level, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) \
375 .cast( (RCF::VariableArgMacro<RCF::LogVarsFunctor> *) NULL ) \
378 #define UTIL_LOG_A(x) UTIL_LOG_OP(x, B)
379 #define UTIL_LOG_B(x) UTIL_LOG_OP(x, A)
380 #define UTIL_LOG_OP(x, next) UTIL_LOG_A.notify_((x), #x).UTIL_LOG_ ## next
384 typedef LogToDebugWindow DefaultLogTarget;
386 typedef LogToStdout DefaultLogTarget;
393 RCF_EXPORT
void enableLogging(
394 const LogTarget & logTarget = DefaultLogTarget(),
396 const std::string & logFormat =
"");
399 RCF_EXPORT
void disableLogging();
403 #endif // ! INCLUDE_UTIL_LOG_HPP