Skip to content

Commit

Permalink
move RLogger out of Experimental / v7
Browse files Browse the repository at this point in the history
  • Loading branch information
jblomer committed Dec 18, 2024
1 parent 92fcfe0 commit 9131dfd
Show file tree
Hide file tree
Showing 34 changed files with 123 additions and 148 deletions.
3 changes: 2 additions & 1 deletion core/base/v7/src/RDirectory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

#include <ROOT/RLogger.hxx>

ROOT::Experimental::RLogChannel &ROOT::Experimental::IOLog() {
ROOT::RLogChannel &ROOT::Experimental::IOLog()
{
static RLogChannel sLog("ROOT.IO");
return sLog;
}
31 changes: 13 additions & 18 deletions core/foundation/inc/ROOT/RLogger.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
/// \ingroup Base ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2015-03-29
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
* Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
Expand All @@ -13,8 +11,8 @@
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT7_RLogger
#define ROOT7_RLogger
#ifndef ROOT_RLogger
#define ROOT_RLogger

#include <atomic>
#include <list>
Expand All @@ -25,7 +23,6 @@
#include <utility>

namespace ROOT {
namespace Experimental {

class RLogEntry;
class RLogManager;
Expand Down Expand Up @@ -317,7 +314,6 @@ inline ELogLevel RLogChannel::GetEffectiveVerbosity(const RLogManager &mgr) cons
return fVerbosity;
}

} // namespace Experimental
} // namespace ROOT

#if defined(_MSC_VER)
Expand All @@ -341,28 +337,27 @@ inline ELogLevel RLogChannel::GetEffectiveVerbosity(const RLogManager &mgr) cons
- Use `(condition) && RLogBuilder(...)` instead of `if (condition) RLogBuilder(...)`
to prevent "ambiguous else" in invocations such as `if (something) R__LOG_DEBUG()...`.
*/
#define R__LOG_TO_CHANNEL(SEVERITY, CHANNEL) \
((SEVERITY < ROOT::Experimental::ELogLevel::kInfo + 0) || \
ROOT::Experimental::Internal::GetChannelOrManager(CHANNEL).GetEffectiveVerbosity( \
ROOT::Experimental::RLogManager::Get()) >= SEVERITY) && \
ROOT::Experimental::Detail::RLogBuilder(SEVERITY, ROOT::Experimental::Internal::GetChannelOrManager(CHANNEL), \
__FILE__, __LINE__, R__LOG_PRETTY_FUNCTION)
#define R__LOG_TO_CHANNEL(SEVERITY, CHANNEL) \
((SEVERITY < ROOT::ELogLevel::kInfo + 0) || \
ROOT::Internal::GetChannelOrManager(CHANNEL).GetEffectiveVerbosity(ROOT::RLogManager::Get()) >= SEVERITY) && \
ROOT::Detail::RLogBuilder(SEVERITY, ROOT::Internal::GetChannelOrManager(CHANNEL), __FILE__, __LINE__, \
R__LOG_PRETTY_FUNCTION)

/// \name LogMacros
/// Macros to log diagnostics.
/// ~~~ {.cpp}
/// R__LOG_INFO(ROOT::Experimental::HistLog()) << "all we know is " << 42;
/// R__LOG_INFO(ROOT::HistLog()) << "all we know is " << 42;
///
/// RLogScopedVerbosity verbose(kDebug + 5);
/// const int decreasedInfoLevel = 5;
/// R__LOG_DEBUG(ROOT::WebGUILog(), decreasedInfoLevel) << "nitty-gritty details";
/// ~~~
///\{
#define R__LOG_FATAL(...) R__LOG_TO_CHANNEL(ROOT::Experimental::ELogLevel::kFatal, __VA_ARGS__)
#define R__LOG_ERROR(...) R__LOG_TO_CHANNEL(ROOT::Experimental::ELogLevel::kError, __VA_ARGS__)
#define R__LOG_WARNING(...) R__LOG_TO_CHANNEL(ROOT::Experimental::ELogLevel::kWarning, __VA_ARGS__)
#define R__LOG_INFO(...) R__LOG_TO_CHANNEL(ROOT::Experimental::ELogLevel::kInfo, __VA_ARGS__)
#define R__LOG_DEBUG(DEBUGLEVEL, ...) R__LOG_TO_CHANNEL(ROOT::Experimental::ELogLevel::kDebug + DEBUGLEVEL, __VA_ARGS__)
#define R__LOG_FATAL(...) R__LOG_TO_CHANNEL(ROOT::ELogLevel::kFatal, __VA_ARGS__)
#define R__LOG_ERROR(...) R__LOG_TO_CHANNEL(ROOT::ELogLevel::kError, __VA_ARGS__)
#define R__LOG_WARNING(...) R__LOG_TO_CHANNEL(ROOT::ELogLevel::kWarning, __VA_ARGS__)
#define R__LOG_INFO(...) R__LOG_TO_CHANNEL(ROOT::ELogLevel::kInfo, __VA_ARGS__)
#define R__LOG_DEBUG(DEBUGLEVEL, ...) R__LOG_TO_CHANNEL(ROOT::ELogLevel::kDebug + DEBUGLEVEL, __VA_ARGS__)
///\}

#endif
20 changes: 9 additions & 11 deletions core/foundation/src/RLogger.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,19 @@
#include <memory>
#include <vector>

using namespace ROOT::Experimental;

// pin vtable
RLogHandler::~RLogHandler() {}
ROOT::RLogHandler::~RLogHandler() {}

namespace {
class RLogHandlerDefault : public RLogHandler {
class RLogHandlerDefault : public ROOT::RLogHandler {
public:
// Returns false if further emission of this log entry should be suppressed.
bool Emit(const RLogEntry &entry) override;
bool Emit(const ROOT::RLogEntry &entry) override;
};

inline bool RLogHandlerDefault::Emit(const RLogEntry &entry)
inline bool RLogHandlerDefault::Emit(const ROOT::RLogEntry &entry)
{
constexpr static int numLevels = static_cast<int>(ELogLevel::kDebug) + 1;
constexpr static int numLevels = static_cast<int>(ROOT::ELogLevel::kDebug) + 1;
int cappedLevel = std::min(static_cast<int>(entry.fLevel), numLevels - 1);
constexpr static std::array<const char *, numLevels> sTag{
{"{unset-error-level please report}", "FATAL", "Error", "Warning", "Info", "Debug"}};
Expand All @@ -53,19 +51,19 @@ inline bool RLogHandlerDefault::Emit(const RLogEntry &entry)
strm << " in " << entry.fLocation.fFuncName;

static constexpr const int errorLevelOld[] = {kFatal /*unset*/, kFatal, kError, kWarning, kInfo, kInfo /*debug*/};
(*::GetErrorHandler())(errorLevelOld[cappedLevel], entry.fLevel == ELogLevel::kFatal, strm.str().c_str(),
(*::GetErrorHandler())(errorLevelOld[cappedLevel], entry.fLevel == ROOT::ELogLevel::kFatal, strm.str().c_str(),
entry.fMessage.c_str());
return true;
}
} // unnamed namespace

RLogManager &RLogManager::Get()
ROOT::RLogManager &ROOT::RLogManager::Get()
{
static RLogManager instance(std::make_unique<RLogHandlerDefault>());
return instance;
}

std::unique_ptr<RLogHandler> RLogManager::Remove(RLogHandler *handler)
std::unique_ptr<ROOT::RLogHandler> ROOT::RLogManager::Remove(RLogHandler *handler)
{
auto iter = std::find_if(fHandlers.begin(), fHandlers.end(), [&](const std::unique_ptr<RLogHandler> &handlerPtr) {
return handlerPtr.get() == handler;
Expand All @@ -79,7 +77,7 @@ std::unique_ptr<RLogHandler> RLogManager::Remove(RLogHandler *handler)
return {};
}

bool RLogManager::Emit(const RLogEntry &entry)
bool ROOT::RLogManager::Emit(const ROOT::RLogEntry &entry)
{
auto channel = entry.fChannel;

Expand Down
86 changes: 42 additions & 44 deletions core/foundation/test/testLogger.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,32 @@
#include <memory>
#include <vector>

using namespace ROOT::Experimental;

struct TestLogger {
class Handler : public RLogHandler {
class Handler : public ROOT::RLogHandler {
TestLogger *fLogger;

public:
Handler(TestLogger &logger) : fLogger(&logger) {}

bool Emit(const RLogEntry &entry) override
bool Emit(const ROOT::RLogEntry &entry) override
{
fLogger->fLogEntries.emplace_back(entry);
// Stop emission.
return false;
}
};

std::vector<RLogEntry> fLogEntries;
std::vector<ROOT::RLogEntry> fLogEntries;
Handler *fHandler;

TestLogger()
{
auto uptr = std::make_unique<Handler>(*this);
fHandler = uptr.get();
RLogManager::Get().PushFront(std::move(uptr));
ROOT::RLogManager::Get().PushFront(std::move(uptr));
}

~TestLogger() { RLogManager::Get().Remove(fHandler); }
~TestLogger() { ROOT::RLogManager::Get().Remove(fHandler); }

size_t size() const { return fLogEntries.size(); }
bool empty() const { return fLogEntries.empty(); }
Expand All @@ -43,26 +41,26 @@ struct TestLogger {
TEST(Logger, EmittedEntry)
{
TestLogger testLogger;
auto prevErrors = RLogManager::Get().GetNumErrors();
auto prevWarnings = RLogManager::Get().GetNumWarnings();
auto prevErrors = ROOT::RLogManager::Get().GetNumErrors();
auto prevWarnings = ROOT::RLogManager::Get().GetNumWarnings();

RLogChannel channel("TheChannel");
ROOT::RLogChannel channel("TheChannel");

// clang-format off
R__LOG_ERROR(channel) << "The text"; auto logLine = __LINE__;
// clang-format on

// Check manager's emission
EXPECT_EQ(testLogger.size(), 1);
EXPECT_EQ(RLogManager::Get().GetNumErrors(), prevErrors + 1);
EXPECT_EQ(RLogManager::Get().GetNumWarnings(), prevWarnings);
EXPECT_EQ(ROOT::RLogManager::Get().GetNumErrors(), prevErrors + 1);
EXPECT_EQ(ROOT::RLogManager::Get().GetNumWarnings(), prevWarnings);

// Check emitted RLogEntry
EXPECT_EQ(testLogger.fLogEntries[0].fChannel->GetName(), "TheChannel");
EXPECT_NE(testLogger.fLogEntries[0].fLocation.fFile.find("testLogger.cxx"), std::string::npos);
EXPECT_NE(testLogger.fLogEntries[0].fLocation.fFuncName.find("EmittedEntry"), std::string::npos);
EXPECT_EQ(testLogger.fLogEntries[0].fLocation.fLine, logLine);
EXPECT_EQ(testLogger.fLogEntries[0].fLevel, ELogLevel::kError);
EXPECT_EQ(testLogger.fLogEntries[0].fLevel, ROOT::ELogLevel::kError);
EXPECT_EQ(testLogger.fLogEntries[0].fMessage, "The text");
EXPECT_TRUE(testLogger.fLogEntries[0].IsError());
EXPECT_FALSE(testLogger.fLogEntries[0].IsWarning());
Expand All @@ -72,11 +70,11 @@ TEST(Logger, RLogManagerCounts)
{
TestLogger testLogger;
// Check diag counts of RLogManager.
auto initialWarnings = RLogManager::Get().GetNumWarnings();
auto initialErrors = RLogManager::Get().GetNumErrors();
auto initialWarnings = ROOT::RLogManager::Get().GetNumWarnings();
auto initialErrors = ROOT::RLogManager::Get().GetNumErrors();
R__LOG_ERROR() << "emitted";
EXPECT_EQ(RLogManager::Get().GetNumWarnings(), initialWarnings);
EXPECT_EQ(RLogManager::Get().GetNumErrors(), initialErrors + 1);
EXPECT_EQ(ROOT::RLogManager::Get().GetNumWarnings(), initialWarnings);
EXPECT_EQ(ROOT::RLogManager::Get().GetNumErrors(), initialErrors + 1);
}

TEST(Logger, RLogDiagCounter)
Expand All @@ -85,7 +83,7 @@ TEST(Logger, RLogDiagCounter)
R__LOG_ERROR() << "emitted"; // before RAII, should not be counted.
R__LOG_ERROR() << "emitted"; // before RAII, should not be counted.
// Check counter seeing what was emitted during its lifetime.
RLogScopedDiagCount counter;
ROOT::RLogScopedDiagCount counter;
EXPECT_EQ(counter.GetAccumulatedWarnings(), 0);
EXPECT_EQ(counter.GetAccumulatedErrors(), 0);
EXPECT_FALSE(counter.HasWarningOccurred());
Expand All @@ -103,27 +101,27 @@ TEST(Logger, RLogDiagCounter)

TEST(Logger, RLogScopedVerbositySuppress)
{
RLogChannel channel("ABC");
ROOT::RLogChannel channel("ABC");

auto initialLogLevel = RLogManager::Get().GetVerbosity();
auto initialLogLevel = ROOT::RLogManager::Get().GetVerbosity();
auto initialLogLevelABC = channel.GetVerbosity();
EXPECT_EQ(initialLogLevel, ELogLevel::kWarning);
EXPECT_EQ(initialLogLevelABC, ELogLevel::kUnset);
EXPECT_EQ(initialLogLevel, ROOT::ELogLevel::kWarning);
EXPECT_EQ(initialLogLevelABC, ROOT::ELogLevel::kUnset);

{
// Test simple suppression.
TestLogger testLogger;
R__LOG_WARNING(channel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
RLogScopedVerbosity suppress(ELogLevel::kError);
ROOT::RLogScopedVerbosity suppress(ROOT::ELogLevel::kError);
R__LOG_WARNING(channel) << "suppressed";
EXPECT_EQ(testLogger.size(), 1);
}
{
// Test channel specific suppression given global higher verbosity.
TestLogger testLogger;
RLogScopedVerbosity suppressGlobal(ELogLevel::kInfo);
RLogScopedVerbosity suppress(channel, ELogLevel::kError);
ROOT::RLogScopedVerbosity suppressGlobal(ROOT::ELogLevel::kInfo);
ROOT::RLogScopedVerbosity suppress(channel, ROOT::ELogLevel::kError);
R__LOG_WARNING(channel) << "suppressed";
R__LOG_INFO(channel) << "suppressed, too";
EXPECT_TRUE(testLogger.empty());
Expand All @@ -138,35 +136,35 @@ TEST(Logger, RLogScopedVerbositySuppress)
{
// Check unrelated channel.
TestLogger testLogger;
RLogChannel channel123("123");
RLogScopedVerbosity suppress(channel123, ELogLevel::kFatal);
ROOT::RLogChannel channel123("123");
ROOT::RLogScopedVerbosity suppress(channel123, ROOT::ELogLevel::kFatal);
R__LOG_ERROR(channel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
}
{
// Check global vs specific suppression.
TestLogger testLogger;
RLogScopedVerbosity suppressGlobal(ELogLevel::kDebug);
RLogScopedVerbosity suppress(channel, ELogLevel::kError);
ROOT::RLogScopedVerbosity suppressGlobal(ROOT::ELogLevel::kDebug);
ROOT::RLogScopedVerbosity suppress(channel, ROOT::ELogLevel::kError);
R__LOG_WARNING(channel) << "suppressed";
EXPECT_TRUE(testLogger.empty());
R__LOG_WARNING() << "emitted";
EXPECT_EQ(testLogger.size(), 1);
}

// Check that levels have returned to values before RAII.
EXPECT_EQ(RLogManager::Get().GetVerbosity(), initialLogLevel);
EXPECT_EQ(ROOT::RLogManager::Get().GetVerbosity(), initialLogLevel);
EXPECT_EQ(channel.GetVerbosity(), initialLogLevelABC);
}

TEST(Logger, RLogScopedVerbosityVerbose)
{
RLogChannel channel("ABC");
ROOT::RLogChannel channel("ABC");

auto initialLogLevel = RLogManager::Get().GetVerbosity();
auto initialLogLevel = ROOT::RLogManager::Get().GetVerbosity();
auto initialLogLevelABC = channel.GetVerbosity();
EXPECT_EQ(initialLogLevel, ELogLevel::kWarning);
EXPECT_EQ(initialLogLevelABC, ELogLevel::kUnset);
EXPECT_EQ(initialLogLevel, ROOT::ELogLevel::kWarning);
EXPECT_EQ(initialLogLevelABC, ROOT::ELogLevel::kUnset);

{
// Test same diag level as verbosity, in channel and global, before and after RAII.
Expand All @@ -175,7 +173,7 @@ TEST(Logger, RLogScopedVerbosityVerbose)
EXPECT_TRUE(testLogger.empty());
R__LOG_DEBUG(0) << "suppressed";
EXPECT_TRUE(testLogger.empty());
RLogScopedVerbosity verbose(ELogLevel::kDebug);
ROOT::RLogScopedVerbosity verbose(ROOT::ELogLevel::kDebug);
R__LOG_DEBUG(0, channel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
R__LOG_DEBUG(0) << "emitted";
Expand All @@ -192,7 +190,7 @@ TEST(Logger, RLogScopedVerbosityVerbose)
EXPECT_EQ(testLogger.size(), 1);
R__LOG_WARNING() << "emitted";
EXPECT_EQ(testLogger.size(), 2);
RLogScopedVerbosity verbose(channel, ELogLevel::kDebug);
ROOT::RLogScopedVerbosity verbose(channel, ROOT::ELogLevel::kDebug);
R__LOG_DEBUG(0, channel) << "emitted";
EXPECT_EQ(testLogger.size(), 3);
R__LOG_WARNING(channel) << "emitted, too";
Expand All @@ -209,7 +207,7 @@ TEST(Logger, RLogScopedVerbosityVerbose)
EXPECT_TRUE(testLogger.empty());
R__LOG_DEBUG(0, channel) << "suppressed, second";
EXPECT_TRUE(testLogger.empty());
RLogScopedVerbosity verbose(channel, ELogLevel::kInfo);
ROOT::RLogScopedVerbosity verbose(channel, ROOT::ELogLevel::kInfo);
R__LOG_INFO(channel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
R__LOG_DEBUG(0, channel) << "suppressed, third";
Expand All @@ -218,24 +216,24 @@ TEST(Logger, RLogScopedVerbosityVerbose)
{
// Test verbosity change on other channel not influcing this one.
TestLogger testLogger;
RLogChannel otherChannel("123");
RLogScopedVerbosity verbose(otherChannel, ELogLevel::kDebug);
ROOT::RLogChannel otherChannel("123");
ROOT::RLogScopedVerbosity verbose(otherChannel, ROOT::ELogLevel::kDebug);
R__LOG_DEBUG(0, channel) << "suppressed";
EXPECT_TRUE(testLogger.empty());
R__LOG_DEBUG(0, otherChannel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
}

// Check that levels have returned to values before RAII.
EXPECT_EQ(RLogManager::Get().GetVerbosity(), initialLogLevel);
EXPECT_EQ(ROOT::RLogManager::Get().GetVerbosity(), initialLogLevel);
EXPECT_EQ(channel.GetVerbosity(), initialLogLevelABC);
}

TEST(Logger, ExtraVerbosityLevels)
{
TestLogger testLogger;
RLogChannel channel("channel");
RLogScopedVerbosity verbose(channel, ELogLevel::kDebug + 50);
ROOT::RLogChannel channel("channel");
ROOT::RLogScopedVerbosity verbose(channel, ROOT::ELogLevel::kDebug + 50);

R__LOG_DEBUG(0, channel) << "emitted";
EXPECT_EQ(testLogger.size(), 1);
Expand All @@ -254,7 +252,7 @@ TEST(Logger, ExtraVerbosityLevels)
TEST(Logger, SuppressStreamEval)
{
TestLogger testLogger;
RLogChannel channel("channel");
ROOT::RLogChannel channel("channel");
bool wasEvaluated = false;
R__LOG_DEBUG(0, channel) << "It's debug, this should not be called!" << [&]() -> int {
wasEvaluated = true;
Expand Down Expand Up @@ -285,7 +283,7 @@ TEST(Logger, ROOTErrorHandlerDiagString)
{
auto prevErrorHandler = GetErrorHandler();
SetErrorHandler(testErrorHandler);
RLogChannel channel("ROOT.checkChannelName");
ROOT::RLogChannel channel("ROOT.checkChannelName");

// clang-format off
R__LOG_ERROR(channel) << "check message " << 42; auto lineNumber = __LINE__;
Expand Down
Loading

0 comments on commit 9131dfd

Please sign in to comment.