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-2020 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 "src/class/pmix_object.h" 77 78 BEGIN_C_DECLS 79 80 /* There are systems where all output needs to be redirected to syslog 81 * and away from stdout/stderr or files - e.g., embedded systems whose 82 * sole file system is in flash. To support such systems, we provide 83 * the following environmental variables that support redirecting -all- 84 * output (both from pmix_output and stdout/stderr of processes) to 85 * syslog: 86 * 87 * PMIX_OUTPUT_REDIRECT - set to "syslog" to redirect to syslog. Other 88 * options may someday be supported 89 * PMIX_OUTPUT_SYSLOG_PRI - set to "info", "error", or "warn" to have 90 * output sent to syslog at that priority 91 * PMIX_OUTPUT_SYSLOG_IDENT - a string identifier for the log 92 * 93 * We also define two global variables that notify all other 94 * layers that output is being redirected to syslog at the given 95 * priority. These are used, for example, by the IO forwarding 96 * subsystem to tell it to dump any collected output directly to 97 * syslog instead of forwarding it to another location. 98 */ 99 extern bool pmix_output_redirected_to_syslog; 100 extern int pmix_output_redirected_syslog_pri; 101 102 /** 103 * \class pmix_output_stream_t 104 * 105 * Structure used to request the opening of a PMIX output stream. A 106 * pointer to this structure is passed to pmix_output_open() to tell 107 * the pmix_output subsystem where to send output for a given stream. 108 * It is valid to specify multiple destinations of output for a stream 109 * -- output streams can be multiplexed to multiple different 110 * destinations through the pmix_output facility. 111 * 112 * Note that all strings in this struct are cached on the stream by 113 * value; there is no need to keep them allocated after the return 114 * from pmix_output_open(). 115 */ 116 struct pmix_output_stream_t { 117 /** Class parent */ 118 pmix_object_t super; 119 120 /** 121 * Indicate the starting verbosity level of the stream. 122 * 123 * Verbose levels are a convenience mechanisms, and are only 124 * consulted when output is sent to a stream through the 125 * pmix_output_verbose() function. Verbose levels are ignored in 126 * PMIX_OUTPUT() and pmix_output(). 127 * 128 * Valid verbose levels typically start at 0 (meaning "minimal 129 * information"). Higher verbosity levels generally indicate that 130 * more output and diagnostics should be displayed. 131 */ 132 int lds_verbose_level; 133 134 /** 135 * When pmix_output_stream_t::lds_want_syslog is true, this field is 136 * examined to see what priority output from the stream should be 137 * sent to the syslog. 138 * 139 * This value should be set as per the syslog(3) man page. It is 140 * typically the OR value of "facilty" and "level" values described 141 * in the man page. 142 */ 143 int lds_syslog_priority; 144 /** 145 * When pmix_output_stream_t::lds_want_syslog is true, this field is 146 * examined to see what ident value should be passed to openlog(3). 147 * 148 * If a NULL value is given, the string "pmix" is used. 149 */ 150 #if !defined(__WINDOWS__) 151 char *lds_syslog_ident; 152 #elif !defined(_MSC_VER) 153 char *lds_syslog_ident; 154 #else 155 HANDLE lds_syslog_ident; 156 #endif /* !defined(__WINDOWS__) */ 157 158 /** 159 * String prefix added to all output on the stream. 160 * 161 * When this field is non-NULL, it is prefixed to all lines of 162 * output on the stream. When this field is NULL, no prefix is 163 * added to each line of output in the stream. The prefix is copied 164 * to an internal structure in the call to pmix_output_open()! 165 */ 166 char *lds_prefix; 167 168 /** 169 * String suffix added to all output on the stream. 170 * 171 * When this field is non-NULL, it is appended to all lines of 172 * output on the stream. When this field is NULL, no suffix is 173 * added to each line of output in the stream. The suffix is copied 174 * to an internal structure in the call to pmix_output_open()! 175 */ 176 char *lds_suffix; 177 178 /** 179 * Indicates whether the output of the stream is 180 * debugging/developer-only output or not. 181 * 182 * This field should be "true" if the output is for debugging 183 * purposes only. In that case, the output will never be sent to 184 * the stream unless PMIX was configured with --enable-debug. 185 */ 186 bool lds_is_debugging; 187 188 /** 189 * Indicates whether output of the stream should be sent to the 190 * syslog or not. 191 * 192 * If this field is true, output from this stream is sent to the 193 * syslog, and the following fields are also examined: 194 * 195 * - lds_syslog_priority 196 * - lds_syslog_ident 197 * - lds_prefix 198 * 199 * If this field is false, the above three fields are ignored. 200 */ 201 bool lds_want_syslog; 202 203 /** 204 * Whether to send stream output to stdout or not. 205 * 206 * If this field is true, stream output is sent to stdout. 207 */ 208 bool lds_want_stdout; 209 /** 210 * Whether to send stream output to stderr or not. 211 * 212 * If this field is true, stream output is sent to stderr. 213 */ 214 bool lds_want_stderr; 215 216 /** 217 * Whether to send stream output to a file or not. 218 * 219 * When this field is true, stream output is sent to a file, and the 220 * following fields are also examined: 221 * 222 * - lds_want_file_append 223 * - lda_file_suffix 224 */ 225 bool lds_want_file; 226 /** 227 * When pmix_output_stream_t::lds_want_file is true, this field 228 * indicates whether to append the file (if it exists) or overwrite 229 * it. 230 * 231 * If false, the file is opened with the O_TRUNC flag. 232 */ 233 bool lds_want_file_append; 234 /** 235 * When pmix_output_stream_t::lds_want_file is true, this field 236 * indicates the string suffix to add to the filename. 237 * 238 * The output file will be in the directory and begin with the 239 * prefix set by pmix_output_set_output_file_info() (e.g., 240 * "$dir/$prefix$suffix"). If this field is NULL and 241 * lds_want_file is true, then the suffix "output.txt" is used. 242 * 243 * Note that it is possible that the output directory may not 244 * exist when pmix_output_open() is invoked. See pmix_output() 245 * for details on what happens in this situation. 246 */ 247 char *lds_file_suffix; 248 249 }; 250 251 /** 252 * Convenience typedef 253 */ 254 typedef struct pmix_output_stream_t pmix_output_stream_t; 255 256 /** 257 * Initializes the output stream system and opens a default 258 * "verbose" stream. 259 * 260 * @retval true Upon success. 261 * @retval false Upon failure. 262 * 263 * This should be the first function invoked in the output 264 * subsystem. After this call, the default "verbose" stream is open 265 * and can be written to via calls to pmix_output_verbose() and 266 * pmix_output_error(). 267 * 268 * By definition, the default verbose stream has a handle ID of 0, 269 * and has a verbose level of 0. 270 */ 271 PMIX_EXPORT bool pmix_output_init(void); 272 273 /** 274 * Shut down the output stream system. 275 * 276 * Shut down the output stream system, including the default verbose 277 * stream. 278 */ 279 PMIX_EXPORT void pmix_output_finalize(void); 280 281 /** 282 * Opens an output stream. 283 * 284 * @param lds A pointer to pmix_output_stream_t describing what the 285 * characteristics of the output stream should be. 286 * 287 * This function opens an output stream and returns an integer 288 * handle. The caller is responsible for maintaining the handle and 289 * using it in successive calls to PMIX_OUTPUT(), pmix_output(), 290 * pmix_output_switch(), and pmix_output_close(). 291 * 292 * If lds is NULL, the default descriptions will be used, meaning 293 * that output will only be sent to stderr. 294 * 295 * It is safe to have multiple threads invoke this function 296 * simultaneously; their execution will be serialized in an 297 * unspecified manner. 298 * 299 * Be sure to see pmix_output() for a description of what happens 300 * when open_open() / pmix_output() is directed to send output to a 301 * file but the process session directory does not yet exist. 302 */ 303 PMIX_EXPORT int pmix_output_open(pmix_output_stream_t *lds); 304 305 /** 306 * Re-opens / redirects an output stream. 307 * 308 * @param output_id Stream handle to reopen 309 * @param lds A pointer to pmix_output_stream_t describing what the 310 * characteristics of the reopened output stream should be. 311 * 312 * This function redirects an existing stream into a new [set of] 313 * location[s], as specified by the lds parameter. If the output_id 314 * passed is invalid, this call is effectively the same as opening a 315 * new stream with a specific stream handle. 316 */ 317 PMIX_EXPORT int pmix_output_reopen(int output_id, pmix_output_stream_t *lds); 318 319 /** 320 * Enables and disables output streams. 321 * 322 * @param output_id Stream handle to switch 323 * @param enable Boolean indicating whether to enable the stream 324 * output or not. 325 * 326 * @returns The previous enable state of the stream (true == enabled, 327 * false == disabled). 328 * 329 * The output of a stream can be temporarily disabled by passing an 330 * enable value to false, and later resumed by passing an enable 331 * value of true. This does not close the stream -- it simply tells 332 * the pmix_output subsystem to intercept and discard any output sent 333 * to the stream via PMIX_OUTPUT() or pmix_output() until the output 334 * is re-enabled. 335 */ 336 PMIX_EXPORT bool pmix_output_switch(int output_id, bool enable); 337 338 /** 339 * \internal 340 * 341 * Reopens all existing output streams. 342 * 343 * This function should never be called by user applications; it is 344 * typically only invoked after a restart (i.e., in a new process) 345 * where output streams need to be re-initialized. 346 */ 347 PMIX_EXPORT void pmix_output_reopen_all(void); 348 349 /** 350 * Close an output stream. 351 * 352 * @param output_id Handle of the stream to close. 353 * 354 * Close an output stream. No output will be sent to the stream 355 * after it is closed. Be aware that output handles tend to be 356 * re-used; it is possible that after a stream is closed, if another 357 * stream is opened, it will get the same handle value. 358 */ 359 PMIX_EXPORT void pmix_output_close(int output_id); 360 361 /** 362 * Main function to send output to a stream. 363 * 364 * @param output_id Stream id returned from pmix_output_open(). 365 * @param format printf-style format string. 366 * @param varargs printf-style varargs list to fill the string 367 * specified by the format parameter. 368 * 369 * This is the main function to send output to custom streams (note 370 * that output to the default "verbose" stream is handled through 371 * pmix_output_verbose() and pmix_output_error()). 372 * 373 * It is never necessary to send a trailing "\n" in the strings to 374 * this function; some streams requires newlines, others do not -- 375 * this function will append newlines as necessary. 376 * 377 * Verbosity levels are ignored in this function. 378 * 379 * Note that for output streams that are directed to files, the 380 * files are stored under the process' session directory. If the 381 * session directory does not exist when pmix_output() is invoked, 382 * the output will be discarded! Once the session directory is 383 * created, pmix_output() will automatically create the file and 384 * writing to it. 385 */ 386 PMIX_EXPORT void pmix_output(int output_id, const char *format, ...) __pmix_attribute_format__(__printf__, 2, 3); 387 388 /** 389 * Send output to a stream only if the passed verbosity level is 390 * high enough. 391 * 392 * @param output_id Stream id returned from pmix_output_open(). 393 * @param level Target verbosity level. 394 * @param format printf-style format string. 395 * @param varargs printf-style varargs list to fill the string 396 * specified by the format parameter. 397 * 398 * Output is only sent to the stream if the current verbosity level 399 * is greater than or equal to the level parameter. This mechanism 400 * can be used to send "information" kinds of output to user 401 * applications, but only when the user has asked for a high enough 402 * verbosity level. 403 * 404 * It is never necessary to send a trailing "\n" in the strings to 405 * this function; some streams requires newlines, others do not -- 406 * this function will append newlines as necessary. 407 * 408 * This function is really a convenience wrapper around checking the 409 * current verbosity level set on the stream, and if the passed 410 * level is less than or equal to the stream's verbosity level, this 411 * function will effectively invoke pmix_output to send the output to 412 * the stream. 413 * 414 * @see pmix_output_set_verbosity() 415 */ 416 #define pmix_output_verbose(verbose_level, output_id, ...) \ 417 if (pmix_output_check_verbosity(verbose_level, output_id)) { \ 418 pmix_output(output_id, __VA_ARGS__); \ 419 } 420 421 PMIX_EXPORT bool pmix_output_check_verbosity(int verbose_level, int output_id); 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_ */ 547