summaryrefslogtreecommitdiff
path: root/src/common/LogClient.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/LogClient.cc')
-rw-r--r--src/common/LogClient.cc87
1 files changed, 77 insertions, 10 deletions
diff --git a/src/common/LogClient.cc b/src/common/LogClient.cc
index 921adcc5485..26f054411d0 100644
--- a/src/common/LogClient.cc
+++ b/src/common/LogClient.cc
@@ -27,6 +27,7 @@
#include <iostream>
#include <errno.h>
#include <sys/stat.h>
+#include <syslog.h>
#ifdef DARWIN
#include <sys/param.h>
@@ -37,25 +38,59 @@
#include "config.h"
-void LogClient::log(log_type type, const char *s)
+/*
+ * Given a clog log_type, return the equivalent syslog priority
+ */
+static inline int clog_type_to_syslog_prio(clog_type t)
+{
+ switch (t) {
+ case CLOG_DEBUG:
+ return LOG_DEBUG;
+ case CLOG_INFO:
+ return LOG_INFO;
+ case CLOG_WARN:
+ return LOG_WARNING;
+ case CLOG_ERROR:
+ return LOG_ERR;
+ case CLOG_SEC:
+ return LOG_CRIT;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+LogClientTemp::LogClientTemp(clog_type type_, LogClient &parent_)
+ : type(type_), parent(parent_)
{
- string str(s);
- log(type, str);
}
-void LogClient::log(log_type type, stringstream& ss)
+LogClientTemp::LogClientTemp(const LogClientTemp &rhs)
+ : type(rhs.type), parent(rhs.parent)
+{
+ // don't want to-- nor can we-- copy the ostringstream
+}
+
+LogClientTemp::~LogClientTemp()
+{
+ if (ss.peek() != EOF)
+ parent.do_log(type, ss);
+}
+
+void LogClient::do_log(clog_type type, std::stringstream& ss)
{
while (!ss.eof()) {
string s;
getline(ss, s);
- log(type, s);
+ if (!s.empty())
+ do_log(type, s);
}
}
-void LogClient::log(log_type type, string& s)
+void LogClient::do_log(clog_type type, const std::string& s)
{
Mutex::Locker l(log_lock);
- dout(0) << "log " << (log_type)type << " : " << s << dendl;
+ dout(0) << "log " << type << " : " << s << dendl;
LogEntry e;
e.who = messenger->get_myinst();
e.stamp = g_clock.now();
@@ -76,6 +111,33 @@ void LogClient::send_log()
void LogClient::_send_log()
{
+ if (g_conf.clog_to_syslog)
+ _send_log_to_syslog();
+ if (g_conf.clog_to_monitors)
+ _send_log_to_monitors();
+}
+
+void LogClient::_send_log_to_syslog()
+{
+ std::deque<LogEntry>::const_reverse_iterator rbegin = log_queue.rbegin();
+ std::deque<LogEntry>::const_reverse_iterator rend = log_queue.rend();
+ for (std::deque<LogEntry>::const_reverse_iterator a = rbegin; a != rend; ++a) {
+ const LogEntry entry(*a);
+ if (entry.seq < last_syslog)
+ break;
+ ostringstream oss;
+ oss << entry;
+ string str(oss.str());
+ syslog(clog_type_to_syslog_prio(entry.type) | LOG_USER, "%s", str.c_str());
+ }
+ if (rbegin != rend) {
+ const LogEntry entry(*rbegin);
+ last_syslog = entry.seq;
+ }
+}
+
+void LogClient::_send_log_to_monitors()
+{
if (log_queue.empty())
return;
MLog *log = new MLog(monmap->get_fsid(), log_queue);
@@ -96,9 +158,14 @@ void LogClient::handle_log_ack(MLogAck *m)
dout(10) << "handle_log_ack " << *m << dendl;
version_t last = m->last;
- while (log_queue.size() && log_queue.begin()->seq <= last) {
- dout(10) << " logged " << log_queue.front() << dendl;
- log_queue.pop_front();
+
+ deque<LogEntry>::iterator q = log_queue.begin();
+ while (q != log_queue.end()) {
+ const LogEntry &entry(*q);
+ if (entry.seq > last)
+ break;
+ dout(10) << " logged " << entry << dendl;
+ q = log_queue.erase(q);
}
m->put();
}