summaryrefslogtreecommitdiff
path: root/asdcplib/src/KM_log.cpp
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-07-16 19:25:13 +0100
committerCarl Hetherington <cth@carlh.net>2012-07-16 19:25:13 +0100
commitec1097e8426461b854b38e7b14bc73995c365e0a (patch)
tree19c8e41ff4061f48ba23524bc8e38f5398c1f21a /asdcplib/src/KM_log.cpp
parent7d48446b5efdf795df1ce22d6d9ed3ebe85d3381 (diff)
asdcplib 1.9.45
Diffstat (limited to 'asdcplib/src/KM_log.cpp')
-rwxr-xr-xasdcplib/src/KM_log.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/asdcplib/src/KM_log.cpp b/asdcplib/src/KM_log.cpp
new file mode 100755
index 00000000..e3608c4a
--- /dev/null
+++ b/asdcplib/src/KM_log.cpp
@@ -0,0 +1,379 @@
+/*
+Copyright (c) 2004-2011, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_log.cpp
+ \version $Id: KM_log.cpp,v 1.15 2011/03/08 19:03:47 jhurst Exp $
+ \brief message logging API
+ */
+
+#include <KM_util.h>
+#include <KM_log.h>
+#include <KM_mutex.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdarg.h>
+#include <iostream>
+#include <sstream>
+
+#ifdef KM_WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <unistd.h>
+#endif
+
+//------------------------------------------------------------------------------------------
+//
+
+void
+Kumu::ILogSink::vLogf(LogType_t type, const char* fmt, va_list* list)
+{
+ char buf[MaxLogLength];
+ vsnprintf(buf, MaxLogLength, fmt, *list);
+
+ WriteEntry(LogEntry(getpid(), type, buf));
+}
+
+//------------------------------------------------------------------------------------------
+//
+
+static Kumu::Mutex s_DefaultLogSinkLock;
+static Kumu::ILogSink* s_DefaultLogSink = 0;
+static Kumu::StdioLogSink s_StderrLogSink;
+
+//
+void
+Kumu::SetDefaultLogSink(ILogSink* 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);
+
+ 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.TestFilter(m_filter) )
+ {
+ Entry.CreateStringWithOptions(buf, m_options);
+ fputs(buf.c_str(), 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.TestFilter(m_filter) )
+ {
+ Entry.CreateStringWithOptions(buf, m_options);
+ ::OutputDebugStringA(buf.c_str());
+ }
+}
+#endif
+
+//------------------------------------------------------------------------------------------
+//
+
+#ifndef KM_WIN32
+//
+void
+Kumu::StreamLogSink::WriteEntry(const LogEntry& Entry)
+{
+ AutoMutex L(m_Lock);
+ std::string buf;
+
+ if ( Entry.TestFilter(m_filter) )
+ {
+ Entry.CreateStringWithOptions(buf, m_options);
+ write(m_fd, buf.c_str(), buf.size());
+ }
+}
+
+// foolin with symbols
+//------------------------------------------------------------------------------------------
+#include <syslog.h>
+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);
+
+ 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
+
+//------------------------------------------------------------------------------------------
+
+//
+std::basic_ostream<char, std::char_traits<char> >&
+Kumu::operator<<(std::basic_ostream<char, std::char_traits<char> >& strm, LogEntry const& Entry)
+{
+ std::basic_ostringstream<char, std::char_traits<char> > 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 )
+ return false;
+ break;
+
+ case LOG_ALERT:
+ if ( (filter & LOG_ALLOW_ALERT) == 0 )
+ return false;
+ break;
+
+ case LOG_NOTICE:
+ if ( (filter & LOG_ALLOW_NOTICE) == 0 )
+ return false;
+ break;
+
+ case LOG_ERROR:
+ if ( (filter & LOG_ALLOW_ERROR) == 0 )
+ return false;
+ break;
+
+ case LOG_WARN:
+ if ( (filter & LOG_ALLOW_WARN) == 0 )
+ return false;
+ break;
+
+ case LOG_INFO:
+ if ( (filter & LOG_ALLOW_INFO) == 0 )
+ return false;
+ break;
+
+ case LOG_DEBUG:
+ if ( (filter & LOG_ALLOW_DEBUG) == 0 )
+ return false;
+ break;
+
+ }
+
+ return true;
+}
+
+//
+std::string&
+Kumu::LogEntry::CreateStringWithOptions(std::string& out_buf, i32_t opt) const
+{
+ out_buf.erase();
+
+ if ( opt != 0 )
+ {
+ 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 out_buf;
+}
+
+
+//
+ui32_t
+Kumu::LogEntry::ArchiveLength() const
+{
+ return sizeof(ui32_t)
+ + EventTime.ArchiveLength()
+ + sizeof(ui32_t)
+ + sizeof(ui32_t) + Msg.size();
+}
+
+//
+bool
+Kumu::LogEntry::Archive(Kumu::MemIOWriter* Writer) const
+{
+ if ( ! Writer->WriteUi32BE(PID) ) return false;
+ if ( ! EventTime.Archive(Writer) ) return false;
+ if ( ! Writer->WriteUi32BE(Type) ) return false;
+ if ( ! ArchiveString(*Writer, Msg) ) return false;
+ return true;
+}
+
+//
+bool
+Kumu::LogEntry::Unarchive(Kumu::MemIOReader* Reader)
+{
+ if ( ! Reader->ReadUi32BE(&PID) ) return false;
+ if ( ! EventTime.Unarchive(Reader) ) return false;
+ if ( ! Reader->ReadUi32BE((ui32_t*)&Type) ) return false;
+ if ( ! UnarchiveString(*Reader, Msg) ) return false;
+ return true;
+}
+
+//
+// end
+//