Logger: Independent logging level for ILogSink

This commit is contained in:
Pavel Kirienko 2014-03-25 21:45:12 +04:00
parent 379a19c1b8
commit 40a9194574
3 changed files with 52 additions and 14 deletions

View File

@ -19,7 +19,18 @@ namespace uavcan
class ILogSink
{
public:
typedef typename StorageType<typename protocol::debug::LogLevel::FieldTypes::value>::Type LogLevel;
virtual ~ILogSink() { }
/**
* Logger will not sink messages with level lower than returned by this method.
*/
virtual LogLevel getLogLevel() const = 0;
/**
* Logger will call this method for every log message with level not less than the current level of this sink.
*/
virtual void log(const protocol::debug::LogMessage& message) = 0;
};
@ -27,7 +38,7 @@ public:
class Logger
{
public:
typedef typename StorageType<typename protocol::debug::LogLevel::FieldTypes::value>::Type LogLevel;
typedef ILogSink::LogLevel LogLevel;
static const LogLevel LevelAboveAll = (protocol::debug::LogLevel::FieldTypes::value::BitLen << 1) - 1;
@ -39,6 +50,8 @@ private:
LogLevel level_;
ILogSink* external_sink_;
LogLevel getExternalSinkLevel() const;
public:
Logger(INode& node)
: logmsg_pub_(node)
@ -65,7 +78,7 @@ public:
template <typename... Args>
int log(LogLevel level, const char* source, const char* format, Args... args)
{
if (level >= level_)
if (level >= level_ || level >= getExternalSinkLevel())
{
msg_buf_.level.value = level;
msg_buf_.source = source;
@ -78,25 +91,25 @@ public:
}
template <typename... Args>
int logDebug(const char* source, const char* format, Args... args)
inline int logDebug(const char* source, const char* format, Args... args)
{
return log(protocol::debug::LogLevel::DEBUG, source, format, args...);
}
template <typename... Args>
int logInfo(const char* source, const char* format, Args... args)
inline int logInfo(const char* source, const char* format, Args... args)
{
return log(protocol::debug::LogLevel::INFO, source, format, args...);
}
template <typename... Args>
int logWarning(const char* source, const char* format, Args... args)
inline int logWarning(const char* source, const char* format, Args... args)
{
return log(protocol::debug::LogLevel::WARNING, source, format, args...);
}
template <typename... Args>
int logError(const char* source, const char* format, Args... args)
inline int logError(const char* source, const char* format, Args... args)
{
return log(protocol::debug::LogLevel::ERROR, source, format, args...);
}
@ -105,7 +118,7 @@ public:
int log(LogLevel level, const char* source, const char* text)
{
if (level >= level_)
if (level >= level_ || level >= getExternalSinkLevel())
{
msg_buf_.level.value = level;
msg_buf_.source = source;

View File

@ -2,6 +2,7 @@
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#include <cstdlib>
#include <uavcan/protocol/logger.hpp>
namespace uavcan
@ -9,18 +10,23 @@ namespace uavcan
const Logger::LogLevel Logger::LevelAboveAll;
Logger::LogLevel Logger::getExternalSinkLevel() const
{
return (external_sink_ == NULL) ? LevelAboveAll : external_sink_->getLogLevel();
}
int Logger::log(const protocol::debug::LogMessage& message)
{
int retval = 0;
if (message.level.value >= getExternalSinkLevel())
{
external_sink_->log(message);
}
if (message.level.value >= level_)
{
const int res = logmsg_pub_.broadcast(message);
if (external_sink_)
{
external_sink_->log(message);
}
return res;
retval = logmsg_pub_.broadcast(message);
}
return 0;
return retval;
}
}

View File

@ -10,6 +10,13 @@
struct LogSink : public uavcan::ILogSink
{
std::queue<uavcan::protocol::debug::LogMessage> msgs;
LogLevel level;
LogSink()
: level(uavcan::protocol::debug::LogLevel::ERROR)
{ }
LogLevel getLogLevel() const { return level; }
void log(const uavcan::protocol::debug::LogMessage& message)
{
@ -31,6 +38,11 @@ struct LogSink : public uavcan::ILogSink
bool popMatchByLevelAndText(int level, const std::string& source, const std::string& text)
{
if (msgs.empty())
{
std::cout << "LogSink is empty" << std::endl;
return false;
}
const uavcan::protocol::debug::LogMessage m = pop();
return
level == m.level.value &&
@ -65,7 +77,14 @@ TEST(Logger, Basic)
SubscriberWithCollector<uavcan::protocol::debug::LogMessage> log_sub(nodes.b);
ASSERT_LE(0, log_sub.start());
// Sink test
ASSERT_EQ(0, logger.logDebug("foo", "Debug (ignored due to low logging level)"));
ASSERT_TRUE(sink.msgs.empty());
sink.level = uavcan::protocol::debug::LogLevel::DEBUG;
ASSERT_EQ(0, logger.logDebug("foo", "Debug (sink only)"));
ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::DEBUG, "foo", "Debug (sink only)"));
ASSERT_LE(0, logger.logError("foo", "Error"));
nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(2));
ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::ERROR);