Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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