Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
logger.cpp
1 // Copyright (c) 2019-2023, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
8 
11 
12 namespace serac::logger {
13 
14 bool initialize(MPI_Comm comm)
15 {
16  namespace slic = axom::slic;
17 
18  if (!slic::isInitialized()) {
19  slic::initialize();
20  }
21 
22  auto [num_ranks, rank] = getMPIInfo(comm);
23 
24  // Mark rank 0 as the root for message filtering macros
25  slic::setIsRoot(rank == 0);
26 
27  std::string loggerName = num_ranks > 1 ? "serac_parallel_logger" : "serac_serial_logger";
28  slic::createLogger(loggerName);
29  slic::activateLogger(loggerName);
30  if (!slic::activateLogger(loggerName)) {
31  // Can't log through SLIC since it just failed to activate
32  std::cerr << "Error: Failed to activate logger: " << loggerName << std::endl;
33  return false;
34  }
35 
36  // Console streams, std::cout for info/debug, std::cerr for warnings/errors
37  slic::LogStream* i_logstream = nullptr; // info
38  slic::LogStream* d_logstream = nullptr; // debug
39  slic::LogStream* we_logstream = nullptr; // warnings and errors
40 
41  // Stream formatting strings
42  std::string i_format_string = "<MESSAGE>\n";
43  std::string d_format_string = "[<LEVEL>]: <MESSAGE>\n";
44  std::string we_format_string = "[<LEVEL> (<FILE>:<LINE>)]\n<MESSAGE>\n\n";
45 
46  // Only create a parallel logger when there is more than one rank
47  if (num_ranks > 1) {
48  // Add rank to format strings if parallel
49  // Note: i_format_string's extra space is on purpose due to no space on above string
50  i_format_string = "[<RANK>] " + i_format_string;
51  d_format_string = "[<RANK>]" + d_format_string;
52  we_format_string = "[<RANK>]" + we_format_string;
53 
54  const int RLIMIT = 8;
55 
56  i_logstream = new slic::LumberjackStream(&std::cout, comm, RLIMIT, i_format_string);
57  d_logstream = new slic::LumberjackStream(&std::cout, comm, RLIMIT, d_format_string);
58  we_logstream = new slic::LumberjackStream(&std::cerr, comm, RLIMIT, we_format_string);
59  } else {
60  i_logstream = new slic::GenericOutputStream(&std::cout, i_format_string);
61  d_logstream = new slic::GenericOutputStream(&std::cout, d_format_string);
62  we_logstream = new slic::GenericOutputStream(&std::cerr, we_format_string);
63  }
64 
65  slic::setLoggingMsgLevel(slic::message::Debug);
66 
67  // Add message levels to streams
68  addStreamToMsgLevel(i_logstream, slic::message::Info);
69  addStreamToMsgLevel(d_logstream, slic::message::Debug);
70  addStreamToMsgLevel(we_logstream, slic::message::Warning);
71  addStreamToMsgLevel(we_logstream, slic::message::Error);
72 
73  // Set SLIC abort functionality
74  // NOTE: Do not set a collective abort function via `slic::setAbortFunction`.
75  // This can cause runs to hang. SLIC flushs locally on the node that fails,
76  // so that the error message is not lost.
77  slic::setAbortOnError(true);
78  slic::setAbortOnWarning(false);
79 
80  std::string msg = axom::fmt::format("Logger activated: '{0}'", loggerName);
81  SLIC_INFO_ROOT(msg);
82  serac::logger::flush();
83 
84  return true;
85 }
86 
87 void finalize() { axom::slic::finalize(); }
88 
89 void flush() { axom::slic::flushStreams(); }
90 
91 } // namespace serac::logger
A function intended to be used as part of a driver to initialize common libraries.
This file contains the all the necessary functions and macros required for logging as well as a helpe...
std::pair< int, int > initialize(int argc, char *argv[], MPI_Comm comm)
Initializes MPI, signal handling, and logging.
Definition: initialize.cpp:40
std::pair< int, int > getMPIInfo(MPI_Comm comm)
Returns the number of processes and rank for an MPI communicator.
Definition: initialize.cpp:26
Helper functions for exiting Serac cleanly.