Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
logger.cpp
1 // Copyright (c) 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 
9 #include <iostream>
10 #include <string>
11 
12 #include "mpi.h"
13 
15 
16 namespace serac::logger {
17 
18 bool initialize(MPI_Comm comm)
19 {
20  namespace slic = axom::slic;
21 
22  if (!slic::isInitialized()) {
23  slic::initialize();
24  }
25 
26  auto [num_ranks, rank] = getMPIInfo(comm);
27 
28  // Mark rank 0 as the root for message filtering macros
29  slic::setIsRoot(rank == 0);
30 
31  std::string loggerName = num_ranks > 1 ? "serac_parallel_logger" : "serac_serial_logger";
32  slic::createLogger(loggerName);
33  slic::activateLogger(loggerName);
34  if (!slic::activateLogger(loggerName)) {
35  // Can't log through SLIC since it just failed to activate
36  std::cerr << "Error: Failed to activate logger: " << loggerName << std::endl;
37  return false;
38  }
39 
40  // Console streams, std::cout for info/debug, std::cerr for warnings/errors
41  slic::LogStream* i_logstream = nullptr; // info
42  slic::LogStream* d_logstream = nullptr; // debug
43  slic::LogStream* we_logstream = nullptr; // warnings and errors
44 
45  // Stream formatting strings
46  std::string i_format_string = "<MESSAGE>\n";
47  std::string d_format_string = "[<LEVEL>]: <MESSAGE>\n";
48  std::string we_format_string = "[<LEVEL> (<FILE>:<LINE>)]\n<MESSAGE>\n\n";
49 
50  // Only create a parallel logger when there is more than one rank
51  if (num_ranks > 1) {
52  // Add rank to format strings if parallel
53  // Note: i_format_string's extra space is on purpose due to no space on above string
54  i_format_string = "[<RANK>] " + i_format_string;
55  d_format_string = "[<RANK>]" + d_format_string;
56  we_format_string = "[<RANK>]" + we_format_string;
57 
58  const int RLIMIT = 8;
59 
60  i_logstream = new slic::LumberjackStream(&std::cout, comm, RLIMIT, i_format_string);
61  d_logstream = new slic::LumberjackStream(&std::cout, comm, RLIMIT, d_format_string);
62  we_logstream = new slic::LumberjackStream(&std::cerr, comm, RLIMIT, we_format_string);
63  } else {
64  i_logstream = new slic::GenericOutputStream(&std::cout, i_format_string);
65  d_logstream = new slic::GenericOutputStream(&std::cout, d_format_string);
66  we_logstream = new slic::GenericOutputStream(&std::cerr, we_format_string);
67  }
68 
69  slic::setLoggingMsgLevel(slic::message::Debug);
70 
71  // Add message levels to streams
72  addStreamToMsgLevel(i_logstream, slic::message::Info);
73  addStreamToMsgLevel(d_logstream, slic::message::Debug);
74  addStreamToMsgLevel(we_logstream, slic::message::Warning);
75  addStreamToMsgLevel(we_logstream, slic::message::Error);
76 
77  // Set SLIC abort functionality
78  // NOTE: Do not set a collective abort function via `slic::setAbortFunction`.
79  // This can cause runs to hang. SLIC flushs locally on the node that fails,
80  // so that the error message is not lost.
81  slic::setAbortOnError(true);
82  slic::setAbortOnWarning(false);
83 
84  std::string msg = axom::fmt::format("Logger activated: '{0}'", loggerName);
85  SLIC_INFO_ROOT(msg);
86  serac::logger::flush();
87 
88  return true;
89 }
90 
91 void finalize() { axom::slic::finalize(); }
92 
93 void flush() { axom::slic::flushStreams(); }
94 
95 } // namespace serac::logger
This file contains the interface used for retrieving information about how the driver is configured.
This file contains the all the necessary functions and macros required for logging as well as a helpe...
axom::inlet::Inlet initialize(axom::sidre::DataStore &datastore, const std::string &input_file_path, const Language language, const std::string &sidre_path)
Initializes Inlet with the given datastore and input file.
Definition: input.cpp:22
std::pair< int, int > getMPIInfo(MPI_Comm comm)
Get MPI Info.
Definition: about.cpp:229