summaryrefslogtreecommitdiffstats
path: root/lib/common/logging.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/logging.c')
-rw-r--r--lib/common/logging.c151
1 files changed, 129 insertions, 22 deletions
diff --git a/lib/common/logging.c b/lib/common/logging.c
index dded873..7768c35 100644
--- a/lib/common/logging.c
+++ b/lib/common/logging.c
@@ -51,6 +51,11 @@ static unsigned int crm_log_priority = LOG_NOTICE;
static GLogFunc glib_log_default = NULL;
static pcmk__output_t *logger_out = NULL;
+pcmk__config_error_func pcmk__config_error_handler = NULL;
+pcmk__config_warning_func pcmk__config_warning_handler = NULL;
+void *pcmk__config_error_context = NULL;
+void *pcmk__config_warning_context = NULL;
+
static gboolean crm_tracing_enabled(void);
static void
@@ -237,7 +242,7 @@ chown_logfile(const char *filename, int logfd)
static void
chmod_logfile(const char *filename, int logfd)
{
- const char *modestr = getenv("PCMK_logfile_mode");
+ const char *modestr = pcmk__env_option(PCMK__ENV_LOGFILE_MODE);
mode_t filemode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
if (modestr != NULL) {
@@ -297,7 +302,7 @@ setenv_logfile(const char *filename)
{
// Some resource agents will log only if environment variable is set
if (pcmk__env_option(PCMK__ENV_LOGFILE) == NULL) {
- pcmk__set_env_option(PCMK__ENV_LOGFILE, filename);
+ pcmk__set_env_option(PCMK__ENV_LOGFILE, filename, true);
}
}
@@ -609,6 +614,20 @@ crm_log_filter_source(int source, const char *trace_files, const char *trace_fns
}
}
+#ifndef HAVE_STRCHRNUL
+/* strchrnul() is a GNU extension. If not present, use our own definition.
+ * The GNU version returns char*, but we only need it to be const char*.
+ */
+static const char *
+strchrnul(const char *s, int c)
+{
+ while ((*s != c) && (*s != '\0')) {
+ ++s;
+ }
+ return s;
+}
+#endif
+
static void
crm_log_filter(struct qb_log_callsite *cs)
{
@@ -622,11 +641,11 @@ crm_log_filter(struct qb_log_callsite *cs)
if (need_init) {
need_init = 0;
- trace_fns = getenv("PCMK_trace_functions");
- trace_fmts = getenv("PCMK_trace_formats");
- trace_tags = getenv("PCMK_trace_tags");
- trace_files = getenv("PCMK_trace_files");
- trace_blackbox = getenv("PCMK_trace_blackbox");
+ trace_fns = pcmk__env_option(PCMK__ENV_TRACE_FUNCTIONS);
+ trace_fmts = pcmk__env_option(PCMK__ENV_TRACE_FORMATS);
+ trace_tags = pcmk__env_option(PCMK__ENV_TRACE_TAGS);
+ trace_files = pcmk__env_option(PCMK__ENV_TRACE_FILES);
+ trace_blackbox = pcmk__env_option(PCMK__ENV_TRACE_BLACKBOX);
if (trace_tags != NULL) {
uint32_t tag;
@@ -695,8 +714,10 @@ crm_update_callsites(void)
log = FALSE;
crm_debug
("Enabling callsites based on priority=%d, files=%s, functions=%s, formats=%s, tags=%s",
- crm_log_level, getenv("PCMK_trace_files"), getenv("PCMK_trace_functions"),
- getenv("PCMK_trace_formats"), getenv("PCMK_trace_tags"));
+ crm_log_level, pcmk__env_option(PCMK__ENV_TRACE_FILES),
+ pcmk__env_option(PCMK__ENV_TRACE_FUNCTIONS),
+ pcmk__env_option(PCMK__ENV_TRACE_FORMATS),
+ pcmk__env_option(PCMK__ENV_TRACE_TAGS));
}
qb_log_filter_fn_set(crm_log_filter);
}
@@ -704,13 +725,11 @@ crm_update_callsites(void)
static gboolean
crm_tracing_enabled(void)
{
- if (crm_log_level == LOG_TRACE) {
- return TRUE;
- } else if (getenv("PCMK_trace_files") || getenv("PCMK_trace_functions")
- || getenv("PCMK_trace_formats") || getenv("PCMK_trace_tags")) {
- return TRUE;
- }
- return FALSE;
+ return (crm_log_level == LOG_TRACE)
+ || (pcmk__env_option(PCMK__ENV_TRACE_FILES) != NULL)
+ || (pcmk__env_option(PCMK__ENV_TRACE_FUNCTIONS) != NULL)
+ || (pcmk__env_option(PCMK__ENV_TRACE_FORMATS) != NULL)
+ || (pcmk__env_option(PCMK__ENV_TRACE_TAGS) != NULL);
}
static int
@@ -784,7 +803,8 @@ set_identity(const char *entity, int argc, char *const *argv)
CRM_ASSERT(crm_system_name != NULL);
- setenv("PCMK_service", crm_system_name, 1);
+ // Used by fencing.py.py (in fence-agents)
+ pcmk__set_env_option(PCMK__ENV_SERVICE, crm_system_name, false);
}
void
@@ -897,7 +917,7 @@ crm_log_init(const char *entity, uint8_t level, gboolean daemon, gboolean to_std
} else {
facility = PCMK__VALUE_NONE;
}
- pcmk__set_env_option(PCMK__ENV_LOGFACILITY, facility);
+ pcmk__set_env_option(PCMK__ENV_LOGFACILITY, facility, true);
}
if (pcmk__str_eq(facility, PCMK__VALUE_NONE, pcmk__str_casei)) {
@@ -1127,16 +1147,21 @@ pcmk__cli_init_logging(const char *name, unsigned int verbosity)
/*!
* \brief Log XML line-by-line in a formatted fashion
*
- * \param[in] level Priority at which to log the messages
- * \param[in] text Prefix for each line
- * \param[in] xml XML to log
+ * \param[in] file File name to use for log filtering
+ * \param[in] function Function name to use for log filtering
+ * \param[in] line Line number to use for log filtering
+ * \param[in] tags Logging tags to use for log filtering
+ * \param[in] level Priority at which to log the messages
+ * \param[in] text Prefix for each line
+ * \param[in] xml XML to log
*
* \note This does nothing when \p level is \p LOG_STDOUT.
* \note Do not call this function directly. It should be called only from the
* \p do_crm_log_xml() macro.
*/
void
-pcmk_log_xml_impl(uint8_t level, const char *text, const xmlNode *xml)
+pcmk_log_xml_as(const char *file, const char *function, uint32_t line,
+ uint32_t tags, uint8_t level, const char *text, const xmlNode *xml)
{
if (xml == NULL) {
do_crm_log(level, "%s%sNo data to dump as XML",
@@ -1148,12 +1173,76 @@ pcmk_log_xml_impl(uint8_t level, const char *text, const xmlNode *xml)
}
pcmk__output_set_log_level(logger_out, level);
+ pcmk__output_set_log_filter(logger_out, file, function, line, tags);
pcmk__xml_show(logger_out, text, xml, 1,
pcmk__xml_fmt_pretty
|pcmk__xml_fmt_open
|pcmk__xml_fmt_children
|pcmk__xml_fmt_close);
+ pcmk__output_set_log_filter(logger_out, NULL, NULL, 0U, 0U);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Log XML changes line-by-line in a formatted fashion
+ *
+ * \param[in] file File name to use for log filtering
+ * \param[in] function Function name to use for log filtering
+ * \param[in] line Line number to use for log filtering
+ * \param[in] tags Logging tags to use for log filtering
+ * \param[in] level Priority at which to log the messages
+ * \param[in] xml XML whose changes to log
+ *
+ * \note This does nothing when \p level is \c LOG_STDOUT.
+ */
+void
+pcmk__log_xml_changes_as(const char *file, const char *function, uint32_t line,
+ uint32_t tags, uint8_t level, const xmlNode *xml)
+{
+ if (xml == NULL) {
+ do_crm_log(level, "No XML to dump");
+ return;
+ }
+
+ if (logger_out == NULL) {
+ CRM_CHECK(pcmk__log_output_new(&logger_out) == pcmk_rc_ok, return);
}
+ pcmk__output_set_log_level(logger_out, level);
+ pcmk__output_set_log_filter(logger_out, file, function, line, tags);
+ pcmk__xml_show_changes(logger_out, xml);
+ pcmk__output_set_log_filter(logger_out, NULL, NULL, 0U, 0U);
+}
+
+/*!
+ * \internal
+ * \brief Log an XML patchset line-by-line in a formatted fashion
+ *
+ * \param[in] file File name to use for log filtering
+ * \param[in] function Function name to use for log filtering
+ * \param[in] line Line number to use for log filtering
+ * \param[in] tags Logging tags to use for log filtering
+ * \param[in] level Priority at which to log the messages
+ * \param[in] patchset XML patchset to log
+ *
+ * \note This does nothing when \p level is \c LOG_STDOUT.
+ */
+void
+pcmk__log_xml_patchset_as(const char *file, const char *function, uint32_t line,
+ uint32_t tags, uint8_t level, const xmlNode *patchset)
+{
+ if (patchset == NULL) {
+ do_crm_log(level, "No patchset to dump");
+ return;
+ }
+
+ if (logger_out == NULL) {
+ CRM_CHECK(pcmk__log_output_new(&logger_out) == pcmk_rc_ok, return);
+ }
+ pcmk__output_set_log_level(logger_out, level);
+ pcmk__output_set_log_filter(logger_out, file, function, line, tags);
+ logger_out->message(logger_out, "xml-patchset", patchset);
+ pcmk__output_set_log_filter(logger_out, NULL, NULL, 0U, 0U);
}
/*!
@@ -1188,5 +1277,23 @@ crm_add_logfile(const char *filename)
return pcmk__add_logfile(filename) == pcmk_rc_ok;
}
+void
+pcmk_log_xml_impl(uint8_t level, const char *text, const xmlNode *xml)
+{
+ pcmk_log_xml_as(__FILE__, __func__, __LINE__, 0, level, text, xml);
+}
+
// LCOV_EXCL_STOP
// End deprecated API
+
+void pcmk__set_config_error_handler(pcmk__config_error_func error_handler, void *error_context)
+{
+ pcmk__config_error_handler = error_handler;
+ pcmk__config_error_context = error_context;
+}
+
+void pcmk__set_config_warning_handler(pcmk__config_warning_func warning_handler, void *warning_context)
+{
+ pcmk__config_warning_handler = warning_handler;
+ pcmk__config_warning_context = warning_context;
+} \ No newline at end of file