X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FKM_log.cpp;h=d820dba50df002aaf82e652c664d765e829dd386;hb=1f46216c14f3582f47b290c5ab4dd0c9a02b90f4;hp=0c4a3bf69f427cbfabdfb54dbc4c36688fbe035d;hpb=4564a68b8a586b49715f39fb84271db61fc109b7;p=asdcplib.git diff --git a/src/KM_log.cpp b/src/KM_log.cpp index 0c4a3bf..d820dba 100755 --- a/src/KM_log.cpp +++ b/src/KM_log.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2007, John Hurst +Copyright (c) 2004-2011, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,9 +31,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include #include +#include +#include #ifdef KM_WIN32 #define getpid GetCurrentProcessId @@ -56,49 +59,80 @@ Kumu::ILogSink::vLogf(LogType_t type, const char* fmt, va_list* list) //------------------------------------------------------------------------------------------ // -static Kumu::ILogSink* s_DefaultLogSink; +static Kumu::Mutex s_DefaultLogSinkLock; +static Kumu::ILogSink* s_DefaultLogSink = 0; static Kumu::StdioLogSink s_StderrLogSink; // void Kumu::SetDefaultLogSink(ILogSink* Sink) { - s_DefaultLogSink = Sink; + AutoMutex L(s_DefaultLogSinkLock); + s_DefaultLogSink = Sink; } // Returns the internal default sink. Kumu::ILogSink& Kumu::DefaultLogSink() { + AutoMutex L(s_DefaultLogSinkLock); + if ( s_DefaultLogSink == 0 ) s_DefaultLogSink = &s_StderrLogSink; return *s_DefaultLogSink; } + +//------------------------------------------------------------------------------------------ +// + +void +Kumu::EntryListLogSink::WriteEntry(const LogEntry& Entry) +{ + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); + + if ( Entry.TestFilter(m_filter) ) + m_Target.push_back(Entry); +} + //------------------------------------------------------------------------------------------ // void Kumu::StdioLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; - if ( Entry.CreateStringWithFilter(m_filter, buf) ) - fputs(buf.c_str(), m_stream); + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); + + if ( Entry.TestFilter(m_filter) ) + { + Entry.CreateStringWithOptions(buf, m_options); + fputs(buf.c_str(), m_stream); + fflush(m_stream); + } } //--------------------------------------------------------------------------------- #ifdef KM_WIN32 // +// http://www.codeguru.com/forum/showthread.php?t=231165 +// void Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; - if ( Entry.CreateStringWithFilter(m_filter, buf) ) - ::OutputDebugString(buf.c_str()); + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); + + if ( Entry.TestFilter(m_filter) ) + { + Entry.CreateStringWithOptions(buf, m_options); + ::OutputDebugStringA(buf.c_str()); + } } #endif @@ -110,86 +144,208 @@ Kumu::WinDbgLogSink::WriteEntry(const LogEntry& Entry) void Kumu::StreamLogSink::WriteEntry(const LogEntry& Entry) { - AutoMutex L(m_Lock); std::string buf; - if ( Entry.CreateStringWithFilter(m_filter, buf) ) - write(m_fd, buf.c_str(), buf.size()); + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); + + if ( Entry.TestFilter(m_filter) ) + { + Entry.CreateStringWithOptions(buf, m_options); + ssize_t n = write(m_fd, buf.c_str(), buf.size()); + assert(n==buf.size()); + } +} + +// foolin with symbols +//------------------------------------------------------------------------------------------ +#include +int const SYSLOG_ALERT = LOG_ALERT; +int const SYSLOG_CRIT = LOG_CRIT; +int const SYSLOG_ERR = LOG_ERR; +int const SYSLOG_WARNING = LOG_WARNING; +int const SYSLOG_NOTICE = LOG_NOTICE; +int const SYSLOG_INFO = LOG_INFO; +int const SYSLOG_DEBUG = LOG_DEBUG; +#undef LOG_ALERT +#undef LOG_CRIT +#undef LOG_ERR +#undef LOG_WARNING +#undef LOG_NOTICE +#undef LOG_INFO +#undef LOG_DEBUG +//------------------------------------------------------------------------------------------ + +Kumu::SyslogLogSink::SyslogLogSink(const std::string& source_name, int facility) +{ + if ( facility == 0 ) + facility = LOG_DAEMON; + + openlog(source_name.c_str(), LOG_CONS|LOG_NDELAY||LOG_PID, facility); +} + +Kumu::SyslogLogSink::~SyslogLogSink() +{ + closelog(); +} + +// +void +Kumu::SyslogLogSink::WriteEntry(const LogEntry& Entry) +{ + int priority; + + switch ( Entry.Type ) + { + case Kumu::LOG_ALERT: priority = SYSLOG_ALERT; break; + case Kumu::LOG_CRIT: priority = SYSLOG_CRIT; break; + case Kumu::LOG_ERROR: priority = SYSLOG_ERR; break; + case Kumu::LOG_WARN: priority = SYSLOG_WARNING; break; + case Kumu::LOG_NOTICE: priority = SYSLOG_NOTICE; break; + case Kumu::LOG_INFO: priority = SYSLOG_INFO; break; + case Kumu::LOG_DEBUG: priority = SYSLOG_DEBUG; break; + } + + AutoMutex L(m_lock); + WriteEntryToListeners(Entry); + + if ( Entry.TestFilter(m_filter) ) + { + syslog(priority, "%s", Entry.Msg.substr(0, Entry.Msg.size() - 1).c_str()); + } } + +// +int +Kumu::SyslogNameToFacility(const std::string& facility_name) +{ + if ( facility_name == "LOG_DAEMON" ) return LOG_DAEMON; + if ( facility_name == "LOG_LOCAL0" ) return LOG_LOCAL0; + if ( facility_name == "LOG_LOCAL1" ) return LOG_LOCAL1; + if ( facility_name == "LOG_LOCAL2" ) return LOG_LOCAL2; + if ( facility_name == "LOG_LOCAL3" ) return LOG_LOCAL3; + if ( facility_name == "LOG_LOCAL4" ) return LOG_LOCAL4; + if ( facility_name == "LOG_LOCAL5" ) return LOG_LOCAL5; + if ( facility_name == "LOG_LOCAL6" ) return LOG_LOCAL6; + if ( facility_name == "LOG_LOCAL7" ) return LOG_LOCAL7; + + DefaultLogSink().Error("Unsupported facility name: %s, using default value LOG_DAEMON\n", facility_name.c_str()); + return LOG_DAEMON; +} + #endif //------------------------------------------------------------------------------------------ -bool -Kumu::LogEntry::CreateStringWithFilter(i32_t filter, std::string& out_buf) const +// +std::basic_ostream >& +Kumu::operator<<(std::basic_ostream >& strm, LogEntry const& Entry) { - const char* p = 0; + std::basic_ostringstream > s; + s.copyfmt(strm); + s.width(0); + std::string buf; + + s << Entry.CreateStringWithOptions(buf, LOG_OPTION_ALL); + strm << s.str(); + return strm; +} + +//------------------------------------------------------------------------------------------ + + +// +bool +Kumu::LogEntry::TestFilter(i32_t filter) const +{ switch ( Type ) { case LOG_CRIT: - if ( (filter & LOG_ALLOW_CRIT) != 0 ) - p = " CRT"; + if ( (filter & LOG_ALLOW_CRIT) == 0 ) + return false; break; case LOG_ALERT: - if ( (filter & LOG_ALLOW_ALERT) != 0 ) - p = " ALR"; + if ( (filter & LOG_ALLOW_ALERT) == 0 ) + return false; break; case LOG_NOTICE: - if ( (filter & LOG_ALLOW_NOTICE) != 0 ) - p = " NTC"; + if ( (filter & LOG_ALLOW_NOTICE) == 0 ) + return false; break; case LOG_ERROR: - if ( (filter & LOG_ALLOW_ERROR) != 0 ) - p = " ERR"; + if ( (filter & LOG_ALLOW_ERROR) == 0 ) + return false; break; case LOG_WARN: - if ( (filter & LOG_ALLOW_WARN) != 0 ) - p = " WRN"; + if ( (filter & LOG_ALLOW_WARN) == 0 ) + return false; break; case LOG_INFO: - if ( (filter & LOG_ALLOW_INFO) != 0 ) - p = " INF"; + if ( (filter & LOG_ALLOW_INFO) == 0 ) + return false; break; case LOG_DEBUG: - if ( (filter & LOG_ALLOW_DEBUG) != 0 ) - p = " DBG"; + if ( (filter & LOG_ALLOW_DEBUG) == 0 ) + return false; break; - default: - if ( (filter & LOG_ALLOW_DEFAULT) != 0 ) - p = " DFL"; - break; } - if ( p == 0 ) - return false; - - char buf[64]; - out_buf = "["; - - if ( (filter & LOG_ALLOW_TIMESTAMP) != 0 ) - { - Timestamp Now; - out_buf += Now.EncodeString(buf, 64); + return true; +} - if ( (filter & LOG_ALLOW_PID) != 0 ) - out_buf += " "; - } +// +std::string& +Kumu::LogEntry::CreateStringWithOptions(std::string& out_buf, i32_t opt) const +{ + out_buf.erase(); - if ( (filter & LOG_ALLOW_PID) != 0 ) + if ( opt != 0 ) { - snprintf(buf, 64, "%d", PID); - out_buf += buf; + char buf[64]; + + if ( (opt & LOG_OPTION_TIMESTAMP) != 0 ) + { + Timestamp Now; + out_buf += Now.EncodeString(buf, 64); + } + + if ( (opt & LOG_OPTION_PID) != 0 ) + { + if ( ! out_buf.empty() ) out_buf += " "; + snprintf(buf, 64, "%d", PID); + out_buf += buf; + } + + if ( (opt & LOG_OPTION_TYPE) != 0 ) + { + if ( ! out_buf.empty() ) out_buf += " "; + + switch ( Type ) + { + case LOG_CRIT: out_buf += "CRT"; break; + case LOG_ALERT: out_buf += "ALR"; break; + case LOG_NOTICE: out_buf += "NTC"; break; + case LOG_ERROR: out_buf += "ERR"; break; + case LOG_WARN: out_buf += "WRN"; break; + case LOG_INFO: out_buf += "INF"; break; + case LOG_DEBUG: out_buf += "DBG"; break; + default: out_buf += "DFL"; break; + } + } + + out_buf.insert(0, "["); + out_buf += "]: "; } - out_buf += "] " + Msg; - return true; + out_buf += Msg; + return out_buf; }