summaryrefslogtreecommitdiffstats
path: root/src/crimson/common/logclient.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/crimson/common/logclient.h')
-rw-r--r--src/crimson/common/logclient.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/crimson/common/logclient.h b/src/crimson/common/logclient.h
new file mode 100644
index 000000000..ab9b25091
--- /dev/null
+++ b/src/crimson/common/logclient.h
@@ -0,0 +1,232 @@
+#ifndef CEPH_LOGCLIENT_H
+#define CEPH_LOGCLIENT_H
+
+#include "common/LogEntry.h"
+#include "common/ostream_temp.h"
+#include "common/ref.h"
+#include "include/health.h"
+#include "crimson/net/Fwd.h"
+
+#include <seastar/core/future.hh>
+#include <seastar/core/gate.hh>
+#include <seastar/core/lowres_clock.hh>
+#include <seastar/core/shared_ptr.hh>
+#include <seastar/core/timer.hh>
+
+class LogClient;
+class MLog;
+class MLogAck;
+class Message;
+struct uuid_d;
+struct Connection;
+
+class LogChannel;
+
+namespace ceph {
+namespace logging {
+ class Graylog;
+}
+}
+
+template<typename Message> using Ref = boost::intrusive_ptr<Message>;
+namespace crimson::net {
+ class Messenger;
+}
+
+enum class log_flushing_t {
+ NO_FLUSH,
+ FLUSH
+};
+
+int parse_log_client_options(CephContext *cct,
+ std::map<std::string,std::string> &log_to_monitors,
+ std::map<std::string,std::string> &log_to_syslog,
+ std::map<std::string,std::string> &log_channels,
+ std::map<std::string,std::string> &log_prios,
+ std::map<std::string,std::string> &log_to_graylog,
+ std::map<std::string,std::string> &log_to_graylog_host,
+ std::map<std::string,std::string> &log_to_graylog_port,
+ uuid_d &fsid,
+ std::string &host);
+
+/** Manage where we output to and at which priority
+ *
+ * Not to be confused with the LogClient, which is the almighty coordinator
+ * of channels. We just deal with the boring part of the logging: send to
+ * syslog, send to file, generate LogEntry and queue it for the LogClient.
+ *
+ * Past queueing the LogEntry, the LogChannel is done with the whole thing.
+ * LogClient will deal with sending and handling of LogEntries.
+ */
+class LogChannel : public LoggerSinkSet
+{
+public:
+ LogChannel(LogClient *lc, const std::string &channel);
+ LogChannel(LogClient *lc, const std::string &channel,
+ const std::string &facility, const std::string &prio);
+
+ OstreamTemp debug() {
+ return OstreamTemp(CLOG_DEBUG, this);
+ }
+ void debug(std::stringstream &s) final {
+ do_log(CLOG_DEBUG, s);
+ }
+ /**
+ * Convenience function mapping health status to
+ * the appropriate cluster log severity.
+ */
+ OstreamTemp health(health_status_t health) {
+ switch(health) {
+ case HEALTH_OK:
+ return info();
+ case HEALTH_WARN:
+ return warn();
+ case HEALTH_ERR:
+ return error();
+ default:
+ // Invalid health_status_t value
+ ceph_abort();
+ }
+ }
+ OstreamTemp info() final {
+ return OstreamTemp(CLOG_INFO, this);
+ }
+ void info(std::stringstream &s) final {
+ do_log(CLOG_INFO, s);
+ }
+ OstreamTemp warn() final {
+ return OstreamTemp(CLOG_WARN, this);
+ }
+ void warn(std::stringstream &s) final {
+ do_log(CLOG_WARN, s);
+ }
+ OstreamTemp error() final {
+ return OstreamTemp(CLOG_ERROR, this);
+ }
+ void error(std::stringstream &s) final {
+ do_log(CLOG_ERROR, s);
+ }
+ OstreamTemp sec() final {
+ return OstreamTemp(CLOG_SEC, this);
+ }
+ void sec(std::stringstream &s) final {
+ do_log(CLOG_SEC, s);
+ }
+
+ void set_log_to_monitors(bool v);
+ void set_log_to_syslog(bool v) {
+ log_to_syslog = v;
+ }
+ void set_log_channel(const std::string& v) {
+ log_channel = v;
+ }
+ void set_log_prio(const std::string& v) {
+ log_prio = v;
+ }
+ void set_syslog_facility(const std::string& v) {
+ syslog_facility = v;
+ }
+ const std::string& get_log_prio() const { return log_prio; }
+ const std::string& get_log_channel() const { return log_channel; }
+ const std::string& get_syslog_facility() const { return syslog_facility; }
+ bool must_log_to_syslog() const { return log_to_syslog; }
+ /**
+ * Do we want to log to syslog?
+ *
+ * @return true if log_to_syslog is true and both channel and prio
+ * are not empty; false otherwise.
+ */
+ bool do_log_to_syslog() {
+ return must_log_to_syslog() &&
+ !log_prio.empty() && !log_channel.empty();
+ }
+ bool must_log_to_monitors() { return log_to_monitors; }
+
+ bool do_log_to_graylog() {
+ return (graylog != nullptr);
+ }
+
+ using Ref = seastar::lw_shared_ptr<LogChannel>;
+
+ /**
+ * update config values from parsed k/v std::map for each config option
+ *
+ * Pick out the relevant value based on our channel.
+ */
+ void update_config(std::map<std::string,std::string> &log_to_monitors,
+ std::map<std::string,std::string> &log_to_syslog,
+ std::map<std::string,std::string> &log_channels,
+ std::map<std::string,std::string> &log_prios,
+ std::map<std::string,std::string> &log_to_graylog,
+ std::map<std::string,std::string> &log_to_graylog_host,
+ std::map<std::string,std::string> &log_to_graylog_port,
+ uuid_d &fsid,
+ std::string &host);
+
+ void do_log(clog_type prio, std::stringstream& ss) final;
+ void do_log(clog_type prio, const std::string& s) final;
+
+private:
+ LogClient *parent;
+ std::string log_channel;
+ std::string log_prio;
+ std::string syslog_facility;
+ bool log_to_syslog;
+ bool log_to_monitors;
+ seastar::shared_ptr<ceph::logging::Graylog> graylog;
+};
+
+using LogChannelRef = LogChannel::Ref;
+
+class LogClient
+{
+public:
+ enum logclient_flag_t {
+ NO_FLAGS = 0,
+ FLAG_MON = 0x1,
+ };
+
+ LogClient(crimson::net::Messenger *m, logclient_flag_t flags);
+
+ virtual ~LogClient() = default;
+
+ seastar::future<> handle_log_ack(Ref<MLogAck> m);
+ MessageURef get_mon_log_message(log_flushing_t flush_flag);
+ bool are_pending() const;
+
+ LogChannelRef create_channel() {
+ return create_channel(CLOG_CHANNEL_DEFAULT);
+ }
+
+ LogChannelRef create_channel(const std::string& name);
+
+ void destroy_channel(const std::string& name) {
+ channels.erase(name);
+ }
+
+ void shutdown() {
+ channels.clear();
+ }
+
+ uint64_t get_next_seq();
+ entity_addrvec_t get_myaddrs() const;
+ const EntityName& get_myname() const;
+ entity_name_t get_myrank();
+ version_t queue(LogEntry &entry);
+ void reset();
+ seastar::future<> set_fsid(const uuid_d& fsid);
+
+private:
+ MessageURef _get_mon_log_message();
+
+ crimson::net::Messenger *messenger;
+ bool is_mon;
+ version_t last_log_sent;
+ version_t last_log;
+ std::deque<LogEntry> log_queue;
+
+ std::map<std::string, LogChannelRef> channels;
+ uuid_d m_fsid;
+};
+#endif
+