X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FKM_log.h;h=9279f300a41c6d0e9736a53be8f969adf7e22184;hb=5d86f368b2bade7bca7700c74f198ef7f4129b44;hp=fdcfd13d10c7a33e17171658f486f640dd8a7641;hpb=a48b3a939a031ec369c58b054c126d7dec963a18;p=asdcplib.git diff --git a/src/KM_log.h b/src/KM_log.h index fdcfd13..9279f30 100755 --- a/src/KM_log.h +++ b/src/KM_log.h @@ -39,6 +39,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #define LOG_MSG_IMPL(t) \ va_list args; \ @@ -87,6 +88,7 @@ namespace Kumu LOG_NOTICE, // application user info LOG_ALERT, // application non-fatal or near-miss error LOG_CRIT, // application fatal error + LOG_MAX }; @@ -149,6 +151,18 @@ namespace Kumu protected: i32_t m_filter; i32_t m_options; + Mutex m_lock; + std::set m_listeners; + + // you must obtain m_lock BEFORE calling this from your own WriteEntry + void WriteEntryToListeners(const LogEntry& entry) + { + std::set::iterator i; + for ( i = m_listeners.begin(); i != m_listeners.end(); ++i ) + (*i)->WriteEntry(entry); + } + + KM_NO_COPY_CONSTRUCT(ILogSink); public: ILogSink() : m_filter(LOG_ALLOW_ALL), m_options(LOG_OPTION_NONE) {} @@ -162,6 +176,19 @@ namespace Kumu void UnsetOptionFlag(i32_t o) { m_options &= ~o; } bool TestOptionFlag(i32_t o) const { return ((m_options & o) == o); } + void AddListener(ILogSink& s) { + if ( &s != this ) + { + AutoMutex l(m_lock); + m_listeners.insert(&s); + } + } + + void DelListener(ILogSink& s) { + AutoMutex l(m_lock); + m_listeners.erase(&s); + } + // library messages void Error(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ERROR); } void Warn(const char* fmt, ...) { LOG_MSG_IMPL(LOG_WARN); } @@ -190,51 +217,35 @@ namespace Kumu ILogSink& DefaultLogSink(); - // Sets a log sink as the default until the object is destroyed. - // The original default sink is saved and then restored on delete. - class LogSinkContext - { - KM_NO_COPY_CONSTRUCT(LogSinkContext); - LogSinkContext(); - ILogSink* m_orig; + // attach a log sink as a listener until deleted + class LogSinkListenContext + { + ILogSink* m_log_source; + ILogSink* m_sink; + KM_NO_COPY_CONSTRUCT(LogSinkListenContext); + LogSinkListenContext(); + + public: + LogSinkListenContext(ILogSink& source, ILogSink& sink) + { + m_log_source = &source; + m_sink = &sink; + m_log_source->AddListener(*m_sink); + } + + ~LogSinkListenContext() + { + m_log_source->DelListener(*m_sink); + } + }; - public: - LogSinkContext(ILogSink& sink) { - m_orig = &DefaultLogSink(); - SetDefaultLogSink(&sink); - } - - ~LogSinkContext() { - SetDefaultLogSink(m_orig); - } - }; //------------------------------------------------------------------------------------------ // - // write messages to two subordinate log sinks - class TeeLogSink : public ILogSink - { - KM_NO_COPY_CONSTRUCT(TeeLogSink); - TeeLogSink(); - - ILogSink& m_a; - ILogSink& m_b; - - public: - TeeLogSink(ILogSink& a, ILogSink& b) : m_a(a), m_b(b) {} - virtual ~TeeLogSink() {} - - void WriteEntry(const LogEntry& Entry) { - m_a.WriteEntry(Entry); - m_b.WriteEntry(Entry); - } - }; - // collect log messages into the given list, does not test filter class EntryListLogSink : public ILogSink { - Mutex m_Lock; LogEntryList& m_Target; KM_NO_COPY_CONSTRUCT(EntryListLogSink); EntryListLogSink(); @@ -250,7 +261,6 @@ namespace Kumu // write messages to a POSIX stdio stream class StdioLogSink : public ILogSink { - Mutex m_Lock; FILE* m_stream; KM_NO_COPY_CONSTRUCT(StdioLogSink); @@ -266,7 +276,6 @@ namespace Kumu // write messages to the Win32 debug stream class WinDbgLogSink : public ILogSink { - Mutex m_Lock; KM_NO_COPY_CONSTRUCT(WinDbgLogSink); public: @@ -281,7 +290,6 @@ namespace Kumu // write messages to a POSIX file descriptor class StreamLogSink : public ILogSink { - Mutex m_Lock; int m_fd; KM_NO_COPY_CONSTRUCT(StreamLogSink); StreamLogSink(); @@ -292,6 +300,22 @@ namespace Kumu void WriteEntry(const LogEntry&); }; + + // write messages to the syslog facility + class SyslogLogSink : public ILogSink + { + KM_NO_COPY_CONSTRUCT(SyslogLogSink); + SyslogLogSink(); + + public: + SyslogLogSink(const std::string& source_name, int facility); + virtual ~SyslogLogSink(); + void WriteEntry(const LogEntry&); + }; + + // convert a string into the appropriate syslog facility id + int SyslogNameToFacility(const std::string& facility_name); + #endif