1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2006 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2007-2011 Cisco Systems, Inc. All rights reserved.
13 * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
14 * Copyright (c) 2015-2017 Intel, Inc. All rights reserved.
15 * Copyright (c) 2016 Research Organization for Information Science
16 * and Technology (RIST). All rights reserved.
17 * $COPYRIGHT$
18 *
19 * Additional copyrights may follow
20 *
21 * $HEADER$
22 */
23
24 /** @file
25 * PMIX output stream facility.
26 *
27 * The PMIX output stream facility is used to send output from the PMIX
28 * libraries to output devices. It is meant to fully replace all
29 * forms of printf() (and friends). Output streams are opened via the
30 * pmix_output_open() function call, and then sent output via
31 * pmix_output_verbose(), PMIX_OUTPUT(), and pmix_output(). Streams are
32 * closed with pmix_output_close().
33 *
34 * Streams can multiplex output to several kinds of outputs (one of
35 * each):
36 *
37 * - the syslog (if available)
38 * - standard output
39 * - standard error
40 * - file
41 *
42 * Which outputs to use are specified during pmix_output_open().
43 *
44 * WARNING: When using "file" as an output destination, be aware that
45 * the file may not exist until the session directory for the process
46 * exists. This is at least part of the way through MPI_INIT (for
47 * example). Most MCA components and internals of PMIx won't be
48 * affected by this, but some RTE / startup aspects of PMIx will
49 * not be able to write to a file for output. See pmix_output() for
50 * details on what happens in these cases.
51 *
52 * pmix_output_open() returns an integer handle that is used in
53 * successive calls to PMIX_OUTPUT() and pmix_output() to send output to
54 * the stream.
55 *
56 * The default "verbose" stream is opened after invoking
57 * pmix_output_init() (and closed after invoking
58 * pmix_output_finalize()). This stream outputs to stderr only, and
59 * has a stream handle ID of 0.
60 *
61 * It is erroneous to have one thread close a stream and have another
62 * try to write to it. Multiple threads writing to a single stream
63 * will be serialized in an unspecified order.
64 */
65
66 #ifndef PMIX_OUTPUT_H_
67 #define PMIX_OUTPUT_H_
68
69 #include <src/include/pmix_config.h>
70
71
72 #ifdef HAVE_STDARG_H
73 #include <stdarg.h>
74 #endif
75
76 #include "pmix_rename.h"
77 #include "src/class/pmix_object.h"
78
79 BEGIN_C_DECLS
80
81 /* There are systems where all output needs to be redirected to syslog
82 * and away from stdout/stderr or files - e.g., embedded systems whose
83 * sole file system is in flash. To support such systems, we provide
84 * the following environmental variables that support redirecting -all-
85 * output (both from pmix_output and stdout/stderr of processes) to
86 * syslog:
87 *
88 * PMIX_OUTPUT_REDIRECT - set to "syslog" to redirect to syslog. Other
89 * options may someday be supported
90 * PMIX_OUTPUT_SYSLOG_PRI - set to "info", "error", or "warn" to have
91 * output sent to syslog at that priority
92 * PMIX_OUTPUT_SYSLOG_IDENT - a string identifier for the log
93 *
94 * We also define two global variables that notify all other
95 * layers that output is being redirected to syslog at the given
96 * priority. These are used, for example, by the IO forwarding
97 * subsystem to tell it to dump any collected output directly to
98 * syslog instead of forwarding it to another location.
99 */
100 extern bool pmix_output_redirected_to_syslog;
101 extern int pmix_output_redirected_syslog_pri;
102
103 /**
104 * \class pmix_output_stream_t
105 *
106 * Structure used to request the opening of a PMIX output stream. A
107 * pointer to this structure is passed to pmix_output_open() to tell
108 * the pmix_output subsystem where to send output for a given stream.
109 * It is valid to specify multiple destinations of output for a stream
110 * -- output streams can be multiplexed to multiple different
111 * destinations through the pmix_output facility.
112 *
113 * Note that all strings in this struct are cached on the stream by
114 * value; there is no need to keep them allocated after the return
115 * from pmix_output_open().
116 */
117 struct pmix_output_stream_t {
118 /** Class parent */
119 pmix_object_t super;
120
121 /**
122 * Indicate the starting verbosity level of the stream.
123 *
124 * Verbose levels are a convenience mechanisms, and are only
125 * consulted when output is sent to a stream through the
126 * pmix_output_verbose() function. Verbose levels are ignored in
127 * PMIX_OUTPUT() and pmix_output().
128 *
129 * Valid verbose levels typically start at 0 (meaning "minimal
130 * information"). Higher verbosity levels generally indicate that
131 * more output and diagnostics should be displayed.
132 */
133 int lds_verbose_level;
134
135 /**
136 * When pmix_output_stream_t::lds_want_syslog is true, this field is
137 * examined to see what priority output from the stream should be
138 * sent to the syslog.
139 *
140 * This value should be set as per the syslog(3) man page. It is
141 * typically the OR value of "facilty" and "level" values described
142 * in the man page.
143 */
144 int lds_syslog_priority;
145 /**
146 * When pmix_output_stream_t::lds_want_syslog is true, this field is
147 * examined to see what ident value should be passed to openlog(3).
148 *
149 * If a NULL value is given, the string "pmix" is used.
150 */
151 #if !defined(__WINDOWS__)
152 char *lds_syslog_ident;
153 #elif !defined(_MSC_VER)
154 char *lds_syslog_ident;
155 #else
156 HANDLE lds_syslog_ident;
157 #endif /* !defined(__WINDOWS__) */
158
159 /**
160 * String prefix added to all output on the stream.
161 *
162 * When this field is non-NULL, it is prefixed to all lines of
163 * output on the stream. When this field is NULL, no prefix is
164 * added to each line of output in the stream. The prefix is copied
165 * to an internal structure in the call to pmix_output_open()!
166 */
167 char *lds_prefix;
168
169 /**
170 * String suffix added to all output on the stream.
171 *
172 * When this field is non-NULL, it is appended to all lines of
173 * output on the stream. When this field is NULL, no suffix is
174 * added to each line of output in the stream. The suffix is copied
175 * to an internal structure in the call to pmix_output_open()!
176 */
177 char *lds_suffix;
178
179 /**
180 * Indicates whether the output of the stream is
181 * debugging/developer-only output or not.
182 *
183 * This field should be "true" if the output is for debugging
184 * purposes only. In that case, the output will never be sent to
185 * the stream unless PMIX was configured with --enable-debug.
186 */
187 bool lds_is_debugging;
188
189 /**
190 * Indicates whether output of the stream should be sent to the
191 * syslog or not.
192 *
193 * If this field is true, output from this stream is sent to the
194 * syslog, and the following fields are also examined:
195 *
196 * - lds_syslog_priority
197 * - lds_syslog_ident
198 * - lds_prefix
199 *
200 * If this field is false, the above three fields are ignored.
201 */
202 bool lds_want_syslog;
203
204 /**
205 * Whether to send stream output to stdout or not.
206 *
207 * If this field is true, stream output is sent to stdout.
208 */
209 bool lds_want_stdout;
210 /**
211 * Whether to send stream output to stderr or not.
212 *
213 * If this field is true, stream output is sent to stderr.
214 */
215 bool lds_want_stderr;
216
217 /**
218 * Whether to send stream output to a file or not.
219 *
220 * When this field is true, stream output is sent to a file, and the
221 * following fields are also examined:
222 *
223 * - lds_want_file_append
224 * - lda_file_suffix
225 */
226 bool lds_want_file;
227 /**
228 * When pmix_output_stream_t::lds_want_file is true, this field
229 * indicates whether to append the file (if it exists) or overwrite
230 * it.
231 *
232 * If false, the file is opened with the O_TRUNC flag.
233 */
234 bool lds_want_file_append;
235 /**
236 * When pmix_output_stream_t::lds_want_file is true, this field
237 * indicates the string suffix to add to the filename.
238 *
239 * The output file will be in the directory and begin with the
240 * prefix set by pmix_output_set_output_file_info() (e.g.,
241 * "$dir/$prefix$suffix"). If this field is NULL and
242 * lds_want_file is true, then the suffix "output.txt" is used.
243 *
244 * Note that it is possible that the output directory may not
245 * exist when pmix_output_open() is invoked. See pmix_output()
246 * for details on what happens in this situation.
247 */
248 char *lds_file_suffix;
249
250 };
251
252 /**
253 * Convenience typedef
254 */
255 typedef struct pmix_output_stream_t pmix_output_stream_t;
256
257 /**
258 * Initializes the output stream system and opens a default
259 * "verbose" stream.
260 *
261 * @retval true Upon success.
262 * @retval false Upon failure.
263 *
264 * This should be the first function invoked in the output
265 * subsystem. After this call, the default "verbose" stream is open
266 * and can be written to via calls to pmix_output_verbose() and
267 * pmix_output_error().
268 *
269 * By definition, the default verbose stream has a handle ID of 0,
270 * and has a verbose level of 0.
271 */
272 PMIX_EXPORT bool pmix_output_init(void);
273
274 /**
275 * Shut down the output stream system.
276 *
277 * Shut down the output stream system, including the default verbose
278 * stream.
279 */
280 PMIX_EXPORT void pmix_output_finalize(void);
281
282 /**
283 * Opens an output stream.
284 *
285 * @param lds A pointer to pmix_output_stream_t describing what the
286 * characteristics of the output stream should be.
287 *
288 * This function opens an output stream and returns an integer
289 * handle. The caller is responsible for maintaining the handle and
290 * using it in successive calls to PMIX_OUTPUT(), pmix_output(),
291 * pmix_output_switch(), and pmix_output_close().
292 *
293 * If lds is NULL, the default descriptions will be used, meaning
294 * that output will only be sent to stderr.
295 *
296 * It is safe to have multiple threads invoke this function
297 * simultaneously; their execution will be serialized in an
298 * unspecified manner.
299 *
300 * Be sure to see pmix_output() for a description of what happens
301 * when open_open() / pmix_output() is directed to send output to a
302 * file but the process session directory does not yet exist.
303 */
304 PMIX_EXPORT int pmix_output_open(pmix_output_stream_t *lds);
305
306 /**
307 * Re-opens / redirects an output stream.
308 *
309 * @param output_id Stream handle to reopen
310 * @param lds A pointer to pmix_output_stream_t describing what the
311 * characteristics of the reopened output stream should be.
312 *
313 * This function redirects an existing stream into a new [set of]
314 * location[s], as specified by the lds parameter. If the output_id
315 * passed is invalid, this call is effectively the same as opening a
316 * new stream with a specific stream handle.
317 */
318 PMIX_EXPORT int pmix_output_reopen(int output_id, pmix_output_stream_t *lds);
319
320 /**
321 * Enables and disables output streams.
322 *
323 * @param output_id Stream handle to switch
324 * @param enable Boolean indicating whether to enable the stream
325 * output or not.
326 *
327 * @returns The previous enable state of the stream (true == enabled,
328 * false == disabled).
329 *
330 * The output of a stream can be temporarily disabled by passing an
331 * enable value to false, and later resumed by passing an enable
332 * value of true. This does not close the stream -- it simply tells
333 * the pmix_output subsystem to intercept and discard any output sent
334 * to the stream via PMIX_OUTPUT() or pmix_output() until the output
335 * is re-enabled.
336 */
337 PMIX_EXPORT bool pmix_output_switch(int output_id, bool enable);
338
339 /**
340 * \internal
341 *
342 * Reopens all existing output streams.
343 *
344 * This function should never be called by user applications; it is
345 * typically only invoked after a restart (i.e., in a new process)
346 * where output streams need to be re-initialized.
347 */
348 PMIX_EXPORT void pmix_output_reopen_all(void);
349
350 /**
351 * Close an output stream.
352 *
353 * @param output_id Handle of the stream to close.
354 *
355 * Close an output stream. No output will be sent to the stream
356 * after it is closed. Be aware that output handles tend to be
357 * re-used; it is possible that after a stream is closed, if another
358 * stream is opened, it will get the same handle value.
359 */
360 PMIX_EXPORT void pmix_output_close(int output_id);
361
362 /**
363 * Main function to send output to a stream.
364 *
365 * @param output_id Stream id returned from pmix_output_open().
366 * @param format printf-style format string.
367 * @param varargs printf-style varargs list to fill the string
368 * specified by the format parameter.
369 *
370 * This is the main function to send output to custom streams (note
371 * that output to the default "verbose" stream is handled through
372 * pmix_output_verbose() and pmix_output_error()).
373 *
374 * It is never necessary to send a trailing "\n" in the strings to
375 * this function; some streams requires newlines, others do not --
376 * this function will append newlines as necessary.
377 *
378 * Verbosity levels are ignored in this function.
379 *
380 * Note that for output streams that are directed to files, the
381 * files are stored under the process' session directory. If the
382 * session directory does not exist when pmix_output() is invoked,
383 * the output will be discarded! Once the session directory is
384 * created, pmix_output() will automatically create the file and
385 * writing to it.
386 */
387 PMIX_EXPORT void pmix_output(int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 2, 3);
388
389 /**
390 * Send output to a stream only if the passed verbosity level is
391 * high enough.
392 *
393 * @param output_id Stream id returned from pmix_output_open().
394 * @param level Target verbosity level.
395 * @param format printf-style format string.
396 * @param varargs printf-style varargs list to fill the string
397 * specified by the format parameter.
398 *
399 * Output is only sent to the stream if the current verbosity level
400 * is greater than or equal to the level parameter. This mechanism
401 * can be used to send "information" kinds of output to user
402 * applications, but only when the user has asked for a high enough
403 * verbosity level.
404 *
405 * It is never necessary to send a trailing "\n" in the strings to
406 * this function; some streams requires newlines, others do not --
407 * this function will append newlines as necessary.
408 *
409 * This function is really a convenience wrapper around checking the
410 * current verbosity level set on the stream, and if the passed
411 * level is less than or equal to the stream's verbosity level, this
412 * function will effectively invoke pmix_output to send the output to
413 * the stream.
414 *
415 * @see pmix_output_set_verbosity()
416 */
417 PMIX_EXPORT void pmix_output_verbose(int verbose_level, int output_id,
418 const char *format, ...) __pmix_attribute_format__(__printf__, 3, 4);
419
420 /**
421 * Same as pmix_output_verbose(), but takes a va_list form of varargs.
422 */
423 PMIX_EXPORT void pmix_output_vverbose(int verbose_level, int output_id,
424 const char *format, va_list ap) __pmix_attribute_format__(__printf__, 3, 0);
425
426 /**
427 * Set the verbosity level for a stream.
428 *
429 * @param output_id Stream id returned from pmix_output_open().
430 * @param level New verbosity level
431 *
432 * This function sets the verbosity level on a given stream. It
433 * will be used for all future invocations of pmix_output_verbose().
434 */
435 PMIX_EXPORT void pmix_output_set_verbosity(int output_id, int level);
436
437 /**
438 * Get the verbosity level for a stream
439 *
440 * @param output_id Stream id returned from pmix_output_open()
441 * @returns Verbosity of stream
442 */
443 PMIX_EXPORT int pmix_output_get_verbosity(int output_id);
444
445 /**
446 * Set characteristics for output files.
447 *
448 * @param dir Directory where output files will go
449 * @param olddir If non-NULL, the directory where output files
450 * were previously opened
451 * @param prefix Prefix of files in the output directory
452 * @param oldprefix If non-NULL, the old prefix
453 *
454 * This function controls the final filename used for all new
455 * output streams that request output files. Specifically, when
456 * pmix_output_stream_t::lds_want_file is true, the output
457 * filename will be of the form $dir/$prefix$suffix.
458 *
459 * The default value for the output directory is whatever is
460 * specified in the TMPDIR environment variable if it exists, or
461 * $HOME if it does not. The default value for the prefix is
462 * "output-pid<pid>-" (where "<pid>" is replaced by the PID of the
463 * current process).
464 *
465 * If dir or prefix are NULL, new values are not set. The strings
466 * represented by dir and prefix are copied into internal storage;
467 * it is safe to pass string constants or free() these values
468 * after pmix_output_set_output_file_info() returns.
469 *
470 * If olddir or oldprefix are not NULL, copies of the old
471 * directory and prefix (respectively) are returned in these
472 * parameters. The caller is responsible for calling (free) on
473 * these values. This allows one to get the old values, output an
474 * output file in a specific directory and/or with a specific
475 * prefix, and then restore the old values.
476 *
477 * Note that this function only affects the creation of \em new
478 * streams -- streams that have already started writing to output
479 * files are not affected (i.e., their output files are not moved
480 * to the new directory). More specifically, the pmix_output
481 * system only opens/creates output files lazily -- so calling
482 * this function affects both new streams \em and any stream that
483 * was previously opened but had not yet output anything.
484 */
485 PMIX_EXPORT void pmix_output_set_output_file_info(const char *dir,
486 const char *prefix,
487 char **olddir,
488 char **oldprefix);
489
490 /**
491 * Same as pmix_output_verbose(), but pointer to buffer and size.
492 */
493 PMIX_EXPORT void pmix_output_hexdump(int verbose_level, int output_id,
494 void *ptr, int buflen);
495
496 #if PMIX_ENABLE_DEBUG
497 /**
498 * Main macro for use in sending debugging output to output streams;
499 * will be "compiled out" when PMIX is configured without
500 * --enable-debug.
501 *
502 * @see pmix_output()
503 */
504 #define PMIX_OUTPUT(a) pmix_output a
505
506 /**
507 * Macro for use in sending debugging output to the output
508 * streams. Will be "compiled out" when PMIX is configured
509 * without --enable-debug.
510 *
511 * @see pmix_output_verbose()
512 */
513 #define PMIX_OUTPUT_VERBOSE(a) pmix_output_verbose a
514 #else
515 /**
516 * Main macro for use in sending debugging output to output streams;
517 * will be "compiled out" when PMIX is configured without
518 * --enable-debug.
519 *
520 * @see pmix_output()
521 */
522 #define PMIX_OUTPUT(a)
523
524 /**
525 * Macro for use in sending debugging output to the output
526 * streams. Will be "compiled out" when PMIX is configured
527 * without --enable-debug.
528 *
529 * @see pmix_output_verbose()
530 */
531 #define PMIX_OUTPUT_VERBOSE(a)
532 #endif
533
534 /**
535 * Declare the class of this type. Note that the constructor for
536 * this class is for convenience only -- it is \em not necessary
537 * to be invoked. If the constructor it used, it sets all values
538 * in the struct to be false / 0 (i.e., turning off all output).
539 * The intended usage is to invoke the constructor and then enable
540 * the output fields that you want.
541 */
542 PMIX_CLASS_DECLARATION(pmix_output_stream_t);
543
544 END_C_DECLS
545
546 #endif /* PMIX_OUTPUT_H_ */