Skip to content
58 changes: 51 additions & 7 deletions src/coreComponents/common/logger/ErrorHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include "ErrorHandling.hpp"
#include "LvArray/src/system.hpp"
#include "common/DataTypes.hpp"
#include "common/logger/Logger.hpp"
#include "common/format/StringUtilities.hpp"
Expand Down Expand Up @@ -45,6 +46,11 @@ ErrorLogger g_errorLogger{};
ErrorLogger & ErrorLogger::global()
{ return g_errorLogger; }

ErrorLogger::ErrorLogger()
{
setDiagnosticInfoLevel( DiagnosticInfoLevel::Basic );
}

std::string ErrorContext::attributeToString( ErrorContext::Attribute attribute )
{
switch( attribute )
Expand Down Expand Up @@ -277,7 +283,29 @@ void ErrorLogger::createFile()
}
}

std::string ErrorLogger::toString( MsgType const type )
void ErrorLogger::setDiagnosticInfoLevel( DiagnosticInfoLevel const level )
{
switch( level )
{
case DiagnosticInfoLevel::Basic:
m_msgTypeSourceInfoEnabled.fill( false );
break;
case DiagnosticInfoLevel::ErrorSources:
m_msgTypeSourceInfoEnabled.fill( true );
m_msgTypeSourceInfoEnabled[integer( MsgType::Warning )] = false;
break;
case DiagnosticInfoLevel::WarningSources:
m_msgTypeSourceInfoEnabled.fill( true );
break;
default:
// if option has a wrong value, we output every details for any messages
m_msgTypeSourceInfoEnabled.fill( true );
break;
}
}


std::string ErrorLogger::typeToString( MsgType const type )
{
switch( type )
{
Expand All @@ -289,12 +317,26 @@ std::string ErrorLogger::toString( MsgType const type )
}
}

void ErrorLogger::formatMsgForLog( DiagnosticMsg const & errMsg, std::ostream & os )
bool ErrorLogger::isSourceInfoEnabled( MsgType const type ) const
{
switch( type )
{
case MsgType::Error: return m_msgTypeSourceInfoEnabled[integer( MsgType::Error )];
case MsgType::Warning: return m_msgTypeSourceInfoEnabled[integer( MsgType::Warning )];
case MsgType::Exception: return m_msgTypeSourceInfoEnabled[integer( MsgType::Exception )];
case MsgType::ExternalError: return m_msgTypeSourceInfoEnabled[integer( MsgType::ExternalError )];
default: return m_msgTypeSourceInfoEnabled[integer( MsgType::Undefined )];
}
}

void ErrorLogger::formatMsgForLog( DiagnosticMsg const & errMsg,
std::ostream & os,
bool enableSourceInfo )
{
static constexpr string_view PREFIX = "***** ";
// --- HEADER ---
os << PREFIX << ErrorLogger::toString( errMsg.m_type ) << "\n";
if( !errMsg.m_file.empty())
os << PREFIX << typeToString( errMsg.m_type ) << "\n";
if( enableSourceInfo && !errMsg.m_file.empty() )
{
os << PREFIX<< "LOCATION: " << errMsg.m_file;
if( errMsg.m_line > 0 )
Expand Down Expand Up @@ -332,7 +374,7 @@ void ErrorLogger::formatMsgForLog( DiagnosticMsg const & errMsg, std::ostream &
}
}
// --- STACKTRACE ---
if( !errMsg.m_sourceCallStack.empty() )
if( enableSourceInfo && !errMsg.m_sourceCallStack.empty() )
{
os << "\n***** StackTrace of "<< errMsg.m_sourceCallStack.size() << " frames\n";
for( size_t i = 0; i < errMsg.m_sourceCallStack.size(); i++ )
Expand All @@ -353,7 +395,9 @@ void ErrorLogger::formatMsgForLog( DiagnosticMsg const & errMsg, std::ostream &
void ErrorLogger::writeToLogStream( DiagnosticMsg & errMsg )
{
std::lock_guard< std::mutex > guard( m_errorHandlerAsciiMutex );
formatMsgForLog( errMsg, m_stream );
formatMsgForLog( errMsg,
m_stream,
isSourceInfoEnabled( errMsg.m_type ) );
m_stream.flush();
}

Expand All @@ -364,7 +408,7 @@ void ErrorLogger::writeToYamlStream( DiagnosticMsg & errMsg )
if( yamlFile.is_open() )
{
// General errors info (type, rank on which the error occured)
yamlFile << g_level1Start << "type: " << ErrorLogger::toString( errMsg.m_type ) << "\n";
yamlFile << g_level1Start << "type: " << typeToString( errMsg.m_type ) << "\n";
yamlFile << g_level1Next << "rank: " << stringutilities::join( errMsg.m_ranksInfo, "," );
yamlFile << "\n";

Expand Down
45 changes: 41 additions & 4 deletions src/coreComponents/common/logger/ErrorHandling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "common/DataTypes.hpp"
#include "common/format/Format.hpp"
#include "common/format/StringUtilities.hpp"

#include <mutex>

namespace geos
Expand Down Expand Up @@ -111,13 +112,28 @@ struct ErrorContext
* @enum MsgType
* Enum listing the different types of possible diagnostics
*/
enum class MsgType
enum class MsgType : integer
{
Undefined,
Error,
ExternalError,
Warning,
Exception,
Undefined
Count // internal use, keep at last
};

/**
* @enum DiagnosticInfoLevel
* Enum listing the different types of possible diagnostic information levels
*/
enum class DiagnosticInfoLevel : integer
{
/// basic information (default)
Basic = 0,
/// errors source-code information
ErrorSources= 1,
/// warnings & errors source-code information
WarningSources = 2,
};

/**
Expand Down Expand Up @@ -295,6 +311,8 @@ class ErrorLogger
*/
GEOS_HOST static ErrorLogger & global();

ErrorLogger();

/**
* @brief Create the YAML file or overwrite the contents if a YAML file of the same name already exists
* And write its header when the command line option is enabled
Expand Down Expand Up @@ -322,6 +340,14 @@ class ErrorLogger
void setOutputFilename( std::string_view filename )
{ m_filename = filename; }

/**
* @brief Set the diagnostic messages information level. The higher, the more verbose and
* developper-oriented the messages will be.
* @param level the desired information level. If level is not an DiagnosticInfoLevel enum label,
* the behaviour of DiagnosticInfoLevel::Basic.
*/
void setDiagnosticInfoLevel( DiagnosticInfoLevel level );

/**
* @return The file name of the output error file
*/
Expand All @@ -333,7 +359,13 @@ class ErrorLogger
* @param type the message type label
* @return the string representation of the message type
*/
static std::string toString( MsgType type );
static std::string typeToString( MsgType type );

/**
* @param type the message type label
* @return true if the message type source information output is enabled
*/
bool isSourceInfoEnabled( MsgType type ) const;

/**
* @return Return the const general log stream
Expand Down Expand Up @@ -384,8 +416,11 @@ class ErrorLogger
* @brief Format all information in ErrorMsg and write it to the specified output stream
* @param errMsg The struct containing the error/warning object
* @param os The output stream
* @param enableSourceInfo if true, information on source code is included in the message
*/
static void formatMsgForLog( DiagnosticMsg const & errMsg, std::ostream & os );
static void formatMsgForLog( DiagnosticMsg const & errMsg,
std::ostream & os,
bool enableSourceInfo );

/**
* @brief Write the ErrorMsg into the log stream output stream
Expand All @@ -407,6 +442,8 @@ class ErrorLogger
std::mutex m_errorHandlerAsciiMutex;
/// Avoid concurrent access between threads for yaml outputs
std::mutex m_errorHandlerYamlMutex;
/// Indicated if the source file information output is enabled for a given message type
stdArray< bool, size_t( MsgType::Count ) > m_msgTypeSourceInfoEnabled;

/**
* @brief Write all the information retrieved about the error/warning message into the YAML stream
Expand Down
4 changes: 3 additions & 1 deletion src/coreComponents/common/logger/GeosExceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ void Exception::prepareWhat( DiagnosticMsg & msg ) noexcept
m_formattingOSS.str( "" );
m_formattingOSS.clear();

ErrorLogger::formatMsgForLog( msg, m_formattingOSS );
ErrorLogger::formatMsgForLog( msg,
m_formattingOSS,
ErrorLogger::global().isSourceInfoEnabled( msg.m_type ) );
m_cachedWhat = m_formattingOSS.bad() ? "Exception formatting error!" : m_formattingOSS.str();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ TEST( ErrorHandling, testLogFileExceptionOutput )
additionalContext.toString(),
testErrorLogger.getCurrentExceptionMsg().m_sourceCallStack );
std::ostringstream oss;
ErrorLogger::formatMsgForLog( testErrorLogger.getCurrentExceptionMsg(), oss );
ErrorLogger::formatMsgForLog( testErrorLogger.getCurrentExceptionMsg(), oss, true );
GEOS_ERROR_IF_EQ_MSG( oss.str().find( streamExpected ), string::npos,
GEOS_FMT( "The error message was not containing the expected sequence.\n"
"The error message was not containing the expected sequence.\n"
Expand Down Expand Up @@ -351,7 +351,7 @@ TEST( ErrorHandling, testStdException )
.addCallStackInfo( LvArray::system::stackTrace( true ) );

std::ostringstream oss;
ErrorLogger::formatMsgForLog( testErrorLogger.getCurrentExceptionMsg(), oss );
ErrorLogger::formatMsgForLog( testErrorLogger.getCurrentExceptionMsg(), oss, true );
string const streamExpected = GEOS_FMT(
"***** Exception\n"
"***** Rank 0\n"
Expand Down
12 changes: 12 additions & 0 deletions src/coreComponents/mainInterface/initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

#include "initialization.hpp"
#include "common/logger/ErrorHandling.hpp"
#include "version.hpp"

#include "common/DataTypes.hpp"
Expand Down Expand Up @@ -97,6 +98,7 @@ std::unique_ptr< CommandLineOptions > parseCommandLineOptions( int argc, char *
ZPAR,
SCHEMA,
VALIDATE_INPUT,
DIAGNOSTIC_INFO_LEVEL,
NONBLOCKING_MPI,
SUPPRESS_PINNED,
PROBLEMNAME,
Expand All @@ -121,6 +123,10 @@ std::unique_ptr< CommandLineOptions > parseCommandLineOptions( int argc, char *
{ ZPAR, 0, "z", "zpartitions", Arg::numeric, "\t-z, --z-partitions, \t Number of partitions in the z-direction" },
{ SCHEMA, 0, "s", "schema", Arg::nonEmpty, "\t-s, --schema, \t Name of the output schema" },
{ VALIDATE_INPUT, 0, "v", "validate-input", Arg::None, "\t-v, --validate-input, \t Only do the loading phase, and not actual simulation. Useful to validate 'input'." },
{ DIAGNOSTIC_INFO_LEVEL, 0, "d", "diagnostic-info-level", Arg::numeric, "\t-d, --diagnostic-info-level, \t Diagnostic message information level:\n"
"\t \t 0 = basic information (default),\n"
"\t \t 1 = errors source-code information,\n"
"\t \t 2 = warnings & errors source-code information." },
{ NONBLOCKING_MPI, 0, "b", "use-nonblocking", Arg::None, "\t-b, --use-nonblocking, \t Use non-blocking MPI communication" },
{ PROBLEMNAME, 0, "n", "name", Arg::nonEmpty, "\t-n, --name, \t Name of the problem, used for output" },
{ SUPPRESS_PINNED, 0, "s", "suppress-pinned", Arg::None, "\t-s, --suppress-pinned, \t Suppress usage of pinned memory for MPI communication buffers" },
Expand Down Expand Up @@ -222,6 +228,12 @@ std::unique_ptr< CommandLineOptions > parseCommandLineOptions( int argc, char *
commandLineOptions->onlyValidateInput = true;
}
break;
case DIAGNOSTIC_INFO_LEVEL:
{
DiagnosticInfoLevel infoLevel = DiagnosticInfoLevel( std::stoi( opt.arg ) );
ErrorLogger::global().setDiagnosticInfoLevel( infoLevel );
}
break;
case PROBLEMNAME:
{
commandLineOptions->problemName = opt.arg;
Expand Down
Loading