diff --git a/websocketpp/logger/basic.hpp b/websocketpp/logger/basic.hpp index 3d8eacb..ac3710a 100644 --- a/websocketpp/logger/basic.hpp +++ b/websocketpp/logger/basic.hpp @@ -99,7 +99,7 @@ public: m_dynamic_channels &= ~channels; } - void write(level channel, std::string const & msg) { + virtual void write(level channel, std::string const & msg) { scoped_lock_type lock(m_lock); if (!this->dynamic_test(channel)) { return; } *m_out << "[" << timestamp << "] " @@ -108,7 +108,7 @@ public: m_out->flush(); } - void write(level channel, char const * msg) { + virtual void write(level channel, char const * msg) { scoped_lock_type lock(m_lock); if (!this->dynamic_test(channel)) { return; } *m_out << "[" << timestamp << "] " @@ -124,10 +124,13 @@ public: bool dynamic_test(level channel) { return ((channel & m_dynamic_channels) != 0); } -private: + +protected: typedef typename concurrency::scoped_lock_type scoped_lock_type; typedef typename concurrency::mutex_type mutex_type; + mutex_type m_lock; +private: // The timestamp does not include the time zone, because on Windows with the // default registry settings, the time zone would be written out in full, // which would be obnoxiously verbose. @@ -145,8 +148,6 @@ private: #endif } - mutex_type m_lock; - level const m_static_channels; level m_dynamic_channels; std::ostream * m_out; diff --git a/websocketpp/logger/syslog.hpp b/websocketpp/logger/syslog.hpp new file mode 100644 index 0000000..61c4b7a --- /dev/null +++ b/websocketpp/logger/syslog.hpp @@ -0,0 +1,77 @@ +#ifndef WEBSOCKETPP_LOGGER_SYSLOG_HPP +#define WEBSOCKETPP_LOGGER_SYSLOG_HPP + +#include + +#include + +#include +#include + +namespace websocketpp { +namespace log { + +/// Basic logger that outputs to syslog +template +class syslog : public basic { +public: + syslog(channel_type_hint::value h = + channel_type_hint::access) + : basic(h), channel_type_hint_(h) {} + + syslog(level c, channel_type_hint::value h = + channel_type_hint::access) + : basic(c, h), channel_type_hint_(h) {} + + void write(level channel, std::string const & msg) override { + write(channel, msg.c_str()); + } + + void write(level channel, char const * msg) override { + scoped_lock_type lock(basic::m_lock); + if (!this->dynamic_test(channel)) { return; } + ::syslog(syslog_priority(channel), "[%s] %s", names::channel_name(channel), msg); + } + +private: + typedef typename basic::scoped_lock_type scoped_lock_type; + const int kDefaultSyslogLevel = LOG_INFO; + + const int syslog_priority(level channel) const { + if (channel_type_hint_ == channel_type_hint::access) { + return syslog_priority_access(channel); + } else { + return syslog_priority_error(channel); + } + } + + const int syslog_priority_error(level channel) const { + switch (channel) { + case elevel::devel: + return LOG_DEBUG; + case elevel::library: + return LOG_DEBUG; + case elevel::info: + return LOG_INFO; + case elevel::warn: + return LOG_WARNING; + case elevel::rerror: + return LOG_ERR; + case elevel::fatal: + return LOG_CRIT; + default: + return kDefaultSyslogLevel; + } + } + + _WEBSOCKETPP_CONSTEXPR_TOKEN_ int syslog_priority_access(level channel) const { + return kDefaultSyslogLevel; + } + + channel_type_hint::value channel_type_hint_; +}; + +} // log +} // websocketpp + +#endif // WEBSOCKETPP_LOGGER_SYSLOG_HPP