]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/LogEntry.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / common / LogEntry.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_LOGENTRY_H
16 #define CEPH_LOGENTRY_H
17
18 #include <fmt/format.h>
19
20 #include "include/utime.h"
21 #include "msg/msg_fmt.h"
22 #include "msg/msg_types.h"
23 #include "common/entity_name.h"
24 #include "ostream_temp.h"
25 #include "LRUSet.h"
26
27 namespace ceph {
28 class Formatter;
29 }
30
31 static const std::string CLOG_CHANNEL_NONE = "none";
32 static const std::string CLOG_CHANNEL_DEFAULT = "cluster";
33 static const std::string CLOG_CHANNEL_CLUSTER = "cluster";
34 static const std::string CLOG_CHANNEL_AUDIT = "audit";
35
36 // this is the key name used in the config options for the default, e.g.
37 // default=true foo=false bar=false
38 static const std::string CLOG_CONFIG_DEFAULT_KEY = "default";
39
40 /*
41 * Given a clog log_type, return the equivalent syslog priority
42 */
43 int clog_type_to_syslog_level(clog_type t);
44
45 clog_type string_to_clog_type(const std::string& s);
46 int string_to_syslog_level(std::string s);
47 int string_to_syslog_facility(std::string s);
48
49 std::string clog_type_to_string(clog_type t);
50
51
52 struct LogEntryKey {
53 private:
54 uint64_t _hash = 0;
55
56 void _calc_hash() {
57 std::hash<entity_name_t> h;
58 _hash = seq + h(rank);
59 }
60
61 entity_name_t rank;
62 utime_t stamp;
63 uint64_t seq = 0;
64
65 public:
66 LogEntryKey() {}
67 LogEntryKey(const entity_name_t& w, utime_t t, uint64_t s)
68 : rank(w), stamp(t), seq(s) {
69 _calc_hash();
70 }
71
72 uint64_t get_hash() const {
73 return _hash;
74 }
75
76 void dump(ceph::Formatter *f) const;
77 static void generate_test_instances(std::list<LogEntryKey*>& o);
78
79 friend bool operator==(const LogEntryKey& l, const LogEntryKey& r) {
80 return l.rank == r.rank && l.stamp == r.stamp && l.seq == r.seq;
81 }
82
83 void encode(bufferlist& bl) const {
84 using ceph::encode;
85 encode(rank, bl);
86 encode(stamp, bl);
87 encode(seq, bl);
88 }
89 void decode(bufferlist::const_iterator &p) {
90 using ceph::decode;
91 decode(rank, p);
92 decode(stamp, p);
93 decode(seq, p);
94 }
95 };
96 WRITE_CLASS_ENCODER(LogEntryKey)
97
98
99 namespace std {
100 template<> struct hash<LogEntryKey> {
101 size_t operator()(const LogEntryKey& r) const {
102 return r.get_hash();
103 }
104 };
105 } // namespace std
106
107 struct LogEntry {
108 EntityName name;
109 entity_name_t rank;
110 entity_addrvec_t addrs;
111 utime_t stamp;
112 uint64_t seq;
113 clog_type prio;
114 std::string msg;
115 std::string channel;
116
117 LogEntry() : seq(0), prio(CLOG_DEBUG) {}
118
119 LogEntryKey key() const { return LogEntryKey(rank, stamp, seq); }
120
121 void log_to_syslog(std::string level, std::string facility) const;
122
123 void encode(ceph::buffer::list& bl, uint64_t features) const;
124 void decode(ceph::buffer::list::const_iterator& bl);
125 void dump(ceph::Formatter *f) const;
126 static void generate_test_instances(std::list<LogEntry*>& o);
127 static clog_type str_to_level(std::string const &str);
128 };
129 WRITE_CLASS_ENCODER_FEATURES(LogEntry)
130
131 struct LogSummary {
132 version_t version;
133
134 // ---- pre-quincy ----
135 // channel -> [(seq#, entry), ...]
136 std::map<std::string,std::list<std::pair<uint64_t,LogEntry>>> tail_by_channel;
137 uint64_t seq = 0;
138 ceph::unordered_set<LogEntryKey> keys;
139
140 // ---- quincy+ ----
141 LRUSet<LogEntryKey> recent_keys;
142 std::map<std::string, std::pair<uint64_t,uint64_t>> channel_info; // channel -> [begin, end)
143
144 LogSummary() : version(0) {}
145
146 void build_ordered_tail_legacy(std::list<LogEntry> *tail) const;
147
148 void add_legacy(const LogEntry& e) {
149 keys.insert(e.key());
150 tail_by_channel[e.channel].push_back(std::make_pair(++seq, e));
151 }
152 void prune(size_t max) {
153 for (auto& i : tail_by_channel) {
154 while (i.second.size() > max) {
155 keys.erase(i.second.front().second.key());
156 i.second.pop_front();
157 }
158 }
159 recent_keys.prune(max);
160 }
161 bool contains(const LogEntryKey& k) const {
162 return keys.count(k) || recent_keys.contains(k);
163 }
164
165 void encode(ceph::buffer::list& bl, uint64_t features) const;
166 void decode(ceph::buffer::list::const_iterator& bl);
167 void dump(ceph::Formatter *f) const;
168 static void generate_test_instances(std::list<LogSummary*>& o);
169 };
170 WRITE_CLASS_ENCODER_FEATURES(LogSummary)
171
172 inline std::ostream& operator<<(std::ostream& out, const clog_type t)
173 {
174 switch (t) {
175 case CLOG_DEBUG:
176 return out << "[DBG]";
177 case CLOG_INFO:
178 return out << "[INF]";
179 case CLOG_SEC:
180 return out << "[SEC]";
181 case CLOG_WARN:
182 return out << "[WRN]";
183 case CLOG_ERROR:
184 return out << "[ERR]";
185 default:
186 return out << "[???]";
187 }
188 }
189
190 inline std::ostream& operator<<(std::ostream& out, const LogEntry& e)
191 {
192 return out << e.stamp << " " << e.name << " (" << e.rank << ") "
193 << e.seq << " : "
194 << e.channel << " " << e.prio << " " << e.msg;
195 }
196
197 template <> struct fmt::formatter<EntityName> : fmt::formatter<std::string_view> {
198 template <typename FormatContext>
199 auto format(const EntityName& e, FormatContext& ctx) {
200 return formatter<std::string_view>::format(e.to_str(), ctx);
201 }
202 };
203
204 template <> struct fmt::formatter<LogEntry> : fmt::formatter<std::string_view> {
205 template <typename FormatContext>
206 auto format(const LogEntry& e, FormatContext& ctx) {
207 return fmt::format_to(ctx.out(), "{} {} ({}) {} : {} {} {}",
208 e.stamp, e.name, e.rank, e.seq, e.channel, e.prio, e.msg);
209 }
210 };
211
212 #endif