]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/LogEntry.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / common / LogEntry.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 //
4 #include <syslog.h>
5 #include <boost/algorithm/string/predicate.hpp>
6
7 #include "LogEntry.h"
8 #include "Formatter.h"
9 #include "include/stringify.h"
10
11 using std::list;
12 using std::map;
13 using std::make_pair;
14 using std::pair;
15 using std::string;
16
17 using ceph::bufferlist;
18 using ceph::decode;
19 using ceph::encode;
20 using ceph::Formatter;
21
22 // ----
23 // LogEntryKey
24
25 void LogEntryKey::dump(Formatter *f) const
26 {
27 f->dump_stream("rank") << rank;
28 f->dump_stream("stamp") << stamp;
29 f->dump_unsigned("seq", seq);
30 }
31
32 void LogEntryKey::generate_test_instances(list<LogEntryKey*>& o)
33 {
34 o.push_back(new LogEntryKey);
35 o.push_back(new LogEntryKey(entity_name_t::CLIENT(1234), utime_t(1,2), 34));
36 }
37
38 clog_type LogEntry::str_to_level(std::string const &str)
39 {
40 std::string level_str = str;
41 std::transform(level_str.begin(), level_str.end(), level_str.begin(),
42 [](char c) {return std::tolower(c);});
43
44 if (level_str == "debug") {
45 return CLOG_DEBUG;
46 } else if (level_str == "info") {
47 return CLOG_INFO;
48 } else if (level_str == "sec") {
49 return CLOG_SEC;
50 } else if (level_str == "warn" || level_str == "warning") {
51 return CLOG_WARN;
52 } else if (level_str == "error" || level_str == "err") {
53 return CLOG_ERROR;
54 } else {
55 return CLOG_UNKNOWN;
56 }
57 }
58
59 // ----
60
61 int clog_type_to_syslog_level(clog_type t)
62 {
63 switch (t) {
64 case CLOG_DEBUG:
65 return LOG_DEBUG;
66 case CLOG_INFO:
67 return LOG_INFO;
68 case CLOG_WARN:
69 return LOG_WARNING;
70 case CLOG_ERROR:
71 return LOG_ERR;
72 case CLOG_SEC:
73 return LOG_CRIT;
74 default:
75 ceph_abort();
76 return 0;
77 }
78 }
79
80 clog_type string_to_clog_type(const string& s)
81 {
82 if (boost::iequals(s, "debug") ||
83 boost::iequals(s, "dbg"))
84 return CLOG_DEBUG;
85 if (boost::iequals(s, "info") ||
86 boost::iequals(s, "inf"))
87 return CLOG_INFO;
88 if (boost::iequals(s, "warning") ||
89 boost::iequals(s, "warn") ||
90 boost::iequals(s, "wrn"))
91 return CLOG_WARN;
92 if (boost::iequals(s, "error") ||
93 boost::iequals(s, "err"))
94 return CLOG_ERROR;
95 if (boost::iequals(s, "security") ||
96 boost::iequals(s, "sec"))
97 return CLOG_SEC;
98
99 return CLOG_UNKNOWN;
100 }
101
102 int string_to_syslog_level(string s)
103 {
104 if (boost::iequals(s, "debug"))
105 return LOG_DEBUG;
106 if (boost::iequals(s, "info") ||
107 boost::iequals(s, "notice"))
108 return LOG_INFO;
109 if (boost::iequals(s, "warning") ||
110 boost::iequals(s, "warn"))
111 return LOG_WARNING;
112 if (boost::iequals(s, "error") ||
113 boost::iequals(s, "err"))
114 return LOG_ERR;
115 if (boost::iequals(s, "crit") ||
116 boost::iequals(s, "critical") ||
117 boost::iequals(s, "emerg"))
118 return LOG_CRIT;
119
120 // err on the side of noise!
121 return LOG_DEBUG;
122 }
123
124 int string_to_syslog_facility(string s)
125 {
126 if (boost::iequals(s, "auth"))
127 return LOG_AUTH;
128 if (boost::iequals(s, "authpriv"))
129 return LOG_AUTHPRIV;
130 if (boost::iequals(s, "cron"))
131 return LOG_CRON;
132 if (boost::iequals(s, "daemon"))
133 return LOG_DAEMON;
134 if (boost::iequals(s, "ftp"))
135 return LOG_FTP;
136 if (boost::iequals(s, "kern"))
137 return LOG_KERN;
138 if (boost::iequals(s, "local0"))
139 return LOG_LOCAL0;
140 if (boost::iequals(s, "local1"))
141 return LOG_LOCAL1;
142 if (boost::iequals(s, "local2"))
143 return LOG_LOCAL2;
144 if (boost::iequals(s, "local3"))
145 return LOG_LOCAL3;
146 if (boost::iequals(s, "local4"))
147 return LOG_LOCAL4;
148 if (boost::iequals(s, "local5"))
149 return LOG_LOCAL5;
150 if (boost::iequals(s, "local6"))
151 return LOG_LOCAL6;
152 if (boost::iequals(s, "local7"))
153 return LOG_LOCAL7;
154 if (boost::iequals(s, "lpr"))
155 return LOG_LPR;
156 if (boost::iequals(s, "mail"))
157 return LOG_MAIL;
158 if (boost::iequals(s, "news"))
159 return LOG_NEWS;
160 if (boost::iequals(s, "syslog"))
161 return LOG_SYSLOG;
162 if (boost::iequals(s, "user"))
163 return LOG_USER;
164 if (boost::iequals(s, "uucp"))
165 return LOG_UUCP;
166
167 // default to USER
168 return LOG_USER;
169 }
170
171 string clog_type_to_string(clog_type t)
172 {
173 switch (t) {
174 case CLOG_DEBUG:
175 return "debug";
176 case CLOG_INFO:
177 return "info";
178 case CLOG_WARN:
179 return "warn";
180 case CLOG_ERROR:
181 return "err";
182 case CLOG_SEC:
183 return "crit";
184 default:
185 ceph_abort();
186 return 0;
187 }
188 }
189
190 void LogEntry::log_to_syslog(string level, string facility) const
191 {
192 int min = string_to_syslog_level(level);
193 int l = clog_type_to_syslog_level(prio);
194 if (l <= min) {
195 int f = string_to_syslog_facility(facility);
196 syslog(l | f, "%s %s %llu : %s",
197 name.to_cstr(),
198 stringify(rank).c_str(),
199 (long long unsigned)seq,
200 msg.c_str());
201 }
202 }
203
204 void LogEntry::encode(bufferlist& bl, uint64_t features) const
205 {
206 assert(HAVE_FEATURE(features, SERVER_NAUTILUS));
207 ENCODE_START(5, 5, bl);
208 __u16 t = prio;
209 encode(name, bl);
210 encode(rank, bl);
211 encode(addrs, bl, features);
212 encode(stamp, bl);
213 encode(seq, bl);
214 encode(t, bl);
215 encode(msg, bl);
216 encode(channel, bl);
217 ENCODE_FINISH(bl);
218 }
219
220 void LogEntry::decode(bufferlist::const_iterator& bl)
221 {
222 DECODE_START_LEGACY_COMPAT_LEN(5, 2, 2, bl);
223 if (struct_v < 5) {
224 __u16 t;
225 entity_inst_t who;
226 decode(who, bl);
227 rank = who.name;
228 addrs.v.clear();
229 addrs.v.push_back(who.addr);
230 decode(stamp, bl);
231 decode(seq, bl);
232 decode(t, bl);
233 prio = (clog_type)t;
234 decode(msg, bl);
235 if (struct_v >= 3) {
236 decode(channel, bl);
237 } else {
238 // prior to having logging channels we only had a cluster log.
239 // Ensure we keep that appearance when the other party has no
240 // clue of what a 'channel' is.
241 channel = CLOG_CHANNEL_CLUSTER;
242 }
243 if (struct_v >= 4) {
244 decode(name, bl);
245 }
246 } else {
247 __u16 t;
248 decode(name, bl);
249 decode(rank, bl);
250 decode(addrs, bl);
251 decode(stamp, bl);
252 decode(seq, bl);
253 decode(t, bl);
254 prio = (clog_type)t;
255 decode(msg, bl);
256 decode(channel, bl);
257 }
258 DECODE_FINISH(bl);
259 }
260
261 void LogEntry::dump(Formatter *f) const
262 {
263 f->dump_stream("name") << name;
264 f->dump_stream("rank") << rank;
265 f->dump_object("addrs", addrs);
266 f->dump_stream("stamp") << stamp;
267 f->dump_unsigned("seq", seq);
268 f->dump_string("channel", channel);
269 f->dump_stream("priority") << prio;
270 f->dump_string("message", msg);
271 }
272
273 void LogEntry::generate_test_instances(list<LogEntry*>& o)
274 {
275 o.push_back(new LogEntry);
276 }
277
278
279 // -----
280
281 void LogSummary::build_ordered_tail_legacy(list<LogEntry> *tail) const
282 {
283 tail->clear();
284 // channel -> (begin, end)
285 map<string,pair<list<pair<uint64_t,LogEntry>>::const_iterator,
286 list<pair<uint64_t,LogEntry>>::const_iterator>> pos;
287 for (auto& i : tail_by_channel) {
288 pos.emplace(i.first, make_pair(i.second.begin(), i.second.end()));
289 }
290 while (true) {
291 uint64_t min_seq = 0;
292 list<pair<uint64_t,LogEntry>>::const_iterator *minp = 0;
293 for (auto& i : pos) {
294 if (i.second.first == i.second.second) {
295 continue;
296 }
297 if (min_seq == 0 || i.second.first->first < min_seq) {
298 min_seq = i.second.first->first;
299 minp = &i.second.first;
300 }
301 }
302 if (min_seq == 0) {
303 break; // done
304 }
305 tail->push_back((*minp)->second);
306 ++(*minp);
307 }
308 }
309
310 void LogSummary::encode(bufferlist& bl, uint64_t features) const
311 {
312 assert(HAVE_FEATURE(features, SERVER_MIMIC));
313 ENCODE_START(4, 3, bl);
314 encode(version, bl);
315 encode(seq, bl);
316 encode(tail_by_channel, bl, features);
317 encode(channel_info, bl);
318 recent_keys.encode(bl);
319 ENCODE_FINISH(bl);
320 }
321
322 void LogSummary::decode(bufferlist::const_iterator& bl)
323 {
324 DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl);
325 decode(version, bl);
326 decode(seq, bl);
327 decode(tail_by_channel, bl);
328 if (struct_v >= 4) {
329 decode(channel_info, bl);
330 recent_keys.decode(bl);
331 }
332 DECODE_FINISH(bl);
333 keys.clear();
334 for (auto& i : tail_by_channel) {
335 for (auto& e : i.second) {
336 keys.insert(e.second.key());
337 }
338 }
339 }
340
341 void LogSummary::dump(Formatter *f) const
342 {
343 f->dump_unsigned("version", version);
344 f->open_object_section("tail_by_channel");
345 for (auto& i : tail_by_channel) {
346 f->open_object_section(i.first.c_str());
347 for (auto& j : i.second) {
348 string s = stringify(j.first);
349 f->dump_object(s.c_str(), j.second);
350 }
351 f->close_section();
352 }
353 f->close_section();
354 }
355
356 void LogSummary::generate_test_instances(list<LogSummary*>& o)
357 {
358 o.push_back(new LogSummary);
359 // more!
360 }