Commit d55c9406 authored by Lukas Riedel's avatar Lukas Riedel

Use loggers for displaying fatal errors

* Improve logger handling and formatting
* Add 'log_base' variable for retrieving base logger
parent 27d9b5bb
......@@ -14,7 +14,7 @@ namespace Dune {
namespace Dorie {
/// The name for retrieving the basic/common logger
inline const std::string logger_base = "base";
inline const std::string log_base = "base";
/// Wrapper around the function spdlog::get which throws exceptions
/** \param name
......@@ -30,6 +30,28 @@ inline std::shared_ptr<spdlog::logger> get_logger (const std::string name)
return logger;
}
/// Restrict this function to the current scope
namespace
{
/// Create a logger or retrieve it if it already exists
/** \param name The name of the logger (also used for lookup)
*/
std::shared_ptr<spdlog::logger> create_or_get (const std::string name)
{
auto logger = spdlog::get(name);
if (not logger) {
logger = spdlog::stdout_color_mt(name);
}
else {
logger->warn("Skipping creation of logger '{}' because "
"it already exists.", name);
}
return logger;
}
}
/// Create a logger with a certain name and log level.
/** If created in parallel, reduce log level for loggers that are not
* on the primary process (rank 0). Sets new logging levels if the
......@@ -48,14 +70,7 @@ inline std::shared_ptr<spdlog::logger> create_logger (
)
{
// create the logger if it does not already exist
auto logger = spdlog::get(name);
if (not logger) {
logger = spdlog::stdout_color_mt(name);
}
else {
logger->warn("Skipping creation of logger {} because "
"it already exists.", name);
}
auto logger = create_or_get(name);
// Set to secondary level if logger runs on secondary process
if (helper.rank() == 0) {
......@@ -67,7 +82,7 @@ inline std::shared_ptr<spdlog::logger> create_logger (
// If run in parallel, add process ID to pattern
if (helper.size() > 1) {
// "[HH:MM:SS.mmm level] [Proc ID] [logger] <message>"
// "[HH:MM:SS.mmm level] (Proc ID) [logger] <message>"
logger->set_pattern("%^[%T.%e %L]%$ (%P) [%n] %v");
}
else {
......@@ -81,7 +96,7 @@ inline std::shared_ptr<spdlog::logger> create_logger (
/** If created in parallel, reduce log level for loggers that are not
* on the primary process (rank 0). Sets new logging levels if the
* logger(s) already exist. The logger automatically receives the name
* Dune::Dorie::logger_base and can be retrieved with its value.
* Dune::Dorie::log_base and can be retrieved with its value.
* \param helper The Dune MPIHelper
* \param level The log level of the (primary) logger.
* \param level_par The log level of the secondary loggers, if the
......@@ -89,12 +104,12 @@ inline std::shared_ptr<spdlog::logger> create_logger (
*/
inline std::shared_ptr<spdlog::logger> create_base_logger (
const Dune::MPIHelper& helper,
const spdlog::level::level_enum level = spdlog::level::info,
const spdlog::level::level_enum level = spdlog::level::warn,
const spdlog::level::level_enum level_par = spdlog::level::err
)
{
// retrieve the usual logger
auto logger = create_logger(logger_base,
auto logger = create_logger(log_base,
helper,
level,
level_par);
......@@ -102,7 +117,7 @@ inline std::shared_ptr<spdlog::logger> create_base_logger (
// Set different pattern without logger name
// If run in parallel, add process ID to pattern
if (helper.size() > 1) {
// "[HH:MM:SS.mmm level] [Proc ID] <message>"
// "[HH:MM:SS.mmm level] (Proc ID) <message>"
logger->set_pattern("%^[%T.%e %L]%$ (%P) %v");
}
else {
......@@ -113,6 +128,26 @@ inline std::shared_ptr<spdlog::logger> create_base_logger (
return logger;
}
/// Create the basic DORiE logger with a certain log level and fixed name.
/** The logger automatically receives the name Dune::Dorie::log_base
* and can be retrieved with its value. This functions creates copies of the
* logger on all processes and is intended to be used for (fatal) error
* messages upon stack unwinding.
* \param level The log level of the logger.
*/
inline std::shared_ptr<spdlog::logger> create_base_logger (
const spdlog::level::level_enum level = spdlog::level::warn
)
{
// create the logger if it does not already exist
auto logger = create_or_get(log_base);
// "[HH:MM:SS.mmm level] <message>"
logger->set_pattern("%^[%T.%e %L]%$ %v");
return logger;
}
} // namespace Dorie
} // namespace Dune
......
......@@ -7,6 +7,7 @@
#include <string>
#include <iostream>
#include <cstdio>
#include <exception>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
......@@ -79,12 +80,13 @@ int main(int argc, char** argv)
//Initialize Mpi
Dune::MPIHelper& helper = Dune::MPIHelper::instance(argc, argv);
// Initialize global logger
const auto logger = Dune::Dorie::create_base_logger(helper);
logger->info("Starting DORiE");
// Initialize global log
const auto log = Dune::Dorie::create_base_logger(helper,
spdlog::level::info);
log->info("Starting DORiE");
if (helper.size() > 1) {
logger->debug("Running in parallel on {} nodes",
log->debug("Running in parallel on {} nodes",
helper.size());
}
......@@ -94,13 +96,15 @@ int main(int argc, char** argv)
const std::string inifilename = argv[1];
// Read ini file
logger->info("Reading parameter file '{}'", inifilename);
log->info("Reading parameter file: {}", inifilename);
Dune::ParameterTree inifile;
Dune::ParameterTreeParser ptreeparser;
ptreeparser.readINITree(inifilename,inifile);
const auto log_level = inifile.get<std::string>("output.logLevel");
logger->set_level(spdlog::level::from_str(log_level));
if (helper.rank() == 1) {
log->set_level(spdlog::level::from_str(log_level));
}
// Allow for a debugger as gdb or lldb to hook into the process, even if run in parallel
// (by manually setting the variable i to a nonzero value)
......@@ -108,15 +112,15 @@ int main(int argc, char** argv)
if (debugMode)
{
// cache log level
const auto log_lvl = logger->level();
logger->set_level(spdlog::level::info);
const auto log_lvl = log->level();
log->set_level(spdlog::level::info);
if (helper.rank() == 0) {
logger->warn("Application halted due to debug mode");
log->warn("Application halted due to debug mode");
}
logger->warn("Attach a debugger and "
log->warn("Attach a debugger and "
"set variable i to a value != 0");
logger->flush();
log->flush();
// actual sleeping
int i = 0;
......@@ -124,8 +128,8 @@ int main(int argc, char** argv)
sleep(5);
}
logger->info("Commencing ...");
logger->set_level(log_lvl);
log->info("Commencing ...");
log->set_level(log_lvl);
}
// setup richards configuration
......@@ -134,7 +138,6 @@ int main(int argc, char** argv)
// Read necessary variables
const std::string gtype = inifile.get<std::string>("grid.gridType");
const int dim = inifile.get<int>("grid.dimensions");
const int verbose = inifile.get<int>("output.verbose");
const std::string adapt_policy_str = inifile.get<std::string>("adaptivity.policy");
const int FEorder = richards_config.get<int>("numerics.FEorder");
const std::string outputPath = richards_config.get<std::string>("output.outputPath");
......@@ -149,7 +152,7 @@ int main(int argc, char** argv)
// Attempt to create output directory
logger->info("Creating output directory '{}'", outputPath);
log->info("Creating output directory: {}", outputPath);
mkdir(outputPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
int result = access(outputPath.c_str(), W_OK);
if (result != 0)
......@@ -326,18 +329,27 @@ int main(int argc, char** argv)
DUNE_THROW(Dune::NotImplemented,"Number of dimensions (grid.dimensions) not supported!");
}
logger->info("DORiE finished after {:.2e}s :)",
log->info("DORiE finished after {:.2e}s :)",
timer.elapsed());
return 0;
}
catch (Dune::Exception &e){
std::cerr << "Dune reported error: " << e << std::endl;
}
catch (Dune::Exception &e){
auto log = Dune::Dorie::create_base_logger();
log->error("DUNE reported error: {}", e.what());
log->critical("Aborting DORiE");
return 1;
}
catch (std::exception& e) {
auto log = Dune::Dorie::create_base_logger();
log->error("Exception thrown: {}", e.what());
log->critical("Aborting DORiE");
return 1;
}
catch (...){
std::cerr << "Unknown exception thrown!" << std::endl;
throw;
}
catch (...){
auto log = Dune::Dorie::create_base_logger();
log->error("Unknown error occurred");
log->critical("Aborting DORiE");
return 1;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment