Logo ROOT  
Reference Guide
RLogger.cxx
Go to the documentation of this file.
1/// \file RLogger.cxx
2/// \ingroup Base ROOT7
3/// \author Axel Naumann <axel@cern.ch>
4/// \date 2015-07-07
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#include "ROOT/RLogger.hxx"
17
18#include "TError.h"
19
20#include <algorithm>
21#include <array>
22#include <memory>
23#include <vector>
24
25using namespace ROOT::Experimental;
26
27// pin vtable
28RLogHandler::~RLogHandler() {}
29
30namespace {
31class RLogHandlerDefault : public RLogHandler {
32public:
33 // Returns false if further emission of this log entry should be suppressed.
34 bool Emit(const RLogEntry &entry) override;
35};
36
37inline bool RLogHandlerDefault::Emit(const RLogEntry &entry)
38{
39 constexpr static int numLevels = static_cast<int>(ELogLevel::kDebug) + 1;
40 int cappedLevel = std::min(static_cast<int>(entry.fLevel), numLevels - 1);
41 constexpr static std::array<const char *, numLevels> sTag{
42 {"{unset-error-level please report}", "FATAL", "Error", "Warning", "Info", "Debug"}};
43
44 std::stringstream strm;
45 auto channel = entry.fChannel;
46 if (channel && !channel->GetName().empty())
47 strm << '[' << channel->GetName() << "] ";
48 strm << sTag[cappedLevel];
49
50 if (!entry.fLocation.fFile.empty())
51 strm << " " << entry.fLocation.fFile << ':' << entry.fLocation.fLine;
52 if (!entry.fLocation.fFuncName.empty())
53 strm << " in " << entry.fLocation.fFuncName;
54
55 static constexpr const int errorLevelOld[] = {kFatal /*unset*/, kFatal, kError, kWarning, kInfo, kInfo /*debug*/};
56 (*::GetErrorHandler())(errorLevelOld[cappedLevel], entry.fLevel == ELogLevel::kFatal, strm.str().c_str(),
57 entry.fMessage.c_str());
58 return true;
59}
60} // unnamed namespace
61
63{
64 static RLogManager instance(std::make_unique<RLogHandlerDefault>());
65 return instance;
66}
67
68std::unique_ptr<RLogHandler> RLogManager::Remove(RLogHandler *handler)
69{
70 auto iter = std::find_if(fHandlers.begin(), fHandlers.end(), [&](const std::unique_ptr<RLogHandler> &handlerPtr) {
71 return handlerPtr.get() == handler;
72 });
73 if (iter != fHandlers.end()) {
74 std::unique_ptr<RLogHandler> ret;
75 swap(*iter, ret);
76 fHandlers.erase(iter);
77 return ret;
78 }
79 return {};
80}
81
82bool RLogManager::Emit(const RLogEntry &entry)
83{
84 auto channel = entry.fChannel;
85
86 Increment(entry.fLevel);
87 if (channel != this)
88 channel->Increment(entry.fLevel);
89
90 // Is there a specific level for the channel? If so, take that,
91 // overruling the global one.
92 if (channel->GetEffectiveVerbosity(*this) < entry.fLevel)
93 return true;
94
95 // Lock-protected extraction of handlers, such that they don't get added during the
96 // handler iteration.
97 std::vector<RLogHandler *> handlers;
98
99 {
100 std::lock_guard<std::mutex> lock(fMutex);
101
102 handlers.resize(fHandlers.size());
103 std::transform(fHandlers.begin(), fHandlers.end(), handlers.begin(),
104 [](const std::unique_ptr<RLogHandler> &handlerUPtr) { return handlerUPtr.get(); });
105 }
106
107 for (auto &&handler : handlers)
108 if (!handler->Emit(entry))
109 return false;
110 return true;
111}
const Int_t kError
Definition: TError.h:46
ErrorHandlerFunc_t GetErrorHandler()
Returns the current error handler function.
Definition: TError.cxx:102
const Int_t kFatal
Definition: TError.h:49
const Int_t kWarning
Definition: TError.h:45
const Int_t kInfo
Definition: TError.h:44
const std::string & GetName() const
Definition: RLogger.hxx:126
void Increment(ELogLevel severity)
Increase warning or error count.
Definition: RLogger.hxx:70
A diagnostic that can be emitted by the RLogManager.
Definition: RLogger.hxx:178
Abstract RLogHandler base class.
Definition: RLogger.hxx:85
A RLogHandler that multiplexes diagnostics to different client RLogHandlers and keeps track of the su...
Definition: RLogger.hxx:136
std::list< std::unique_ptr< RLogHandler > > fHandlers
Definition: RLogger.hxx:138
std::unique_ptr< RLogHandler > Remove(RLogHandler *handler)
Remove and return the given log handler. Returns nullptr if not found.
Definition: RLogger.cxx:68
static RLogManager & Get()
Definition: RLogger.cxx:62
bool Emit(const RLogEntry &entry) override
Emit a log entry.
Definition: RLogger.cxx:82
void swap(RHist< DIMENSIONS, PRECISION, STAT... > &a, RHist< DIMENSIONS, PRECISION, STAT... > &b) noexcept
Swap two histograms.
Definition: RHist.hxx:195
@ kDebug
Debug information; only useful for developers; can have added verbosity up to 255-kDebug.
@ kFatal
An error which causes further processing to be unreliable.
static Roo_reg_AGKInteg1D instance