diff --git a/src/global.cpp b/src/global.cpp index 1e9c11ee..26dfcc09 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -7,6 +7,16 @@ #include #include +#if __has_include() + #include + namespace fs = std::filesystem; +#elif __has_include() + #include + namespace fs = std::experimental::filesystem; +#else + #error "Missing the header." +#endif + #include "idefix.hpp" #include "global.hpp" #include "profiler.hpp" @@ -26,6 +36,7 @@ bool warningsAreErrors{false}; IdefixOutStream cout; IdefixErrStream cerr; +std::string logFileDir; Profiler prof; LoopPattern defaultLoopPattern; @@ -103,11 +114,30 @@ void IdefixOutStream::init(int rank) { // disable the log file void IdefixOutStream::enableLogFile() { std::stringstream sslogFileName; - sslogFileName << "idefix." << idfx::prank << ".log"; + sslogFileName << idfx::logFileDir << "/./" << "idefix." << idfx::prank << ".log"; std::string logFileName(sslogFileName.str()); - this->my_fstream.open(logFileName.c_str()); + if(idfx::prank==0) { + if(!fs::is_directory(logFileDir)) { + try { + if(!fs::create_directories(logFileDir)) { + std::stringstream msg; + msg << "Cannot create directory " << logFileDir << std::endl; + IDEFIX_ERROR(msg); + } + } catch(std::exception &e) { + std::stringstream msg; + msg << "Cannot create directory " << logFileDir << std::endl; + msg << e.what(); + IDEFIX_ERROR(msg); + } + } + } +#ifdef WITH_MPI + MPI_Barrier(MPI_COMM_WORLD); +#endif + this->my_fstream.open(logFileName.c_str()); this->logFileEnabled = true; } diff --git a/src/global.hpp b/src/global.hpp index 47fca42e..78747f57 100644 --- a/src/global.hpp +++ b/src/global.hpp @@ -21,6 +21,7 @@ class Profiler; extern int prank; //< parallel rank extern int psize; +extern std::string logFileDir; //< logfileDir extern IdefixOutStream cout; //< custom cout for idefix extern IdefixErrStream cerr; //< custom cerr for idefix extern Profiler prof; //< profiler (for memory & performance usage) diff --git a/src/input.cpp b/src/input.cpp index 33641495..2e628f85 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -43,6 +43,8 @@ Input::Input(int argc, char* argv[] ) { bool haveBlock = false; std::stringstream msg; int nParameters = 0; // # of parameters in current block + // Log files are enabled by default + this->enableLogs = true; // Tell the system we want to catch the SIGUSR2 signals signal(SIGUSR2, signalHandler); @@ -108,12 +110,20 @@ Input::Input(int argc, char* argv[] ) { } } file.close(); + + if(this->enableLogs) { + if(CheckEntry("Output","log_dir")>=0) { + idfx::logFileDir = Get("Output", "log_dir", 0); + } else { + idfx::logFileDir = "./"; + } + idfx::cout.enableLogFile(); + } } // This routine parse command line options void Input::ParseCommandLine(int argc, char **argv) { std::stringstream msg; - bool enableLogs = true; for(int i = 1 ; i < argc ; i++) { // MPI decomposition argument if(std::string(argv[i]) == "-dec") { @@ -171,9 +181,9 @@ void Input::ParseCommandLine(int argc, char **argv) { this->forceInitRequested = true; } else if(std::string(argv[i]) == "-nowrite") { this->forceNoWrite = true; - enableLogs = false; + this->enableLogs = false; } else if(std::string(argv[i]) == "-nolog") { - enableLogs = false; + this->enableLogs = false; } else if(std::string(argv[i]) == "-profile") { idfx::prof.EnablePerformanceProfiling(); } else if(std::string(argv[i]) == "-Werror") { @@ -190,9 +200,6 @@ void Input::ParseCommandLine(int argc, char **argv) { IDEFIX_ERROR(msg); } } - if(enableLogs) { - idfx::cout.enableLogFile(); - } } diff --git a/src/input.hpp b/src/input.hpp index 18fcf260..72792059 100644 --- a/src/input.hpp +++ b/src/input.hpp @@ -25,6 +25,9 @@ class Input { Input (int, char ** ); void ShowConfig(); + // flag if logging is to be done + bool enableLogs; + // Accessor to input parameters // the parameters are always: BlockName, EntryName, ParameterNumber (starting from 0) // These specialised functions are deprecated. Use the template Get function.