This source file includes following definitions.
- log_subprocess_output
- log_free_priv
- log_init
- log_finish
- log_reset
- log_version
- G_GNUC_PRINTF
- log_output_xml
- G_GNUC_PRINTF
- G_GNUC_PRINTF
- log_end_list
- G_GNUC_PRINTF
- G_GNUC_PRINTF
- log_is_quiet
- log_spacer
- log_progress
- log_prompt
- pcmk__mk_log_output
- pcmk__output_get_log_level
- pcmk__output_set_log_level
- pcmk__output_set_log_filter
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/common/cmdline_internal.h>
12
13 #include <ctype.h>
14 #include <stdarg.h>
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18
19 GOptionEntry pcmk__log_output_entries[] = {
20 { NULL }
21 };
22
23 typedef struct private_data_s {
24
25 GQueue *prefixes;
26 uint8_t log_level;
27 const char *function;
28 const char *file;
29 uint32_t line;
30 uint32_t tags;
31 } private_data_t;
32
33
34
35
36
37
38
39
40
41 #define logger(priv, fmt, args...) do { \
42 qb_log_from_external_source(pcmk__s((priv)->function, __func__), \
43 pcmk__s((priv)->file, __FILE__), fmt, (priv)->log_level, \
44 (((priv)->line == 0)? __LINE__ : (priv)->line), (priv)->tags, \
45 ##args); \
46 } while (0);
47
48
49
50
51
52
53
54
55
56
57 #define logger_va(priv, level, fmt, ap) do { \
58 qb_log_from_external_source_va(pcmk__s((priv)->function, __func__), \
59 pcmk__s((priv)->file, __FILE__), fmt, level, \
60 (((priv)->line == 0)? __LINE__ : (priv)->line), (priv)->tags, \
61 ap); \
62 } while (0);
63
64 static void
65 log_subprocess_output(pcmk__output_t *out, int exit_status,
66 const char *proc_stdout, const char *proc_stderr) {
67
68 }
69
70 static void
71 log_free_priv(pcmk__output_t *out) {
72 private_data_t *priv = NULL;
73
74 if (out == NULL || out->priv == NULL) {
75 return;
76 }
77
78 priv = out->priv;
79
80 g_queue_free(priv->prefixes);
81 free(priv);
82 out->priv = NULL;
83 }
84
85 static bool
86 log_init(pcmk__output_t *out) {
87 private_data_t *priv = NULL;
88
89 CRM_ASSERT(out != NULL);
90
91
92 if (out->priv != NULL) {
93 return true;
94 }
95
96 out->priv = calloc(1, sizeof(private_data_t));
97 if (out->priv == NULL) {
98 return false;
99 }
100
101 priv = out->priv;
102
103 priv->prefixes = g_queue_new();
104 priv->log_level = LOG_INFO;
105
106 return true;
107 }
108
109 static void
110 log_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
111
112 }
113
114 static void
115 log_reset(pcmk__output_t *out) {
116 CRM_ASSERT(out != NULL);
117
118 out->dest = freopen(NULL, "w", out->dest);
119 CRM_ASSERT(out->dest != NULL);
120
121 log_free_priv(out);
122 log_init(out);
123 }
124
125 static void
126 log_version(pcmk__output_t *out, bool extended) {
127 private_data_t *priv = NULL;
128
129 CRM_ASSERT(out != NULL && out->priv != NULL);
130 priv = out->priv;
131
132 if (extended) {
133 logger(priv, "Pacemaker %s (Build: %s): %s",
134 PACEMAKER_VERSION, BUILD_VERSION, CRM_FEATURES);
135 } else {
136 logger(priv, "Pacemaker " PACEMAKER_VERSION);
137 logger(priv, "Written by Andrew Beekhof and "
138 "the Pacemaker project contributors");
139 }
140 }
141
142 G_GNUC_PRINTF(2, 3)
143 static void
144 log_err(pcmk__output_t *out, const char *format, ...)
145 {
146 va_list ap;
147 private_data_t *priv = NULL;
148
149 CRM_ASSERT((out != NULL) && (out->priv != NULL));
150 priv = out->priv;
151
152
153
154
155 va_start(ap, format);
156 logger_va(priv, LOG_ERR, format, ap);
157 va_end(ap);
158 }
159
160 static void
161 log_output_xml(pcmk__output_t *out, const char *name, const char *buf) {
162 xmlNodePtr node = NULL;
163 private_data_t *priv = NULL;
164
165 CRM_ASSERT(out != NULL && out->priv != NULL);
166 priv = out->priv;
167
168 node = create_xml_node(NULL, name);
169 xmlNodeSetContent(node, (pcmkXmlStr) buf);
170 do_crm_log_xml(priv->log_level, name, node);
171 free(node);
172 }
173
174 G_GNUC_PRINTF(4, 5)
175 static void
176 log_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plural_noun,
177 const char *format, ...) {
178 int len = 0;
179 va_list ap;
180 char* buffer = NULL;
181 private_data_t *priv = NULL;
182
183 CRM_ASSERT(out != NULL && out->priv != NULL);
184 priv = out->priv;
185
186 va_start(ap, format);
187 len = vasprintf(&buffer, format, ap);
188 CRM_ASSERT(len >= 0);
189 va_end(ap);
190
191
192
193
194 if(strcmp(buffer, "") == 0) {
195
196 }
197
198 g_queue_push_tail(priv->prefixes, buffer);
199 }
200
201 G_GNUC_PRINTF(3, 4)
202 static void
203 log_list_item(pcmk__output_t *out, const char *name, const char *format, ...) {
204 int len = 0;
205 va_list ap;
206 private_data_t *priv = NULL;
207 char prefix[LINE_MAX] = { 0 };
208 int offset = 0;
209 char* buffer = NULL;
210
211 CRM_ASSERT(out != NULL && out->priv != NULL);
212 priv = out->priv;
213
214 for (GList* gIter = priv->prefixes->head; gIter; gIter = gIter->next) {
215 if (strcmp(prefix, "") != 0) {
216 offset += snprintf(prefix + offset, LINE_MAX - offset, ": %s", (char *)gIter->data);
217 } else {
218 offset = snprintf(prefix, LINE_MAX, "%s", (char *)gIter->data);
219 }
220 }
221
222 va_start(ap, format);
223 len = vasprintf(&buffer, format, ap);
224 CRM_ASSERT(len >= 0);
225 va_end(ap);
226
227 if (strcmp(buffer, "") != 0) {
228 if ((name != NULL) && (strcmp(name, "") != 0)) {
229 if (strcmp(prefix, "") != 0) {
230 logger(priv, "%s: %s: %s", prefix, name, buffer);
231 } else {
232 logger(priv, "%s: %s", name, buffer);
233 }
234 } else {
235 if (strcmp(prefix, "") != 0) {
236 logger(priv, "%s: %s", prefix, buffer);
237 } else {
238 logger(priv, "%s", buffer);
239 }
240 }
241 }
242 free(buffer);
243 }
244
245 static void
246 log_end_list(pcmk__output_t *out) {
247 private_data_t *priv = NULL;
248
249 CRM_ASSERT(out != NULL && out->priv != NULL);
250 priv = out->priv;
251
252 if (priv->prefixes == NULL) {
253 return;
254 }
255 CRM_ASSERT(priv->prefixes->tail != NULL);
256
257 free((char *)priv->prefixes->tail->data);
258 g_queue_pop_tail(priv->prefixes);
259 }
260
261 G_GNUC_PRINTF(2, 3)
262 static int
263 log_info(pcmk__output_t *out, const char *format, ...)
264 {
265 va_list ap;
266 private_data_t *priv = NULL;
267
268 CRM_ASSERT(out != NULL && out->priv != NULL);
269 priv = out->priv;
270
271
272
273
274 va_start(ap, format);
275 logger_va(priv, priv->log_level, format, ap);
276 va_end(ap);
277
278 return pcmk_rc_ok;
279 }
280
281 G_GNUC_PRINTF(2, 3)
282 static int
283 log_transient(pcmk__output_t *out, const char *format, ...)
284 {
285 va_list ap;
286 private_data_t *priv = NULL;
287
288 CRM_ASSERT(out != NULL && out->priv != NULL);
289 priv = out->priv;
290
291 va_start(ap, format);
292 logger_va(priv, QB_MAX(priv->log_level, LOG_DEBUG), format, ap);
293 va_end(ap);
294
295 return pcmk_rc_ok;
296 }
297
298 static bool
299 log_is_quiet(pcmk__output_t *out) {
300 return false;
301 }
302
303 static void
304 log_spacer(pcmk__output_t *out) {
305
306 }
307
308 static void
309 log_progress(pcmk__output_t *out, bool end) {
310
311 }
312
313 static void
314 log_prompt(const char *prompt, bool echo, char **dest) {
315
316 }
317
318 pcmk__output_t *
319 pcmk__mk_log_output(char **argv) {
320 pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
321
322 if (retval == NULL) {
323 return NULL;
324 }
325
326 retval->fmt_name = "log";
327 retval->request = pcmk__quote_cmdline(argv);
328
329 retval->init = log_init;
330 retval->free_priv = log_free_priv;
331 retval->finish = log_finish;
332 retval->reset = log_reset;
333
334 retval->register_message = pcmk__register_message;
335 retval->message = pcmk__call_message;
336
337 retval->subprocess_output = log_subprocess_output;
338 retval->version = log_version;
339 retval->info = log_info;
340 retval->transient = log_transient;
341 retval->err = log_err;
342 retval->output_xml = log_output_xml;
343
344 retval->begin_list = log_begin_list;
345 retval->list_item = log_list_item;
346 retval->end_list = log_end_list;
347
348 retval->is_quiet = log_is_quiet;
349 retval->spacer = log_spacer;
350 retval->progress = log_progress;
351 retval->prompt = log_prompt;
352
353 return retval;
354 }
355
356 uint8_t
357 pcmk__output_get_log_level(const pcmk__output_t *out)
358 {
359 private_data_t *priv = NULL;
360
361 CRM_ASSERT((out != NULL) && (out->priv != NULL));
362 CRM_CHECK(pcmk__str_eq(out->fmt_name, "log", pcmk__str_none), return 0);
363
364 priv = out->priv;
365 return priv->log_level;
366 }
367
368 void
369 pcmk__output_set_log_level(pcmk__output_t *out, uint8_t log_level) {
370 private_data_t *priv = NULL;
371
372 CRM_ASSERT(out != NULL && out->priv != NULL);
373 CRM_CHECK(pcmk__str_eq(out->fmt_name, "log", pcmk__str_none), return);
374
375 priv = out->priv;
376 priv->log_level = log_level;
377 }
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 void
394 pcmk__output_set_log_filter(pcmk__output_t *out, const char *file,
395 const char *function, uint32_t line, uint32_t tags)
396 {
397 private_data_t *priv = NULL;
398
399 CRM_ASSERT((out != NULL) && (out->priv != NULL));
400 CRM_CHECK(pcmk__str_eq(out->fmt_name, "log", pcmk__str_none), return);
401
402 priv = out->priv;
403 priv->file = file;
404 priv->function = function;
405 priv->line = line;
406 priv->tags = tags;
407 }