root/include/crm/common/logging.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. crm_extended_logging

   1 /*
   2  * Copyright 2004-2021 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 #ifndef PCMK__CRM_COMMON_LOGGING__H
  11 #  define PCMK__CRM_COMMON_LOGGING__H
  12 
  13 #  include <stdio.h>
  14 #  include <glib.h>
  15 #  include <qb/qblog.h>
  16 #  include <libxml/tree.h>
  17 
  18 #ifdef __cplusplus
  19 extern "C" {
  20 #endif
  21 
  22 /**
  23  * \file
  24  * \brief Wrappers for and extensions to libqb logging
  25  * \ingroup core
  26  */
  27 
  28 
  29 /* Define custom log priorities.
  30  *
  31  * syslog(3) uses int for priorities, but libqb's struct qb_log_callsite uses
  32  * uint8_t, so make sure they fit in the latter.
  33  */
  34 
  35 // Define something even less desired than debug
  36 #  ifndef LOG_TRACE
  37 #    define LOG_TRACE   (LOG_DEBUG+1)
  38 #  endif
  39 
  40 // Print message to stdout instead of logging it
  41 #  ifndef LOG_STDOUT
  42 #    define LOG_STDOUT  254
  43 #  endif
  44 
  45 // Don't send message anywhere
  46 #  ifndef LOG_NEVER
  47 #    define LOG_NEVER   255
  48 #  endif
  49 
  50 /* "Extended information" logging support */
  51 #ifdef QB_XS
  52 #  define CRM_XS QB_XS
  53 #  define crm_extended_logging(t, e) qb_log_ctl((t), QB_LOG_CONF_EXTENDED, (e))
  54 #else
  55 #  define CRM_XS "|"
  56 
  57 /* A caller might want to check the return value, so we can't define this as a
  58  * no-op, and we can't simply define it to be 0 because gcc will then complain
  59  * when the value isn't checked.
  60  */
  61 static inline int
  62 crm_extended_logging(int t, int e)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64     return 0;
  65 }
  66 #endif
  67 
  68 extern unsigned int crm_log_level;
  69 extern unsigned int crm_trace_nonlog;
  70 
  71 /*! \deprecated Pacemaker library functions set this when a configuration
  72  *              error is found, which turns on extra messages at the end of
  73  *              processing. It should not be used directly and will be removed
  74  *              from the public C API in a future release.
  75  */
  76 extern gboolean crm_config_error;
  77 
  78 /*! \deprecated Pacemaker library functions set this when a configuration
  79  *              warning is found, which turns on extra messages at the end of
  80  *              processing. It should not be used directly and will be removed
  81  *              from the public C API in a future release.
  82  */
  83 extern gboolean crm_config_warning;
  84 
  85 enum xml_log_options
  86 {
  87     xml_log_option_filtered   = 0x0001,
  88     xml_log_option_formatted  = 0x0002,
  89     xml_log_option_text       = 0x0004, /* add this option to dump text into xml */
  90     xml_log_option_full_fledged = 0x0008, // Use libxml when converting XML to text
  91     xml_log_option_diff_plus  = 0x0010,
  92     xml_log_option_diff_minus = 0x0020,
  93     xml_log_option_diff_short = 0x0040,
  94     xml_log_option_diff_all   = 0x0100,
  95     xml_log_option_dirty_add  = 0x1000,
  96     xml_log_option_open       = 0x2000,
  97     xml_log_option_children   = 0x4000,
  98     xml_log_option_close      = 0x8000,
  99 };
 100 
 101 void crm_enable_blackbox(int nsig);
 102 void crm_disable_blackbox(int nsig);
 103 void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite);
 104 
 105 void crm_update_callsites(void);
 106 
 107 void crm_log_deinit(void);
 108 
 109 /*!
 110  * \brief Initializes the logging system and defaults to the least verbose output level
 111  *
 112  * \param[in] entity  If not NULL, will be used as the identity for logging purposes
 113  * \param[in] argc    The number of command line parameters
 114  * \param[in] argv    The command line parameter values
 115  */
 116 void crm_log_preinit(const char *entity, int argc, char **argv);
 117 gboolean crm_log_init(const char *entity, uint8_t level, gboolean daemon,
 118                       gboolean to_stderr, int argc, char **argv, gboolean quiet);
 119 
 120 void crm_log_args(int argc, char **argv);
 121 void crm_log_output_fn(const char *file, const char *function, int line, int level,
 122                        const char *prefix, const char *output);
 123 
 124 // Log a block of text line by line
 125 #define crm_log_output(level, prefix, output)   \
 126     crm_log_output_fn(__FILE__, __func__, __LINE__, level, prefix, output)
 127 
 128 void crm_bump_log_level(int argc, char **argv);
 129 
 130 void crm_enable_stderr(int enable);
 131 
 132 gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags);
 133 
 134 void log_data_element(int log_level, const char *file, const char *function, int line,
 135                       const char *prefix, xmlNode * data, int depth, gboolean formatted);
 136 
 137 /* returns the old value */
 138 unsigned int set_crm_log_level(unsigned int level);
 139 
 140 unsigned int get_crm_log_level(void);
 141 
 142 /*
 143  * Throughout the macros below, note the leading, pre-comma, space in the
 144  * various ' , ##args' occurrences to aid portability across versions of 'gcc'.
 145  * https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros
 146  */
 147 #if defined(__clang__)
 148 #    define CRM_TRACE_INIT_DATA(name)
 149 #  else
 150 #    include <assert.h> // required by QB_LOG_INIT_DATA() macro
 151 #    define CRM_TRACE_INIT_DATA(name) QB_LOG_INIT_DATA(name)
 152 #endif
 153 
 154 /* Using "switch" instead of "if" in these macro definitions keeps
 155  * static analysis from complaining about constant evaluations
 156  */
 157 
 158 /*!
 159  * \brief Log a message
 160  *
 161  * \param[in] level  Priority at which to log the message
 162  * \param[in] fmt    printf-style format string literal for message
 163  * \param[in] args   Any arguments needed by format string
 164  *
 165  * \note This is a macro, and \p level may be evaluated more than once.
 166  */
 167 #  define do_crm_log(level, fmt, args...) do {                              \
 168         switch (level) {                                                    \
 169             case LOG_STDOUT:                                                \
 170                 printf(fmt "\n" , ##args);                                  \
 171                 break;                                                      \
 172             case LOG_NEVER:                                                 \
 173                 break;                                                      \
 174             default:                                                        \
 175                 qb_log_from_external_source(__func__, __FILE__, fmt,        \
 176                     (level),   __LINE__, 0 , ##args);                       \
 177                 break;                                                      \
 178         }                                                                   \
 179     } while (0)
 180 
 181 /*!
 182  * \brief Log a message that is likely to be filtered out
 183  *
 184  * \param[in] level  Priority at which to log the message
 185  * \param[in] fmt    printf-style format string for message
 186  * \param[in] args   Any arguments needed by format string
 187  *
 188  * \note This is a macro, and \p level may be evaluated more than once.
 189  *       This does nothing when level is LOG_STDOUT.
 190  */
 191 #  define do_crm_log_unlikely(level, fmt, args...) do {                     \
 192         switch (level) {                                                    \
 193             case LOG_STDOUT: case LOG_NEVER:                                \
 194                 break;                                                      \
 195             default: {                                                      \
 196                 static struct qb_log_callsite *trace_cs = NULL;             \
 197                 if (trace_cs == NULL) {                                     \
 198                     trace_cs = qb_log_callsite_get(__func__, __FILE__, fmt, \
 199                                                    (level), __LINE__, 0);   \
 200                 }                                                           \
 201                 if (crm_is_callsite_active(trace_cs, (level), 0)) {         \
 202                     qb_log_from_external_source(__func__, __FILE__, fmt,    \
 203                         (level), __LINE__, 0 , ##args);                     \
 204                 }                                                           \
 205             }                                                               \
 206             break;                                                          \
 207         }                                                                   \
 208     } while (0)
 209 
 210 #  define CRM_LOG_ASSERT(expr) do {                                     \
 211         if (!(expr)) {                                                  \
 212             static struct qb_log_callsite *core_cs = NULL;              \
 213             if(core_cs == NULL) {                                       \
 214                 core_cs = qb_log_callsite_get(__func__, __FILE__,       \
 215                                               "log-assert", LOG_TRACE,  \
 216                                               __LINE__, 0);             \
 217             }                                                           \
 218             crm_abort(__FILE__, __func__, __LINE__, #expr,              \
 219                       core_cs?core_cs->targets:FALSE, TRUE);            \
 220         }                                                               \
 221     } while(0)
 222 
 223 /* 'failure_action' MUST NOT be 'continue' as it will apply to the
 224  * macro's do-while loop
 225  */
 226 #  define CRM_CHECK(expr, failure_action) do {                                      \
 227         if (!(expr)) {                                                  \
 228             static struct qb_log_callsite *core_cs = NULL;              \
 229             if (core_cs == NULL) {                                      \
 230                 core_cs = qb_log_callsite_get(__func__, __FILE__,       \
 231                                               "check-assert",           \
 232                                               LOG_TRACE, __LINE__, 0);  \
 233             }                                                           \
 234                 crm_abort(__FILE__, __func__, __LINE__, #expr,              \
 235                         (core_cs? core_cs->targets: FALSE), TRUE);              \
 236                 failure_action;                                                                 \
 237             }                                                                                           \
 238     } while(0)
 239 
 240 /*!
 241  * \brief Log XML line-by-line in a formatted fashion
 242  *
 243  * \param[in] level  Priority at which to log the messages
 244  * \param[in] text   Prefix for each line
 245  * \param[in] xml    XML to log
 246  *
 247  * \note This is a macro, and \p level may be evaluated more than once.
 248  *       This does nothing when level is LOG_STDOUT.
 249  */
 250 #  define do_crm_log_xml(level, text, xml) do {                             \
 251         switch (level) {                                                    \
 252             case LOG_STDOUT: case LOG_NEVER:                                \
 253                 break;                                                      \
 254             default: {                                                      \
 255                 static struct qb_log_callsite *xml_cs = NULL;               \
 256                 if (xml_cs == NULL) {                                       \
 257                     xml_cs = qb_log_callsite_get(__func__, __FILE__,        \
 258                                         "xml-blob", (level), __LINE__, 0);  \
 259                 }                                                           \
 260                 if (crm_is_callsite_active(xml_cs, (level), 0)) {           \
 261                     log_data_element((level), __FILE__, __func__,           \
 262                          __LINE__, text, xml, 1, xml_log_option_formatted); \
 263                 }                                                           \
 264             }                                                               \
 265             break;                                                          \
 266         }                                                                   \
 267     } while(0)
 268 
 269 /*!
 270  * \brief Log a message as if it came from a different code location
 271  *
 272  * \param[in] level     Priority at which to log the message
 273  * \param[in] file      Source file name to use instead of __FILE__
 274  * \param[in] function  Source function name to use instead of __func__
 275  * \param[in] line      Source line number to use instead of __line__
 276  * \param[in] fmt       printf-style format string literal for message
 277  * \param[in] args      Any arguments needed by format string
 278  *
 279  * \note This is a macro, and \p level may be evaluated more than once.
 280  */
 281 #  define do_crm_log_alias(level, file, function, line, fmt, args...) do {  \
 282         switch (level) {                                                    \
 283             case LOG_STDOUT:                                                \
 284                 printf(fmt "\n" , ##args);                                  \
 285                 break;                                                      \
 286             case LOG_NEVER:                                                 \
 287                 break;                                                      \
 288             default:                                                        \
 289                 qb_log_from_external_source(function, file, fmt, (level),   \
 290                                             line, 0 , ##args);              \
 291                 break;                                                      \
 292         }                                                                   \
 293     } while (0)
 294 
 295 /*!
 296  * \brief Send a system error message to both the log and stderr
 297  *
 298  * \param[in] level  Priority at which to log the message
 299  * \param[in] fmt    printf-style format string for message
 300  * \param[in] args   Any arguments needed by format string
 301  *
 302  * \deprecated One of the other logging functions should be used with
 303  *             pcmk_strerror() instead.
 304  * \note This is a macro, and \p level may be evaluated more than once.
 305  * \note Because crm_perror() adds the system error message and error number
 306  *       onto the end of fmt, that information will become extended information
 307  *       if CRM_XS is used inside fmt and will not show up in syslog.
 308  */
 309 #  define crm_perror(level, fmt, args...) do {                              \
 310         switch (level) {                                                    \
 311             case LOG_NEVER:                                                 \
 312                 break;                                                      \
 313             default: {                                                      \
 314                 const char *err = strerror(errno);                          \
 315                 /* cast to int makes coverity happy when level == 0 */      \
 316                 if ((level) <= (int) crm_log_level) {                       \
 317                     fprintf(stderr, fmt ": %s (%d)\n" , ##args, err, errno);\
 318                 }                                                           \
 319                 do_crm_log((level), fmt ": %s (%d)" , ##args, err, errno);  \
 320             }                                                               \
 321             break;                                                          \
 322         }                                                                   \
 323     } while (0)
 324 
 325 /*!
 326  * \brief Log a message with a tag (for use with PCMK_trace_tags)
 327  *
 328  * \param[in] level  Priority at which to log the message
 329  * \param[in] tag    String to tag message with
 330  * \param[in] fmt    printf-style format string for message
 331  * \param[in] args   Any arguments needed by format string
 332  *
 333  * \note This is a macro, and \p level may be evaluated more than once.
 334  *       This does nothing when level is LOG_STDOUT.
 335  */
 336 #  define crm_log_tag(level, tag, fmt, args...)    do {                     \
 337         switch (level) {                                                    \
 338             case LOG_STDOUT: case LOG_NEVER:                                \
 339                 break;                                                      \
 340             default: {                                                      \
 341                 static struct qb_log_callsite *trace_tag_cs = NULL;         \
 342                 int converted_tag = g_quark_try_string(tag);                \
 343                 if (trace_tag_cs == NULL) {                                 \
 344                     trace_tag_cs = qb_log_callsite_get(__func__, __FILE__,  \
 345                                     fmt, (level), __LINE__, converted_tag); \
 346                 }                                                           \
 347                 if (crm_is_callsite_active(trace_tag_cs, (level),           \
 348                                            converted_tag)) {                \
 349                     qb_log_from_external_source(__func__, __FILE__, fmt,    \
 350                                 (level), __LINE__, converted_tag , ##args); \
 351                 }                                                           \
 352             }                                                               \
 353         }                                                                   \
 354     } while (0)
 355 
 356 #  define crm_emerg(fmt, args...)   qb_log(LOG_EMERG,       fmt , ##args)
 357 #  define crm_crit(fmt, args...)    qb_logt(LOG_CRIT,    0, fmt , ##args)
 358 #  define crm_err(fmt, args...)     qb_logt(LOG_ERR,     0, fmt , ##args)
 359 #  define crm_warn(fmt, args...)    qb_logt(LOG_WARNING, 0, fmt , ##args)
 360 #  define crm_notice(fmt, args...)  qb_logt(LOG_NOTICE,  0, fmt , ##args)
 361 #  define crm_info(fmt, args...)    qb_logt(LOG_INFO,    0, fmt , ##args)
 362 
 363 #  define crm_debug(fmt, args...)   do_crm_log_unlikely(LOG_DEBUG, fmt , ##args)
 364 #  define crm_trace(fmt, args...)   do_crm_log_unlikely(LOG_TRACE, fmt , ##args)
 365 
 366 #  define crm_log_xml_crit(xml, text)    do_crm_log_xml(LOG_CRIT,    text, xml)
 367 #  define crm_log_xml_err(xml, text)     do_crm_log_xml(LOG_ERR,     text, xml)
 368 #  define crm_log_xml_warn(xml, text)    do_crm_log_xml(LOG_WARNING, text, xml)
 369 #  define crm_log_xml_notice(xml, text)  do_crm_log_xml(LOG_NOTICE,  text, xml)
 370 #  define crm_log_xml_info(xml, text)    do_crm_log_xml(LOG_INFO,    text, xml)
 371 #  define crm_log_xml_debug(xml, text)   do_crm_log_xml(LOG_DEBUG,   text, xml)
 372 #  define crm_log_xml_trace(xml, text)   do_crm_log_xml(LOG_TRACE,   text, xml)
 373 
 374 #  define crm_log_xml_explicit(xml, text)  do {                 \
 375         static struct qb_log_callsite *digest_cs = NULL;        \
 376         digest_cs = qb_log_callsite_get(                        \
 377             __func__, __FILE__, text, LOG_TRACE, __LINE__,      \
 378             crm_trace_nonlog);                                  \
 379         if (digest_cs && digest_cs->targets) {                  \
 380             do_crm_log_xml(LOG_TRACE,   text, xml);             \
 381         }                                                       \
 382     } while(0)
 383 
 384 #  define crm_str(x)    (const char*)(x?x:"<null>")
 385 
 386 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
 387 #include <crm/common/logging_compat.h>
 388 #endif
 389 
 390 #ifdef __cplusplus
 391 }
 392 #endif
 393 
 394 #endif

/* [previous][next][first][last][top][bottom][index][help] */