]>
Commit | Line | Data |
---|---|---|
224ce89b WB |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | // | |
7c673cae | 4 | #include <syslog.h> |
7c673cae FG |
5 | #include <boost/algorithm/string/predicate.hpp> |
6 | ||
7 | #include "LogEntry.h" | |
8 | #include "Formatter.h" | |
7c673cae FG |
9 | #include "include/stringify.h" |
10 | ||
f67539c2 TL |
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 | ||
7c673cae FG |
22 | // ---- |
23 | // LogEntryKey | |
24 | ||
7c673cae FG |
25 | void LogEntryKey::dump(Formatter *f) const |
26 | { | |
11fdf7f2 | 27 | f->dump_stream("rank") << rank; |
7c673cae FG |
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); | |
11fdf7f2 | 35 | o.push_back(new LogEntryKey(entity_name_t::CLIENT(1234), utime_t(1,2), 34)); |
7c673cae FG |
36 | } |
37 | ||
224ce89b WB |
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 | ||
7c673cae FG |
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 | ||
20effc67 | 190 | void LogEntry::log_to_syslog(string level, string facility) const |
7c673cae FG |
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); | |
11fdf7f2 TL |
196 | syslog(l | f, "%s %s %llu : %s", |
197 | name.to_cstr(), | |
198 | stringify(rank).c_str(), | |
7c673cae FG |
199 | (long long unsigned)seq, |
200 | msg.c_str()); | |
201 | } | |
202 | } | |
203 | ||
204 | void LogEntry::encode(bufferlist& bl, uint64_t features) const | |
205 | { | |
20effc67 | 206 | assert(HAVE_FEATURE(features, SERVER_NAUTILUS)); |
11fdf7f2 | 207 | ENCODE_START(5, 5, bl); |
7c673cae | 208 | __u16 t = prio; |
11fdf7f2 TL |
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); | |
7c673cae FG |
217 | ENCODE_FINISH(bl); |
218 | } | |
219 | ||
11fdf7f2 | 220 | void LogEntry::decode(bufferlist::const_iterator& bl) |
7c673cae | 221 | { |
11fdf7f2 TL |
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 | } | |
7c673cae | 246 | } else { |
11fdf7f2 TL |
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); | |
31f18b77 | 257 | } |
7c673cae FG |
258 | DECODE_FINISH(bl); |
259 | } | |
260 | ||
261 | void LogEntry::dump(Formatter *f) const | |
262 | { | |
31f18b77 | 263 | f->dump_stream("name") << name; |
11fdf7f2 TL |
264 | f->dump_stream("rank") << rank; |
265 | f->dump_object("addrs", addrs); | |
7c673cae FG |
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 | ||
20effc67 | 281 | void LogSummary::build_ordered_tail_legacy(list<LogEntry> *tail) const |
11fdf7f2 TL |
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 | ||
7c673cae FG |
310 | void LogSummary::encode(bufferlist& bl, uint64_t features) const |
311 | { | |
20effc67 TL |
312 | assert(HAVE_FEATURE(features, SERVER_MIMIC)); |
313 | ENCODE_START(4, 3, bl); | |
11fdf7f2 TL |
314 | encode(version, bl); |
315 | encode(seq, bl); | |
316 | encode(tail_by_channel, bl, features); | |
20effc67 TL |
317 | encode(channel_info, bl); |
318 | recent_keys.encode(bl); | |
7c673cae FG |
319 | ENCODE_FINISH(bl); |
320 | } | |
321 | ||
11fdf7f2 | 322 | void LogSummary::decode(bufferlist::const_iterator& bl) |
7c673cae | 323 | { |
20effc67 | 324 | DECODE_START_LEGACY_COMPAT_LEN(4, 2, 2, bl); |
11fdf7f2 | 325 | decode(version, bl); |
20effc67 TL |
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); | |
11fdf7f2 | 331 | } |
7c673cae | 332 | DECODE_FINISH(bl); |
31f18b77 | 333 | keys.clear(); |
11fdf7f2 TL |
334 | for (auto& i : tail_by_channel) { |
335 | for (auto& e : i.second) { | |
336 | keys.insert(e.second.key()); | |
337 | } | |
31f18b77 | 338 | } |
7c673cae FG |
339 | } |
340 | ||
341 | void LogSummary::dump(Formatter *f) const | |
342 | { | |
343 | f->dump_unsigned("version", version); | |
11fdf7f2 TL |
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 | } | |
7c673cae FG |
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 | } |