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