]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/LogClient.h
update sources to v12.2.1
[ceph.git] / ceph / src / common / LogClient.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_LOGCLIENT_H
16 #define CEPH_LOGCLIENT_H
17
18 #include <atomic>
19 #include "common/LogEntry.h"
20 #include "common/Mutex.h"
21 #include "include/health.h"
22
23 class LogClient;
24 class MLog;
25 class MLogAck;
26 class Messenger;
27 class MonMap;
28 class Message;
29 struct uuid_d;
30 struct Connection;
31
32 class LogChannel;
33
34 namespace ceph {
35 namespace logging {
36 class Graylog;
37 }
38 }
39
40 int parse_log_client_options(CephContext *cct,
41 map<string,string> &log_to_monitors,
42 map<string,string> &log_to_syslog,
43 map<string,string> &log_channels,
44 map<string,string> &log_prios,
45 map<string,string> &log_to_graylog,
46 map<string,string> &log_to_graylog_host,
47 map<string,string> &log_to_graylog_port,
48 uuid_d &fsid,
49 string &host);
50
51 class LogClientTemp
52 {
53 public:
54 LogClientTemp(clog_type type_, LogChannel &parent_);
55 LogClientTemp(const LogClientTemp &rhs);
56 ~LogClientTemp();
57
58 template<typename T>
59 std::ostream& operator<<(const T& rhs)
60 {
61 return ss << rhs;
62 }
63
64 private:
65 clog_type type;
66 LogChannel &parent;
67 stringstream ss;
68 };
69
70 /** Manage where we output to and at which priority
71 *
72 * Not to be confused with the LogClient, which is the almighty coordinator
73 * of channels. We just deal with the boring part of the logging: send to
74 * syslog, send to file, generate LogEntry and queue it for the LogClient.
75 *
76 * Past queueing the LogEntry, the LogChannel is done with the whole thing.
77 * LogClient will deal with sending and handling of LogEntries.
78 */
79 class LogChannel
80 {
81 public:
82
83 LogChannel(CephContext *cct, LogClient *lc, const std::string &channel);
84 LogChannel(CephContext *cct, LogClient *lc,
85 const std::string &channel,
86 const std::string &facility,
87 const std::string &prio);
88
89 LogClientTemp debug() {
90 return LogClientTemp(CLOG_DEBUG, *this);
91 }
92 void debug(std::stringstream &s) {
93 do_log(CLOG_DEBUG, s);
94 }
95 /**
96 * Convenience function mapping health status to
97 * the appropriate cluster log severity.
98 */
99 LogClientTemp health(health_status_t health) {
100 switch(health) {
101 case HEALTH_OK:
102 return info();
103 case HEALTH_WARN:
104 return warn();
105 case HEALTH_ERR:
106 return error();
107 default:
108 // Invalid health_status_t value
109 ceph_abort();
110 }
111 }
112 LogClientTemp info() {
113 return LogClientTemp(CLOG_INFO, *this);
114 }
115 void info(std::stringstream &s) {
116 do_log(CLOG_INFO, s);
117 }
118 LogClientTemp warn() {
119 return LogClientTemp(CLOG_WARN, *this);
120 }
121 void warn(std::stringstream &s) {
122 do_log(CLOG_WARN, s);
123 }
124 LogClientTemp error() {
125 return LogClientTemp(CLOG_ERROR, *this);
126 }
127 void error(std::stringstream &s) {
128 do_log(CLOG_ERROR, s);
129 }
130 LogClientTemp sec() {
131 return LogClientTemp(CLOG_SEC, *this);
132 }
133 void sec(std::stringstream &s) {
134 do_log(CLOG_SEC, s);
135 }
136
137 void set_log_to_monitors(bool v) {
138 log_to_monitors = v;
139 }
140 void set_log_to_syslog(bool v) {
141 log_to_syslog = v;
142 }
143 void set_log_channel(const std::string& v) {
144 log_channel = v;
145 }
146 void set_log_prio(const std::string& v) {
147 log_prio = v;
148 }
149 void set_syslog_facility(const std::string& v) {
150 syslog_facility = v;
151 }
152 std::string get_log_prio() { return log_prio; }
153 std::string get_log_channel() { return log_channel; }
154 std::string get_syslog_facility() { return syslog_facility; }
155 bool must_log_to_syslog() { return log_to_syslog; }
156 /**
157 * Do we want to log to syslog?
158 *
159 * @return true if log_to_syslog is true and both channel and prio
160 * are not empty; false otherwise.
161 */
162 bool do_log_to_syslog() {
163 return must_log_to_syslog() &&
164 !log_prio.empty() && !log_channel.empty();
165 }
166 bool must_log_to_monitors() { return log_to_monitors; }
167
168 bool do_log_to_graylog() {
169 return (graylog != nullptr);
170 }
171
172 typedef shared_ptr<LogChannel> Ref;
173
174 /**
175 * update config values from parsed k/v map for each config option
176 *
177 * Pick out the relevant value based on our channel.
178 */
179 void update_config(map<string,string> &log_to_monitors,
180 map<string,string> &log_to_syslog,
181 map<string,string> &log_channels,
182 map<string,string> &log_prios,
183 map<string,string> &log_to_graylog,
184 map<string,string> &log_to_graylog_host,
185 map<string,string> &log_to_graylog_port,
186 uuid_d &fsid,
187 string &host);
188
189 void do_log(clog_type prio, std::stringstream& ss);
190 void do_log(clog_type prio, const std::string& s);
191
192 private:
193 CephContext *cct;
194 LogClient *parent;
195 Mutex channel_lock;
196 std::string log_channel;
197 std::string log_prio;
198 std::string syslog_facility;
199 bool log_to_syslog;
200 bool log_to_monitors;
201 shared_ptr<ceph::logging::Graylog> graylog;
202
203
204 friend class LogClientTemp;
205 };
206
207 typedef LogChannel::Ref LogChannelRef;
208
209 class LogClient
210 {
211 public:
212 enum logclient_flag_t {
213 NO_FLAGS = 0,
214 FLAG_MON = 0x1,
215 };
216
217 LogClient(CephContext *cct, Messenger *m, MonMap *mm,
218 enum logclient_flag_t flags);
219 virtual ~LogClient() {
220 channels.clear();
221 }
222
223 bool handle_log_ack(MLogAck *m);
224 Message *get_mon_log_message(bool flush);
225 bool are_pending();
226
227 LogChannelRef create_channel() {
228 return create_channel(CLOG_CHANNEL_DEFAULT);
229 }
230
231 LogChannelRef create_channel(const std::string& name) {
232 LogChannelRef c;
233 if (channels.count(name))
234 c = channels[name];
235 else {
236 c = std::make_shared<LogChannel>(cct, this, name);
237 channels[name] = c;
238 }
239 return c;
240 }
241
242 void destroy_channel(const std::string& name) {
243 if (channels.count(name))
244 channels.erase(name);
245 }
246
247 void shutdown() {
248 channels.clear();
249 }
250
251 uint64_t get_next_seq();
252 const entity_inst_t& get_myinst();
253 const EntityName& get_myname();
254 version_t queue(LogEntry &entry);
255
256 private:
257 Message *_get_mon_log_message();
258 void _send_to_mon();
259
260 CephContext *cct;
261 Messenger *messenger;
262 MonMap *monmap;
263 bool is_mon;
264 Mutex log_lock;
265 version_t last_log_sent;
266 version_t last_log;
267 std::deque<LogEntry> log_queue;
268
269 std::map<std::string, LogChannelRef> channels;
270
271 };
272 #endif