root/lib/pacemaker/pcmk_graph_logging.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmk__graph_status2text
  2. actiontype2text
  3. find_graph_action_by_id
  4. synapse_state_str
  5. synapse_pending_inputs
  6. log_unresolved_inputs
  7. log_synapse_action
  8. log_synapse
  9. pcmk__log_graph_action
  10. pcmk__log_graph

   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 Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <crm/crm.h>
  13 #include <crm/msg_xml.h>
  14 #include <crm/common/xml.h>
  15 #include <pacemaker-internal.h>
  16 
  17 /*!
  18  * \internal
  19  * \brief Return text equivalent of an enum transition_status for logging
  20  *
  21  * \param[in] state  Transition status
  22  *
  23  * \return Human-readable text equivalent of \p state
  24  */
  25 const char *
  26 pcmk__graph_status2text(enum transition_status state)
     /* [previous][next][first][last][top][bottom][index][help] */
  27 {
  28     switch (state) {
  29         case transition_active:
  30             return "active";
  31         case transition_pending:
  32             return "pending";
  33         case transition_complete:
  34             return "complete";
  35         case transition_stopped:
  36             return "stopped";
  37         case transition_terminated:
  38             return "terminated";
  39         case transition_action_failed:
  40             return "failed (action)";
  41         case transition_failed:
  42             return "failed";
  43     }
  44     return "unknown";
  45 }
  46 
  47 static const char *
  48 actiontype2text(action_type_e type)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50     switch (type) {
  51         case action_type_pseudo:
  52             return "pseudo";
  53         case action_type_rsc:
  54             return "resource";
  55         case action_type_crm:
  56             return "cluster";
  57     }
  58     return "invalid";
  59 }
  60 
  61 /*!
  62  * \internal
  63  * \brief Find a transition graph action by ID
  64  *
  65  * \param[in] graph  Transition graph to search
  66  * \param[in] id     Action ID to search for
  67  *
  68  * \return Transition graph action corresponding to \p id, or NULL if none
  69  */
  70 static crm_action_t *
  71 find_graph_action_by_id(crm_graph_t *graph, int id)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73     if (graph == NULL) {
  74         return NULL;
  75     }
  76 
  77     for (GList *sIter = graph->synapses; sIter != NULL; sIter = sIter->next) {
  78         synapse_t *synapse = (synapse_t *) sIter->data;
  79 
  80         for (GList *aIter = synapse->actions; aIter != NULL;
  81              aIter = aIter->next) {
  82 
  83             crm_action_t *action = (crm_action_t *) aIter->data;
  84 
  85             if (action->id == id) {
  86                 return action;
  87             }
  88         }
  89     }
  90     return NULL;
  91 }
  92 
  93 const char *
  94 synapse_state_str(synapse_t *synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96     if (pcmk_is_set(synapse->flags, pcmk__synapse_failed)) {
  97         return "Failed";
  98 
  99     } else if (pcmk_is_set(synapse->flags, pcmk__synapse_confirmed)) {
 100         return "Completed";
 101 
 102     } else if (pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
 103         return "In-flight";
 104 
 105     } else if (pcmk_is_set(synapse->flags, pcmk__synapse_ready)) {
 106         return "Ready";
 107     }
 108     return "Pending";
 109 }
 110 
 111 // List action IDs of inputs in graph that haven't completed successfully
 112 static char *
 113 synapse_pending_inputs(crm_graph_t *graph, synapse_t *synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115     char *pending = NULL;
 116     size_t pending_len = 0;
 117 
 118     for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
 119         crm_action_t *input = (crm_action_t *) lpc->data;
 120 
 121         if (pcmk_is_set(input->flags, pcmk__graph_action_failed)) {
 122             pcmk__add_word(&pending, &pending_len, ID(input->xml));
 123 
 124         } else if (pcmk_is_set(input->flags, pcmk__graph_action_confirmed)) {
 125             // Confirmed successful inputs are not pending
 126 
 127         } else if (find_graph_action_by_id(graph, input->id) != NULL) {
 128             // In-flight or pending
 129             pcmk__add_word(&pending, &pending_len, ID(input->xml));
 130         }
 131     }
 132     if (pending == NULL) {
 133         pending = strdup("none");
 134     }
 135     return pending;
 136 }
 137 
 138 // Log synapse inputs that aren't in graph
 139 static void
 140 log_unresolved_inputs(unsigned int log_level, crm_graph_t *graph,
     /* [previous][next][first][last][top][bottom][index][help] */
 141                       synapse_t *synapse)
 142 {
 143     for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
 144         crm_action_t *input = (crm_action_t *) lpc->data;
 145         const char *key = crm_element_value(input->xml, XML_LRM_ATTR_TASK_KEY);
 146         const char *host = crm_element_value(input->xml, XML_LRM_ATTR_TARGET);
 147 
 148         if (find_graph_action_by_id(graph, input->id) == NULL) {
 149             do_crm_log(log_level,
 150                        " * [Input %2d]: Unresolved dependency %s op %s%s%s",
 151                        input->id, actiontype2text(input->type), key,
 152                        (host? " on " : ""), (host? host : ""));
 153         }
 154     }
 155 }
 156 
 157 static void
 158 log_synapse_action(unsigned int log_level, synapse_t *synapse,
     /* [previous][next][first][last][top][bottom][index][help] */
 159                    crm_action_t *action, const char *pending_inputs)
 160 {
 161     const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
 162     const char *host = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);
 163     char *desc = crm_strdup_printf("%s %s op %s",
 164                                    synapse_state_str(synapse),
 165                                    actiontype2text(action->type), key);
 166 
 167     do_crm_log(log_level,
 168                "[Action %4d]: %-50s%s%s (priority: %d, waiting: %s)",
 169                action->id, desc, (host? " on " : ""), (host? host : ""),
 170                synapse->priority, pending_inputs);
 171     free(desc);
 172 }
 173 
 174 static void
 175 log_synapse(unsigned int log_level, crm_graph_t *graph, synapse_t *synapse)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177     char *pending = NULL;
 178 
 179     if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
 180         pending = synapse_pending_inputs(graph, synapse);
 181     }
 182     for (GList *lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
 183         log_synapse_action(log_level, synapse, (crm_action_t *) lpc->data,
 184                            pending);
 185     }
 186     free(pending);
 187     if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
 188         log_unresolved_inputs(log_level, graph, synapse);
 189     }
 190 }
 191 
 192 void
 193 pcmk__log_graph_action(int log_level, crm_action_t *action)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195     log_synapse(log_level, NULL, action->synapse);
 196 }
 197 
 198 void
 199 pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
     /* [previous][next][first][last][top][bottom][index][help] */
 200 {
 201     if ((graph == NULL) || (graph->num_actions == 0)) {
 202         if (log_level == LOG_TRACE) {
 203             crm_debug("Empty transition graph");
 204         }
 205         return;
 206     }
 207 
 208     do_crm_log(log_level, "Graph %d with %d actions:"
 209                " batch-limit=%d jobs, network-delay=%ums",
 210                graph->id, graph->num_actions,
 211                graph->batch_limit, graph->network_delay);
 212 
 213     for (GList *lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
 214         log_synapse(log_level, graph, (synapse_t *) lpc->data);
 215     }
 216 }

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