]>
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" |
181888fb | 21 | #include "include/health.h" |
7c673cae | 22 | |
7c673cae FG |
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 | } | |
181888fb FG |
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 | } | |
7c673cae FG |
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; | |
11fdf7f2 | 195 | ceph::mutex channel_lock = ceph::make_mutex("LogChannel::channel_lock"); |
7c673cae FG |
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(); | |
11fdf7f2 | 252 | entity_addrvec_t get_myaddrs(); |
31f18b77 | 253 | const EntityName& get_myname(); |
11fdf7f2 | 254 | entity_name_t get_myrank(); |
7c673cae FG |
255 | version_t queue(LogEntry &entry); |
256 | ||
257 | private: | |
258 | Message *_get_mon_log_message(); | |
259 | void _send_to_mon(); | |
260 | ||
261 | CephContext *cct; | |
262 | Messenger *messenger; | |
263 | MonMap *monmap; | |
264 | bool is_mon; | |
11fdf7f2 | 265 | ceph::mutex log_lock = ceph::make_mutex("LogClient::log_lock"); |
7c673cae | 266 | version_t last_log_sent; |
b5b8bbf5 | 267 | version_t last_log; |
7c673cae FG |
268 | std::deque<LogEntry> log_queue; |
269 | ||
270 | std::map<std::string, LogChannelRef> channels; | |
271 | ||
272 | }; | |
273 | #endif |