]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
31f18b77 | 18 | #include <atomic> |
7c673cae | 19 | #include "common/LogEntry.h" |
11fdf7f2 | 20 | #include "common/ceph_mutex.h" |
9f95a23c TL |
21 | #include "common/ostream_temp.h" |
22 | #include "common/ref.h" | |
181888fb | 23 | #include "include/health.h" |
7c673cae | 24 | |
7c673cae FG |
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 | ||
20effc67 TL |
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 | }; | |
7c673cae FG |
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 | */ | |
1e59de90 | 63 | class LogChannel : public LoggerSinkSet |
7c673cae FG |
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 | ||
1e59de90 | 73 | OstreamTemp debug() final { |
9f95a23c | 74 | return OstreamTemp(CLOG_DEBUG, this); |
7c673cae | 75 | } |
1e59de90 | 76 | void debug(std::stringstream &s) final { |
7c673cae FG |
77 | do_log(CLOG_DEBUG, s); |
78 | } | |
181888fb FG |
79 | /** |
80 | * Convenience function mapping health status to | |
81 | * the appropriate cluster log severity. | |
82 | */ | |
9f95a23c | 83 | OstreamTemp health(health_status_t health) { |
181888fb FG |
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 | } | |
1e59de90 | 96 | OstreamTemp info() final { |
9f95a23c | 97 | return OstreamTemp(CLOG_INFO, this); |
7c673cae | 98 | } |
1e59de90 | 99 | void info(std::stringstream &s) final { |
7c673cae FG |
100 | do_log(CLOG_INFO, s); |
101 | } | |
1e59de90 | 102 | OstreamTemp warn() final { |
9f95a23c | 103 | return OstreamTemp(CLOG_WARN, this); |
7c673cae | 104 | } |
1e59de90 | 105 | void warn(std::stringstream &s) final { |
7c673cae FG |
106 | do_log(CLOG_WARN, s); |
107 | } | |
1e59de90 | 108 | OstreamTemp error() final { |
9f95a23c | 109 | return OstreamTemp(CLOG_ERROR, this); |
7c673cae | 110 | } |
1e59de90 | 111 | void error(std::stringstream &s) final { |
7c673cae FG |
112 | do_log(CLOG_ERROR, s); |
113 | } | |
1e59de90 | 114 | OstreamTemp sec() final { |
9f95a23c | 115 | return OstreamTemp(CLOG_SEC, this); |
7c673cae | 116 | } |
1e59de90 | 117 | void sec(std::stringstream &s) final { |
7c673cae FG |
118 | do_log(CLOG_SEC, s); |
119 | } | |
120 | ||
f67539c2 | 121 | void set_log_to_monitors(bool v); |
7c673cae FG |
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 | ||
9f95a23c | 154 | typedef std::shared_ptr<LogChannel> Ref; |
7c673cae FG |
155 | |
156 | /** | |
20effc67 TL |
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. | |
7c673cae | 160 | * |
20effc67 | 161 | * Return a collection of configuration strings. |
7c673cae | 162 | */ |
20effc67 | 163 | clog_targets_conf_t parse_client_options(CephContext* conf_cct); |
7c673cae | 164 | |
1e59de90 TL |
165 | void do_log(clog_type prio, std::stringstream& ss) final; |
166 | void do_log(clog_type prio, const std::string& s) final; | |
7c673cae FG |
167 | |
168 | private: | |
169 | CephContext *cct; | |
170 | LogClient *parent; | |
11fdf7f2 | 171 | ceph::mutex channel_lock = ceph::make_mutex("LogChannel::channel_lock"); |
7c673cae FG |
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; | |
9f95a23c | 177 | std::shared_ptr<ceph::logging::Graylog> graylog; |
7c673cae | 178 | |
20effc67 TL |
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); | |
7c673cae FG |
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, | |
20effc67 TL |
198 | logclient_flag_t flags); |
199 | ||
7c673cae FG |
200 | virtual ~LogClient() { |
201 | channels.clear(); | |
202 | } | |
203 | ||
204 | bool handle_log_ack(MLogAck *m); | |
9f95a23c | 205 | ceph::ref_t<Message> get_mon_log_message(bool flush); |
7c673cae FG |
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(); | |
11fdf7f2 | 233 | entity_addrvec_t get_myaddrs(); |
31f18b77 | 234 | const EntityName& get_myname(); |
11fdf7f2 | 235 | entity_name_t get_myrank(); |
7c673cae | 236 | version_t queue(LogEntry &entry); |
f67539c2 | 237 | void reset(); |
7c673cae FG |
238 | |
239 | private: | |
9f95a23c | 240 | ceph::ref_t<Message> _get_mon_log_message(); |
7c673cae FG |
241 | void _send_to_mon(); |
242 | ||
243 | CephContext *cct; | |
244 | Messenger *messenger; | |
245 | MonMap *monmap; | |
246 | bool is_mon; | |
11fdf7f2 | 247 | ceph::mutex log_lock = ceph::make_mutex("LogClient::log_lock"); |
7c673cae | 248 | version_t last_log_sent; |
b5b8bbf5 | 249 | version_t last_log; |
7c673cae FG |
250 | std::deque<LogEntry> log_queue; |
251 | ||
252 | std::map<std::string, LogChannelRef> channels; | |
253 | ||
254 | }; | |
255 | #endif |