summaryrefslogtreecommitdiffstats
path: root/src/common/LogEntry.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/LogEntry.h212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/common/LogEntry.h b/src/common/LogEntry.h
new file mode 100644
index 000000000..3ddebbd30
--- /dev/null
+++ b/src/common/LogEntry.h
@@ -0,0 +1,212 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_LOGENTRY_H
+#define CEPH_LOGENTRY_H
+
+#include <fmt/format.h>
+
+#include "include/utime.h"
+#include "msg/msg_fmt.h"
+#include "msg/msg_types.h"
+#include "common/entity_name.h"
+#include "ostream_temp.h"
+#include "LRUSet.h"
+
+namespace ceph {
+ class Formatter;
+}
+
+static const std::string CLOG_CHANNEL_NONE = "none";
+static const std::string CLOG_CHANNEL_DEFAULT = "cluster";
+static const std::string CLOG_CHANNEL_CLUSTER = "cluster";
+static const std::string CLOG_CHANNEL_AUDIT = "audit";
+
+// this is the key name used in the config options for the default, e.g.
+// default=true foo=false bar=false
+static const std::string CLOG_CONFIG_DEFAULT_KEY = "default";
+
+/*
+ * Given a clog log_type, return the equivalent syslog priority
+ */
+int clog_type_to_syslog_level(clog_type t);
+
+clog_type string_to_clog_type(const std::string& s);
+int string_to_syslog_level(std::string s);
+int string_to_syslog_facility(std::string s);
+
+std::string clog_type_to_string(clog_type t);
+
+
+struct LogEntryKey {
+private:
+ uint64_t _hash = 0;
+
+ void _calc_hash() {
+ std::hash<entity_name_t> h;
+ _hash = seq + h(rank);
+ }
+
+ entity_name_t rank;
+ utime_t stamp;
+ uint64_t seq = 0;
+
+public:
+ LogEntryKey() {}
+ LogEntryKey(const entity_name_t& w, utime_t t, uint64_t s)
+ : rank(w), stamp(t), seq(s) {
+ _calc_hash();
+ }
+
+ uint64_t get_hash() const {
+ return _hash;
+ }
+
+ void dump(ceph::Formatter *f) const;
+ static void generate_test_instances(std::list<LogEntryKey*>& o);
+
+ friend bool operator==(const LogEntryKey& l, const LogEntryKey& r) {
+ return l.rank == r.rank && l.stamp == r.stamp && l.seq == r.seq;
+ }
+
+ void encode(bufferlist& bl) const {
+ using ceph::encode;
+ encode(rank, bl);
+ encode(stamp, bl);
+ encode(seq, bl);
+ }
+ void decode(bufferlist::const_iterator &p) {
+ using ceph::decode;
+ decode(rank, p);
+ decode(stamp, p);
+ decode(seq, p);
+ }
+};
+WRITE_CLASS_ENCODER(LogEntryKey)
+
+
+namespace std {
+template<> struct hash<LogEntryKey> {
+ size_t operator()(const LogEntryKey& r) const {
+ return r.get_hash();
+ }
+};
+} // namespace std
+
+struct LogEntry {
+ EntityName name;
+ entity_name_t rank;
+ entity_addrvec_t addrs;
+ utime_t stamp;
+ uint64_t seq;
+ clog_type prio;
+ std::string msg;
+ std::string channel;
+
+ LogEntry() : seq(0), prio(CLOG_DEBUG) {}
+
+ LogEntryKey key() const { return LogEntryKey(rank, stamp, seq); }
+
+ void log_to_syslog(std::string level, std::string facility) const;
+
+ void encode(ceph::buffer::list& bl, uint64_t features) const;
+ void decode(ceph::buffer::list::const_iterator& bl);
+ void dump(ceph::Formatter *f) const;
+ static void generate_test_instances(std::list<LogEntry*>& o);
+ static clog_type str_to_level(std::string const &str);
+};
+WRITE_CLASS_ENCODER_FEATURES(LogEntry)
+
+struct LogSummary {
+ version_t version;
+
+ // ---- pre-quincy ----
+ // channel -> [(seq#, entry), ...]
+ std::map<std::string,std::list<std::pair<uint64_t,LogEntry>>> tail_by_channel;
+ uint64_t seq = 0;
+ ceph::unordered_set<LogEntryKey> keys;
+
+ // ---- quincy+ ----
+ LRUSet<LogEntryKey> recent_keys;
+ std::map<std::string, std::pair<uint64_t,uint64_t>> channel_info; // channel -> [begin, end)
+
+ LogSummary() : version(0) {}
+
+ void build_ordered_tail_legacy(std::list<LogEntry> *tail) const;
+
+ void add_legacy(const LogEntry& e) {
+ keys.insert(e.key());
+ tail_by_channel[e.channel].push_back(std::make_pair(++seq, e));
+ }
+ void prune(size_t max) {
+ for (auto& i : tail_by_channel) {
+ while (i.second.size() > max) {
+ keys.erase(i.second.front().second.key());
+ i.second.pop_front();
+ }
+ }
+ recent_keys.prune(max);
+ }
+ bool contains(const LogEntryKey& k) const {
+ return keys.count(k) || recent_keys.contains(k);
+ }
+
+ void encode(ceph::buffer::list& bl, uint64_t features) const;
+ void decode(ceph::buffer::list::const_iterator& bl);
+ void dump(ceph::Formatter *f) const;
+ static void generate_test_instances(std::list<LogSummary*>& o);
+};
+WRITE_CLASS_ENCODER_FEATURES(LogSummary)
+
+inline std::ostream& operator<<(std::ostream& out, const clog_type t)
+{
+ switch (t) {
+ case CLOG_DEBUG:
+ return out << "[DBG]";
+ case CLOG_INFO:
+ return out << "[INF]";
+ case CLOG_SEC:
+ return out << "[SEC]";
+ case CLOG_WARN:
+ return out << "[WRN]";
+ case CLOG_ERROR:
+ return out << "[ERR]";
+ default:
+ return out << "[???]";
+ }
+}
+
+inline std::ostream& operator<<(std::ostream& out, const LogEntry& e)
+{
+ return out << e.stamp << " " << e.name << " (" << e.rank << ") "
+ << e.seq << " : "
+ << e.channel << " " << e.prio << " " << e.msg;
+}
+
+template <> struct fmt::formatter<EntityName> : fmt::formatter<std::string_view> {
+ template <typename FormatContext>
+ auto format(const EntityName& e, FormatContext& ctx) {
+ return formatter<std::string_view>::format(e.to_str(), ctx);
+ }
+};
+
+template <> struct fmt::formatter<LogEntry> : fmt::formatter<std::string_view> {
+ template <typename FormatContext>
+ auto format(const LogEntry& e, FormatContext& ctx) {
+ return fmt::format_to(ctx.out(), "{} {} ({}) {} : {} {} {}",
+ e.stamp, e.name, e.rank, e.seq, e.channel, e.prio, e.msg);
+ }
+};
+
+#endif