#include <iostream>
#include <errno.h>
#include <sys/stat.h>
+#include <syslog.h>
#ifdef DARWIN
#include <sys/param.h>
#include "config.h"
+/*
+ * 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_)
{
}
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;
LogClient(Messenger *m, MonMap *mm, MonClient *mc, enum logclient_flag_t flags) :
messenger(m), monmap(mm), monc(mc), is_synchronous(flags & FLAG_SYNC),
- log_lock("LogClient::log_lock"), last_log(0) { }
+ log_lock("LogClient::log_lock"), last_log(0), last_syslog(0) { }
void send_log();
void handle_log_ack(MLogAck *m);
void do_log(clog_type type, const std::string& s);
bool ms_dispatch(Message *m);
void _send_log();
+ void _send_log_to_syslog();
+ void _send_log_to_monitors();
void ms_handle_connect(Connection *con);
bool ms_handle_reset(Connection *con) { return false; }
void ms_handle_remote_reset(Connection *con) {}
bool is_synchronous;
Mutex log_lock;
version_t last_log;
+ uint64_t last_syslog;
std::deque<LogEntry> log_queue;
friend class LogClientTemp;
OPTION(log_sym_history, 0, OPT_INT, 10),
OPTION(log_to_stdout, 0, OPT_BOOL, true),
OPTION(log_per_instance, 0, OPT_BOOL, false),
+ OPTION(clog_to_monitors, 0, OPT_BOOL, true),
+ OPTION(clog_to_syslog, 0, OPT_BOOL, false),
OPTION(pid_file, 0, OPT_STR, "/var/run/ceph/$type.$id.pid"),
OPTION(conf, 'c', OPT_STR, "/etc/ceph/ceph.conf, ~/.ceph/config, ceph.conf"),
OPTION(chdir, 0, OPT_STR, "/"),
bool log_to_stdout;
bool log_per_instance;
+ bool clog_to_monitors;
+ bool clog_to_syslog;
+
const char *pid_file;
const char *conf;