// ********************************************************************** // // Copyright (c) 2003-present ZeroC, Inc. All rights reserved. // // ********************************************************************** #ifndef ICE_LOGGER_UTIL_H #define ICE_LOGGER_UTIL_H #include #include #include #include namespace Ice { /** * Base class for logger output utility classes. * \headerfile Ice/Ice.h */ class ICE_API LoggerOutputBase : private IceUtil::noncopyable { public: /** Obtains the collected output. */ std::string str() const; /// \cond INTERNAL std::ostringstream& _stream(); // For internal use only. Don't use in your code. /// \endcond private: std::ostringstream _os; }; /// \cond INTERNAL ICE_API LoggerOutputBase& loggerInsert(LoggerOutputBase& out, const IceUtil::Exception& ex); template struct IsException { static char testex(IceUtil::Exception*); static long testex(...); static const bool value = sizeof(testex(static_cast(0))) == sizeof(char); }; template struct LoggerOutputInserter { static inline LoggerOutputBase& insert(LoggerOutputBase& out, const T& val) { out._stream() << val; return out; } }; // Partial specialization template struct LoggerOutputInserter { static inline LoggerOutputBase& insert(LoggerOutputBase& out, const T& ex) { return loggerInsert(out, ex); } }; template inline LoggerOutputBase& operator<<(LoggerOutputBase& out, const T& val) { return LoggerOutputInserter::value>::insert(out, val); } #ifdef ICE_CPP11_MAPPING template::value>::type* = nullptr> inline LoggerOutputBase& operator<<(LoggerOutputBase& os, const ::std::shared_ptr& p) #else template inline LoggerOutputBase& operator<<(LoggerOutputBase& os, const ::IceInternal::ProxyHandle& p) #endif { return os << (p ? p->ice_toString() : ""); } inline LoggerOutputBase& operator<<(LoggerOutputBase& out, const ::std::exception& ex) { out._stream() << ex.what(); return out; } ICE_API LoggerOutputBase& operator<<(LoggerOutputBase&, std::ios_base& (*)(std::ios_base&)); /// \endcond /** * Collects output and flushes it via a logger method. * \headerfile Ice/Ice.h */ template class LoggerOutput : public LoggerOutputBase { public: inline LoggerOutput(const LPtr& lptr) : _logger(lptr) {} inline ~LoggerOutput() { flush(); } /** Flushes the colleted output to the logger method. */ inline void flush() { std::string s = _stream().str(); if(!s.empty()) { L& ref = *_logger; (ref.*output)(s); } _stream().str(""); } private: LPtr _logger; }; /** Flushes output to Logger::print. */ typedef LoggerOutput Print; /** Flushes output to Logger::warning. */ typedef LoggerOutput Warning; /** Flushes output to Logger::error. */ typedef LoggerOutput Error; /** * Flushes output to Logger::trace. * \headerfile Ice/Ice.h */ class ICE_API Trace : public LoggerOutputBase { public: Trace(const LoggerPtr&, const std::string&); ~Trace(); void flush(); private: LoggerPtr _logger; std::string _category; }; /** * A special plug-in that installs a logger during a communicator's initialization. * Both initialize and destroy are no-op. See Ice::InitializationData. * \headerfile Ice/Ice.h */ class ICE_API LoggerPlugin : public Ice::Plugin { public: /** * Constructs the plug-in with a target communicator and a logger. * @param communicator The communicator in which to install the logger. * @param logger The logger to be installed. */ LoggerPlugin(const CommunicatorPtr& communicator, const LoggerPtr& logger); /** This method is a no-op. */ virtual void initialize(); /** This method is a no-op. */ virtual void destroy(); }; } #endif