pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
logging.h
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2020 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
20 #ifndef CRM_LOGGING__H
21 # define CRM_LOGGING__H
22 
23 # include <stdio.h>
24 # include <glib.h>
25 # include <qb/qblog.h>
26 # include <libxml/tree.h>
27 
28 /* Define custom log priorities.
29  *
30  * syslog(3) uses int for priorities, but libqb's struct qb_log_callsite uses
31  * uint8_t, so make sure they fit in the latter.
32  */
33 
34 // Define something even less desired than debug
35 # ifndef LOG_TRACE
36 # define LOG_TRACE (LOG_DEBUG+1)
37 # endif
38 
39 // Print message to stdout instead of logging it
40 # ifndef LOG_STDOUT
41 # define LOG_STDOUT 254
42 # endif
43 
44 // Don't send message anywhere
45 # ifndef LOG_NEVER
46 # define LOG_NEVER 255
47 # endif
48 
49 /* "Extended information" logging support */
50 #ifdef QB_XS
51 # define CRM_XS QB_XS
52 # define crm_extended_logging(t, e) qb_log_ctl((t), QB_LOG_CONF_EXTENDED, (e))
53 #else
54 # define CRM_XS "|"
55 
56 /* A caller might want to check the return value, so we can't define this as a
57  * no-op, and we can't simply define it to be 0 because gcc will then complain
58  * when the value isn't checked.
59  */
60 static inline int
61 crm_extended_logging(int t, int e)
62 {
63  return 0;
64 }
65 #endif
66 
67 extern unsigned int crm_log_level;
68 extern unsigned int crm_trace_nonlog;
69 
70 /* These are set when a configuration issue is found, and turn on extra messages
71  * at the end of processing. They are set via wrapper functions and do not need
72  * to be set directly.
73  */
74 extern bool pcmk__config_error;
75 extern bool pcmk__config_warning;
76 
78 {
81  xml_log_option_text = 0x0004, /* add this option to dump text into xml */
82  xml_log_option_full_fledged = 0x0008, // Use libxml when converting XML to text
91 };
92 
93 void crm_enable_blackbox(int nsig);
94 void crm_disable_blackbox(int nsig);
95 void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite);
96 
97 void crm_update_callsites(void);
98 
99 void crm_log_deinit(void);
100 
101 gboolean crm_log_cli_init(const char *entity);
102 
103 void crm_log_preinit(const char *entity, int argc, char **argv);
104 gboolean crm_log_init(const char *entity, uint8_t level, gboolean daemon,
105  gboolean to_stderr, int argc, char **argv, gboolean quiet);
106 
107 void crm_log_args(int argc, char **argv);
108 void crm_log_output_fn(const char *file, const char *function, int line, int level,
109  const char *prefix, const char *output);
110 
111 // Log a block of text line by line
112 #define crm_log_output(level, prefix, output) \
113  crm_log_output_fn(__FILE__, __func__, __LINE__, level, prefix, output)
114 
115 gboolean crm_add_logfile(const char *filename);
116 
117 void crm_bump_log_level(int argc, char **argv);
118 
119 void crm_enable_stderr(int enable);
120 
121 gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags);
122 
123 void log_data_element(int log_level, const char *file, const char *function, int line,
124  const char *prefix, xmlNode * data, int depth, gboolean formatted);
125 
126 /* returns the old value */
127 unsigned int set_crm_log_level(unsigned int level);
128 
129 unsigned int get_crm_log_level(void);
130 
131 /*
132  * Throughout the macros below, note the leading, pre-comma, space in the
133  * various ' , ##args' occurrences to aid portability across versions of 'gcc'.
134  * https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros
135  */
136 #if defined(__clang__)
137 # define CRM_TRACE_INIT_DATA(name)
138 # else
139 # include <assert.h> // required by QB_LOG_INIT_DATA() macro
140 # define CRM_TRACE_INIT_DATA(name) QB_LOG_INIT_DATA(name)
141 #endif
142 
143 /* Using "switch" instead of "if" in these macro definitions keeps
144  * static analysis from complaining about constant evaluations
145  */
146 
156 # define do_crm_log(level, fmt, args...) do { \
157  switch (level) { \
158  case LOG_STDOUT: \
159  printf(fmt "\n" , ##args); \
160  break; \
161  case LOG_NEVER: \
162  break; \
163  default: \
164  qb_log_from_external_source(__func__, __FILE__, fmt, \
165  (level), __LINE__, 0 , ##args); \
166  break; \
167  } \
168  } while (0)
169 
180 # define do_crm_log_unlikely(level, fmt, args...) do { \
181  switch (level) { \
182  case LOG_STDOUT: case LOG_NEVER: \
183  break; \
184  default: { \
185  static struct qb_log_callsite *trace_cs = NULL; \
186  if (trace_cs == NULL) { \
187  trace_cs = qb_log_callsite_get(__func__, __FILE__, fmt, \
188  (level), __LINE__, 0); \
189  } \
190  if (crm_is_callsite_active(trace_cs, (level), 0)) { \
191  qb_log_from_external_source(__func__, __FILE__, fmt, \
192  (level), __LINE__, 0 , ##args); \
193  } \
194  } \
195  break; \
196  } \
197  } while (0)
198 
199 # define CRM_LOG_ASSERT(expr) do { \
200  if(__unlikely((expr) == FALSE)) { \
201  static struct qb_log_callsite *core_cs = NULL; \
202  if(core_cs == NULL) { \
203  core_cs = qb_log_callsite_get(__func__, __FILE__, \
204  "log-assert", LOG_TRACE, \
205  __LINE__, 0); \
206  } \
207  crm_abort(__FILE__, __func__, __LINE__, #expr, \
208  core_cs?core_cs->targets:FALSE, TRUE); \
209  } \
210  } while(0)
211 
212 /* 'failure_action' MUST NOT be 'continue' as it will apply to the
213  * macro's do-while loop
214  */
215 # define CRM_CHECK(expr, failure_action) do { \
216  if (__unlikely((expr) == FALSE)) { \
217  static struct qb_log_callsite *core_cs = NULL; \
218  if (core_cs == NULL) { \
219  core_cs = qb_log_callsite_get(__func__, __FILE__, \
220  "check-assert", \
221  LOG_TRACE, __LINE__, 0); \
222  } \
223  crm_abort(__FILE__, __func__, __LINE__, #expr, \
224  (core_cs? core_cs->targets: FALSE), TRUE); \
225  failure_action; \
226  } \
227  } while(0)
228 
239 # define do_crm_log_xml(level, text, xml) do { \
240  switch (level) { \
241  case LOG_STDOUT: case LOG_NEVER: \
242  break; \
243  default: { \
244  static struct qb_log_callsite *xml_cs = NULL; \
245  if (xml_cs == NULL) { \
246  xml_cs = qb_log_callsite_get(__func__, __FILE__, \
247  "xml-blob", (level), __LINE__, 0); \
248  } \
249  if (crm_is_callsite_active(xml_cs, (level), 0)) { \
250  log_data_element((level), __FILE__, __func__, \
251  __LINE__, text, xml, 1, xml_log_option_formatted); \
252  } \
253  } \
254  break; \
255  } \
256  } while(0)
257 
270 # define do_crm_log_alias(level, file, function, line, fmt, args...) do { \
271  switch (level) { \
272  case LOG_STDOUT: \
273  printf(fmt "\n" , ##args); \
274  break; \
275  case LOG_NEVER: \
276  break; \
277  default: \
278  qb_log_from_external_source(function, file, fmt, (level), \
279  line, 0 , ##args); \
280  break; \
281  } \
282  } while (0)
283 
298 # define crm_perror(level, fmt, args...) do { \
299  switch (level) { \
300  case LOG_NEVER: \
301  break; \
302  default: { \
303  const char *err = strerror(errno); \
304  /* cast to int makes coverity happy when level == 0 */ \
305  if ((level) <= (int) crm_log_level) { \
306  fprintf(stderr, fmt ": %s (%d)\n" , ##args, err, errno);\
307  } \
308  do_crm_log((level), fmt ": %s (%d)" , ##args, err, errno); \
309  } \
310  break; \
311  } \
312  } while (0)
313 
325 # define crm_log_tag(level, tag, fmt, args...) do { \
326  switch (level) { \
327  case LOG_STDOUT: case LOG_NEVER: \
328  break; \
329  default: { \
330  static struct qb_log_callsite *trace_tag_cs = NULL; \
331  int converted_tag = g_quark_try_string(tag); \
332  if (trace_tag_cs == NULL) { \
333  trace_tag_cs = qb_log_callsite_get(__func__, __FILE__, \
334  fmt, (level), __LINE__, converted_tag); \
335  } \
336  if (crm_is_callsite_active(trace_tag_cs, (level), \
337  converted_tag)) { \
338  qb_log_from_external_source(__func__, __FILE__, fmt, \
339  (level), __LINE__, converted_tag , ##args); \
340  } \
341  } \
342  } \
343  } while (0)
344 
345 # define crm_emerg(fmt, args...) qb_log(LOG_EMERG, fmt , ##args)
346 # define crm_crit(fmt, args...) qb_logt(LOG_CRIT, 0, fmt , ##args)
347 # define crm_err(fmt, args...) qb_logt(LOG_ERR, 0, fmt , ##args)
348 # define crm_warn(fmt, args...) qb_logt(LOG_WARNING, 0, fmt , ##args)
349 # define crm_notice(fmt, args...) qb_logt(LOG_NOTICE, 0, fmt , ##args)
350 # define crm_info(fmt, args...) qb_logt(LOG_INFO, 0, fmt , ##args)
351 
352 # define crm_debug(fmt, args...) do_crm_log_unlikely(LOG_DEBUG, fmt , ##args)
353 # define crm_trace(fmt, args...) do_crm_log_unlikely(LOG_TRACE, fmt , ##args)
354 
355 # define crm_log_xml_crit(xml, text) do_crm_log_xml(LOG_CRIT, text, xml)
356 # define crm_log_xml_err(xml, text) do_crm_log_xml(LOG_ERR, text, xml)
357 # define crm_log_xml_warn(xml, text) do_crm_log_xml(LOG_WARNING, text, xml)
358 # define crm_log_xml_notice(xml, text) do_crm_log_xml(LOG_NOTICE, text, xml)
359 # define crm_log_xml_info(xml, text) do_crm_log_xml(LOG_INFO, text, xml)
360 # define crm_log_xml_debug(xml, text) do_crm_log_xml(LOG_DEBUG, text, xml)
361 # define crm_log_xml_trace(xml, text) do_crm_log_xml(LOG_TRACE, text, xml)
362 
363 # define crm_log_xml_explicit(xml, text) do { \
364  static struct qb_log_callsite *digest_cs = NULL; \
365  digest_cs = qb_log_callsite_get( \
366  __func__, __FILE__, text, LOG_TRACE, __LINE__, \
367  crm_trace_nonlog); \
368  if (digest_cs && digest_cs->targets) { \
369  do_crm_log_xml(LOG_TRACE, text, xml); \
370  } \
371  } while(0)
372 
373 # define crm_str(x) (const char*)(x?x:"<null>")
374 
375 #ifndef PCMK__NO_COMPAT
376 
377 /* Everything here is deprecated and kept only for public API backward
378  * compatibility. It will be moved to compatibility.h in a future release.
379  */
380 
392 # define do_crm_log_always(level, fmt, args...) do { \
393  switch (level) { \
394  case LOG_STDOUT: case LOG_NEVER: \
395  break; \
396  default: \
397  qb_log((level), fmt , ##args); \
398  break; \
399  } \
400  } while (0)
401 
402 #endif // PCMK__NO_COMPAT
403 
404 #ifdef __cplusplus
405 }
406 #endif
407 
408 #endif
void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite)
Definition: logging.c:410
void crm_enable_stderr(int enable)
Definition: logging.c:906
void log_data_element(int log_level, const char *file, const char *function, int line, const char *prefix, xmlNode *data, int depth, gboolean formatted)
bool pcmk__config_warning
Definition: utils.c:53
gboolean crm_log_init(const char *entity, uint8_t level, gboolean daemon, gboolean to_stderr, int argc, char **argv, gboolean quiet)
Definition: logging.c:747
unsigned int crm_trace_nonlog
Definition: logging.c:37
gboolean crm_log_cli_init(const char *entity)
Definition: logging.c:467
void crm_bump_log_level(int argc, char **argv)
Make logging more verbose.
Definition: logging.c:927
void crm_log_deinit(void)
Definition: logging.c:116
int daemon(int nochdir, int noclose)
void crm_log_output_fn(const char *file, const char *function, int line, int level, const char *prefix, const char *output)
Definition: logging.c:968
void crm_enable_blackbox(int nsig)
Definition: logging.c:388
xml_log_options
Definition: logging.h:77
void crm_log_args(int argc, char **argv)
Log the command line (once)
Definition: logging.c:953
unsigned int set_crm_log_level(unsigned int level)
Definition: logging.c:892
void crm_log_preinit(const char *entity, int argc, char **argv)
Definition: logging.c:691
gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags)
Definition: logging.c:577
unsigned int get_crm_log_level(void)
Definition: logging.c:938
unsigned int crm_log_level
Definition: logging.c:36
void crm_disable_blackbox(int nsig)
Definition: logging.c:394
char data[0]
Definition: internal.h:90
bool pcmk__config_error
Definition: utils.c:52
gboolean crm_add_logfile(const char *filename)
Definition: logging.c:172
void crm_update_callsites(void)
Definition: logging.c:606