pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
pcmk_graph_logging.c
Go to the documentation of this file.
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
25const char *
27{
28 switch (state) {
30 return "active";
32 return "pending";
34 return "complete";
36 return "stopped";
38 return "terminated";
40 return "failed (action)";
42 return "failed";
43 }
44 return "unknown";
45}
46
47static const char *
48actiontype2text(action_type_e type)
49{
50 switch (type) {
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
70static crm_action_t *
71find_graph_action_by_id(crm_graph_t *graph, int id)
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
93const char *
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
112static char *
113synapse_pending_inputs(crm_graph_t *graph, synapse_t *synapse)
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
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
139static void
140log_unresolved_inputs(unsigned int log_level, crm_graph_t *graph,
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
157static void
158log_synapse_action(unsigned int log_level, synapse_t *synapse,
159 crm_action_t *action, const char *pending_inputs)
160{
161 const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
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
174static void
175log_synapse(unsigned int log_level, crm_graph_t *graph, synapse_t *synapse)
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
192void
194{
195 log_synapse(log_level, NULL, action->synapse);
196}
197
198void
199pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
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}
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:122
pcmk__cpg_host_t host
Definition: cpg.c:4
enum crm_ais_msg_types type
Definition: cpg.c:3
A dumping ground.
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:167
#define crm_debug(fmt, args...)
Definition: logging.h:363
#define LOG_TRACE
Definition: logging.h:37
#define ID(x)
Definition: msg_xml.h:460
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:304
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:305
xmlNode * input
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
const char * action
Definition: pcmk_fence.c:29
void pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
const char * synapse_state_str(synapse_t *synapse)
void pcmk__log_graph_action(int log_level, crm_action_t *action)
const char * pcmk__graph_status2text(enum transition_status state)
@ pcmk__graph_action_confirmed
@ pcmk__graph_action_failed
transition_status
@ transition_action_failed
@ transition_active
@ transition_failed
@ transition_complete
@ transition_terminated
@ transition_pending
@ transition_stopped
@ pcmk__synapse_ready
@ pcmk__synapse_executed
@ pcmk__synapse_confirmed
@ pcmk__synapse_failed
action_type_e
@ action_type_rsc
@ action_type_pseudo
@ action_type_crm
GList * inputs
uint32_t flags
GList * actions
Wrappers for and extensions to libxml2.