Support tagged messages.
This changes the design of the LogBackend class and its subclasses, now the main virtual method is addTaggedMessage(). The former virtual method addMessage() is now a regular non-virtual method forwarding to addTaggedMessage(). You can configure message limiting based on tags by passing a MessageLimiter to the configureMessageLimiter() method, which will then be used by the includeMessage() method. That method now takes an additional tag argument. The most user-visible part of this is that there are new overloads of the static methods OpmLog::warning(), OpmLog::error() etc, that take message tags. To tie things together the OpmLog and Logger classes have also gotten new addTaggedMessage() methods, but they should mostly be used through the convenience methods such as OpmLog::warning().
This commit is contained in:
parent
9c84967734
commit
d2564ff838
@ -48,8 +48,8 @@ size_t CounterLog::numMessages(int64_t messageType) const {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CounterLog::addMessage(int64_t messageType , const std::string& ) {
|
void CounterLog::addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& ) {
|
||||||
if (includeMessage( messageType ))
|
if (includeMessage( messageType, messageTag ))
|
||||||
m_count[messageType]++;
|
m_count[messageType]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,8 @@ public:
|
|||||||
size_t numMessages(int64_t messageType) const;
|
size_t numMessages(int64_t messageType) const;
|
||||||
|
|
||||||
|
|
||||||
void addMessage(int64_t messageFlag ,
|
void addTaggedMessage(int64_t messageFlag,
|
||||||
|
const std::string& messageTag,
|
||||||
const std::string& message);
|
const std::string& message);
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
|
|
||||||
void EclipsePRTLog::addMessage(int64_t messageType, const std::string& message)
|
void EclipsePRTLog::addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& message)
|
||||||
{
|
{
|
||||||
StreamLog::addMessage(messageType, message);
|
StreamLog::addTaggedMessage(messageType, messageTag, message);
|
||||||
m_count[messageType]++;
|
m_count[messageType]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ namespace Opm {
|
|||||||
std::string("\nBugs " + std::to_string(numMessages(Log::MessageType::Bug))) +
|
std::string("\nBugs " + std::to_string(numMessages(Log::MessageType::Bug))) +
|
||||||
std::string("\nDebug " + std::to_string(numMessages(Log::MessageType::Debug))) +
|
std::string("\nDebug " + std::to_string(numMessages(Log::MessageType::Debug))) +
|
||||||
std::string("\nProblems " + std::to_string(numMessages(Log::MessageType::Problem))) +"\n";
|
std::string("\nProblems " + std::to_string(numMessages(Log::MessageType::Problem))) +"\n";
|
||||||
addMessage(Log::MessageType::Info, summary_msg);
|
StreamLog::addTaggedMessage(Log::MessageType::Info, "", summary_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class EclipsePRTLog : public StreamLog {
|
|||||||
public:
|
public:
|
||||||
using StreamLog::StreamLog;
|
using StreamLog::StreamLog;
|
||||||
|
|
||||||
void addMessage(int64_t messageType, const std::string& message);
|
void addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& message);
|
||||||
|
|
||||||
size_t numMessages(int64_t messageType) const;
|
size_t numMessages(int64_t messageType) const;
|
||||||
|
|
||||||
|
@ -36,14 +36,40 @@ namespace Opm {
|
|||||||
m_formatter = formatter;
|
m_formatter = formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogBackend::configureMessageLimiter(std::shared_ptr<MessageLimiter> limiter)
|
||||||
|
{
|
||||||
|
m_limiter = limiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogBackend::addMessage(int64_t messageFlag, const std::string& message)
|
||||||
|
{
|
||||||
|
// Forward the call to the tagged version.
|
||||||
|
addTaggedMessage(messageFlag, "", message);
|
||||||
|
}
|
||||||
|
|
||||||
int64_t LogBackend::getMask() const
|
int64_t LogBackend::getMask() const
|
||||||
{
|
{
|
||||||
return m_mask;
|
return m_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogBackend::includeMessage(int64_t messageFlag)
|
bool LogBackend::includeMessage(int64_t messageFlag, const std::string& messageTag)
|
||||||
{
|
{
|
||||||
return ((messageFlag & m_mask) == messageFlag) && (messageFlag > 0);
|
// Check mask.
|
||||||
|
const bool included = ((messageFlag & m_mask) == messageFlag) && (messageFlag > 0);
|
||||||
|
if (!included) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the message limiter (if any).
|
||||||
|
MessageLimiter::Response res = m_limiter
|
||||||
|
? m_limiter->encounteredMessage(messageTag)
|
||||||
|
: MessageLimiter::Response::PrintMessage;
|
||||||
|
if (res == MessageLimiter::Response::JustOverLimit) {
|
||||||
|
// Special case: add a message to this backend about limit being reached.
|
||||||
|
std::string msg = "Message limit reached for message tag: " + messageTag;
|
||||||
|
addTaggedMessage(messageFlag, "", msg);
|
||||||
|
}
|
||||||
|
return res == MessageLimiter::Response::PrintMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LogBackend::decorateMessage(int64_t messageFlag, const std::string& message)
|
std::string LogBackend::decorateMessage(int64_t messageFlag, const std::string& message)
|
||||||
|
@ -43,11 +43,22 @@ namespace Opm
|
|||||||
/// Configure how decorateMessage() will modify message strings.
|
/// Configure how decorateMessage() will modify message strings.
|
||||||
void configureDecoration(std::shared_ptr<MessageFormatterInterface> formatter);
|
void configureDecoration(std::shared_ptr<MessageFormatterInterface> formatter);
|
||||||
|
|
||||||
|
/// Configure how message tags will be used to limit messages.
|
||||||
|
void configureMessageLimiter(std::shared_ptr<MessageLimiter> limiter);
|
||||||
|
|
||||||
/// Add a message to the backend.
|
/// Add a message to the backend.
|
||||||
///
|
///
|
||||||
/// Typically a subclass may filter, change, and output
|
/// Typically a subclass may filter, change, and output
|
||||||
/// messages based on configuration and the messageFlag.
|
/// messages based on configuration and the messageFlag.
|
||||||
virtual void addMessage(int64_t messageFlag, const std::string& message) = 0;
|
void addMessage(int64_t messageFlag, const std::string& message);
|
||||||
|
|
||||||
|
/// Add a tagged message to the backend.
|
||||||
|
///
|
||||||
|
/// Typically a subclass may filter, change, and output
|
||||||
|
/// messages based on configuration and the messageFlag.
|
||||||
|
virtual void addTaggedMessage(int64_t messageFlag,
|
||||||
|
const std::string& messageTag,
|
||||||
|
const std::string& message) = 0;
|
||||||
|
|
||||||
/// The message mask types are specified in the
|
/// The message mask types are specified in the
|
||||||
/// Opm::Log::MessageType namespace, in file LogUtils.hpp.
|
/// Opm::Log::MessageType namespace, in file LogUtils.hpp.
|
||||||
@ -55,7 +66,7 @@ namespace Opm
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Return true if all bits of messageFlag are also set in our mask.
|
/// Return true if all bits of messageFlag are also set in our mask.
|
||||||
bool includeMessage(int64_t messageFlag);
|
bool includeMessage(int64_t messageFlag, const std::string& messageTag);
|
||||||
|
|
||||||
/// Return decorated version of message depending on configureDecoration() arguments.
|
/// Return decorated version of message depending on configureDecoration() arguments.
|
||||||
std::string decorateMessage(int64_t messageFlag, const std::string& message);
|
std::string decorateMessage(int64_t messageFlag, const std::string& message);
|
||||||
@ -63,6 +74,7 @@ namespace Opm
|
|||||||
private:
|
private:
|
||||||
int64_t m_mask;
|
int64_t m_mask;
|
||||||
std::shared_ptr<MessageFormatterInterface> m_formatter;
|
std::shared_ptr<MessageFormatterInterface> m_formatter;
|
||||||
|
std::shared_ptr<MessageLimiter> m_limiter;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LogBackend
|
} // namespace LogBackend
|
||||||
|
@ -38,6 +38,18 @@ namespace Opm {
|
|||||||
addMessageType( Log::MessageType::Bug , "bug");
|
addMessageType( Log::MessageType::Bug , "bug");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logger::addTaggedMessage(int64_t messageType, const std::string& tag, const std::string& message) const {
|
||||||
|
if ((m_enabledTypes & messageType) == 0)
|
||||||
|
throw std::invalid_argument("Tried to issue message with unrecognized message ID");
|
||||||
|
|
||||||
|
if (m_globalMask & messageType) {
|
||||||
|
for (auto iter = m_backends.begin(); iter != m_backends.end(); ++iter) {
|
||||||
|
std::shared_ptr<LogBackend> backend = (*iter).second;
|
||||||
|
backend->addTaggedMessage( messageType, tag, message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Logger::addMessage(int64_t messageType , const std::string& message) const {
|
void Logger::addMessage(int64_t messageType , const std::string& message) const {
|
||||||
if ((m_enabledTypes & messageType) == 0)
|
if ((m_enabledTypes & messageType) == 0)
|
||||||
throw std::invalid_argument("Tried to issue message with unrecognized message ID");
|
throw std::invalid_argument("Tried to issue message with unrecognized message ID");
|
||||||
|
@ -35,6 +35,7 @@ class Logger {
|
|||||||
public:
|
public:
|
||||||
Logger();
|
Logger();
|
||||||
void addMessage(int64_t messageType , const std::string& message) const;
|
void addMessage(int64_t messageType , const std::string& message) const;
|
||||||
|
void addTaggedMessage(int64_t messageType, const std::string& tag, const std::string& message) const;
|
||||||
|
|
||||||
static bool enabledDefaultMessageType( int64_t messageType);
|
static bool enabledDefaultMessageType( int64_t messageType);
|
||||||
bool enabledMessageType( int64_t messageType) const;
|
bool enabledMessageType( int64_t messageType) const;
|
||||||
|
@ -37,6 +37,12 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::addTaggedMessage(int64_t messageFlag, const std::string& tag, const std::string& message) {
|
||||||
|
if (m_logger)
|
||||||
|
m_logger->addTaggedMessage( messageFlag, tag, message );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpmLog::info(const std::string& message)
|
void OpmLog::info(const std::string& message)
|
||||||
{
|
{
|
||||||
addMessage(Log::MessageType::Info, message);
|
addMessage(Log::MessageType::Info, message);
|
||||||
@ -73,6 +79,45 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::info(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Info, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::warning(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Warning, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::problem(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Problem, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::error(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Error, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::bug(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Bug, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpmLog::debug(const std::string& tag, const std::string& message)
|
||||||
|
{
|
||||||
|
addTaggedMessage(Log::MessageType::Debug, tag, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool OpmLog::enabledMessageType( int64_t messageType ) {
|
bool OpmLog::enabledMessageType( int64_t messageType ) {
|
||||||
if (m_logger)
|
if (m_logger)
|
||||||
return m_logger->enabledMessageType( messageType );
|
return m_logger->enabledMessageType( messageType );
|
||||||
|
@ -40,6 +40,7 @@ class OpmLog {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void addMessage(int64_t messageFlag , const std::string& message);
|
static void addMessage(int64_t messageFlag , const std::string& message);
|
||||||
|
static void addTaggedMessage(int64_t messageFlag, const std::string& tag, const std::string& message);
|
||||||
|
|
||||||
static void info(const std::string& message);
|
static void info(const std::string& message);
|
||||||
static void warning(const std::string& message);
|
static void warning(const std::string& message);
|
||||||
@ -47,6 +48,14 @@ public:
|
|||||||
static void problem(const std::string& message);
|
static void problem(const std::string& message);
|
||||||
static void bug(const std::string& message);
|
static void bug(const std::string& message);
|
||||||
static void debug(const std::string& message);
|
static void debug(const std::string& message);
|
||||||
|
|
||||||
|
static void info(const std::string& tag, const std::string& message);
|
||||||
|
static void warning(const std::string& tag, const std::string& message);
|
||||||
|
static void error(const std::string& tag, const std::string& message);
|
||||||
|
static void problem(const std::string& tag, const std::string& message);
|
||||||
|
static void bug(const std::string& tag, const std::string& message);
|
||||||
|
static void debug(const std::string& tag, const std::string& message);
|
||||||
|
|
||||||
static bool hasBackend( const std::string& backendName );
|
static bool hasBackend( const std::string& backendName );
|
||||||
static void addBackend(const std::string& name , std::shared_ptr<LogBackend> backend);
|
static void addBackend(const std::string& name , std::shared_ptr<LogBackend> backend);
|
||||||
static bool removeBackend(const std::string& name);
|
static bool removeBackend(const std::string& name);
|
||||||
|
@ -44,14 +44,14 @@ void StreamLog::close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamLog::addMessage(int64_t messageType , const std::string& message) {
|
void StreamLog::addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& message) {
|
||||||
if (includeMessage( messageType )) {
|
if (includeMessage( messageType, messageTag )) {
|
||||||
(*m_ostream) << decorateMessage(messageType, message) << std::endl;
|
(*m_ostream) << decorateMessage(messageType, message) << std::endl;
|
||||||
|
if (m_ofstream.is_open()) {
|
||||||
if (m_ofstream.is_open())
|
|
||||||
m_ofstream.flush();
|
m_ofstream.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StreamLog::~StreamLog() {
|
StreamLog::~StreamLog() {
|
||||||
|
@ -33,7 +33,7 @@ class StreamLog : public LogBackend {
|
|||||||
public:
|
public:
|
||||||
StreamLog(const std::string& logFile , int64_t messageMask);
|
StreamLog(const std::string& logFile , int64_t messageMask);
|
||||||
StreamLog(std::ostream& os , int64_t messageMask);
|
StreamLog(std::ostream& os , int64_t messageMask);
|
||||||
void addMessage(int64_t messageType , const std::string& message);
|
virtual void addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& message) override;
|
||||||
~StreamLog();
|
~StreamLog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,14 +41,14 @@ TimerLog::TimerLog(std::ostream& os) : StreamLog( os , StopTimer | StartTimer )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void TimerLog::addMessage(int64_t messageType , const std::string& msg ) {
|
void TimerLog::addTaggedMessage(int64_t messageType, const std::string& messageTag, const std::string& msg ) {
|
||||||
if (messageType == StopTimer) {
|
if (messageType == StopTimer) {
|
||||||
clock_t stop = clock();
|
clock_t stop = clock();
|
||||||
double secondsElapsed = 1.0 * (m_start - stop) / CLOCKS_PER_SEC ;
|
double secondsElapsed = 1.0 * (m_start - stop) / CLOCKS_PER_SEC ;
|
||||||
|
|
||||||
m_work.str("");
|
m_work.str("");
|
||||||
m_work << std::fixed << msg << ": " << secondsElapsed << " seconds ";
|
m_work << std::fixed << msg << ": " << secondsElapsed << " seconds ";
|
||||||
StreamLog::addMessage( messageType , m_work.str());
|
StreamLog::addTaggedMessage( messageType, messageTag, m_work.str());
|
||||||
} else {
|
} else {
|
||||||
if (messageType == StartTimer)
|
if (messageType == StartTimer)
|
||||||
m_start = clock();
|
m_start = clock();
|
||||||
|
@ -42,8 +42,9 @@ public:
|
|||||||
TimerLog(const std::string& logFile);
|
TimerLog(const std::string& logFile);
|
||||||
TimerLog(std::ostream& os);
|
TimerLog(std::ostream& os);
|
||||||
|
|
||||||
void addMessage(int64_t messageFlag ,
|
void addTaggedMessage(int64_t messageFlag,
|
||||||
const std::string& message);
|
const std::string& messageTag,
|
||||||
|
const std::string& message) override;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
~TimerLog() {};
|
~TimerLog() {};
|
||||||
|
@ -118,7 +118,7 @@ public:
|
|||||||
m_specialMessages = 0;
|
m_specialMessages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMessage(int64_t messageType , const std::string& /* message */) {
|
void addTaggedMessage(int64_t messageType , const std::string& /* messageTag */, const std::string& /* message */) {
|
||||||
if (messageType & Log::DefaultMessageTypes)
|
if (messageType & Log::DefaultMessageTypes)
|
||||||
m_defaultMessages +=1;
|
m_defaultMessages +=1;
|
||||||
else
|
else
|
||||||
@ -303,3 +303,59 @@ BOOST_AUTO_TEST_CASE(TestOpmLogWithColors)
|
|||||||
|
|
||||||
std::cout << log_stream.str() << std::endl;
|
std::cout << log_stream.str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(TestOpmLogWithLimits)
|
||||||
|
{
|
||||||
|
OpmLog::removeAllBackends();
|
||||||
|
|
||||||
|
std::ostringstream log_stream1;
|
||||||
|
std::ostringstream log_stream2;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::shared_ptr<StreamLog> streamLog1 = std::make_shared<StreamLog>(log_stream1, Log::DefaultMessageTypes);
|
||||||
|
std::shared_ptr<StreamLog> streamLog2 = std::make_shared<StreamLog>(log_stream2, Log::DefaultMessageTypes);
|
||||||
|
OpmLog::addBackend("STREAM1" , streamLog1);
|
||||||
|
OpmLog::addBackend("STREAM2" , streamLog2);
|
||||||
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM1"));
|
||||||
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM2"));
|
||||||
|
|
||||||
|
streamLog1->configureDecoration(std::make_shared<SimpleMessageFormatter>(false, true));
|
||||||
|
streamLog1->configureMessageLimiter(std::make_shared<MessageLimiter>(2));
|
||||||
|
streamLog2->configureDecoration(std::make_shared<SimpleMessageFormatter>(false, true));
|
||||||
|
streamLog2->configureMessageLimiter(std::make_shared<MessageLimiter>()); // no limit
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string tag = "ExampleTag";
|
||||||
|
OpmLog::warning(tag, "Warning");
|
||||||
|
OpmLog::error("Error");
|
||||||
|
OpmLog::info("Info");
|
||||||
|
OpmLog::bug("Bug");
|
||||||
|
OpmLog::warning(tag, "Warning");
|
||||||
|
OpmLog::warning(tag, "Warning");
|
||||||
|
OpmLog::warning(tag, "Warning");
|
||||||
|
|
||||||
|
const std::string expected1 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Message limit reached for message tag: " + tag) + "\n";
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(log_stream1.str(), expected1);
|
||||||
|
|
||||||
|
const std::string expected2 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
||||||
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n";
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(log_stream2.str(), expected2);
|
||||||
|
|
||||||
|
std::cout << log_stream1.str() << std::endl;
|
||||||
|
std::cout << log_stream2.str() << std::endl;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user