root/opal/util/output.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   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 

/* [<][>][^][v][top][bottom][index][help] */