Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -321,7 +321,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,
"The error message was not containing the expected sequence.\n" <<
"The error message was not containing the expected sequence.\n" <<
Expand All @@ -347,7 +347,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
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ TEST( testGroupPath, testGlobalPaths )
"The children of Mesh are: { mesh1 }";
// checks if the exception contains the expected message
std::ostringstream stream;
geos::ErrorLogger::formatMsgForLog( ErrorLogger::global().getCurrentExceptionMsg(), stream );
geos::ErrorLogger::formatMsgForLog( ErrorLogger::global().getCurrentExceptionMsg(), stream, false );
GEOS_ERROR_IF_EQ_MSG( string( e.what() ).find( expectedMsg ), string::npos,
"The error message was not containing the expected sequence.\n" <<
" Error message :\n" << e.what() <<
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