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