Page MenuHomeHEPForge

No OneTemporary

diff --git a/include/Rivet/Tools/Logging.hh b/include/Rivet/Tools/Logging.hh
--- a/include/Rivet/Tools/Logging.hh
+++ b/include/Rivet/Tools/Logging.hh
@@ -1,187 +1,183 @@
#ifndef RIVET_LOGGING_HH
#define RIVET_LOGGING_HH
#include "Rivet/Config/RivetCommon.hh"
namespace Rivet {
class Log {
public:
/// Log priority levels.
enum Level {
TRACE = 0, DEBUG = 10, INFO = 20, WARN = 30, WARNING = 30, ERROR = 40, CRITICAL = 50, ALWAYS = 50
};
/// Typedef for a collection of named logs.
- typedef std::map<std::string, Log*> LogMap;
+ typedef std::map<std::string, Log> LogMap;
/// Typedef for a collection of named log levels.
typedef std::map<std::string, int> LevelMap;
/// Typedef for a collection of shell color codes, accessed by log level.
typedef std::map<int, std::string> ColorCodes;
private:
/// A static map of existing logs: we don't make more loggers than necessary.
static LogMap existingLogs;
/// A static map of default log levels.
static LevelMap defaultLevels;
/// A static map of shell color codes for the log levels.
static ColorCodes colorCodes;
/// Shell color code for the end of the log levels.
static std::string endColorCode;
/// Show timestamp?
static bool showTimestamp;
/// Show log level?
static bool showLogLevel;
/// Show logger name?
static bool showLoggerName;
/// Use shell colour escape codes?
static bool useShellColors;
public:
/// Set the log levels
static void setLevel(const std::string& name, int level);
static void setLevels(const LevelMap& logLevels);
static void setShowTimestamp(bool showTime=true) {
showTimestamp = showTime;
}
static void setShowLevel(bool showLevel=true) {
showLogLevel = showLevel;
}
static void setShowLoggerName(bool showName=true) {
showLoggerName = showName;
}
static void setUseColors(bool useColors=true) {
useShellColors = useColors;
}
protected:
/// @name Hidden constructors etc.
//@{
/// Constructor 1
Log(const std::string& name);
/// Constructor 2
Log(const std::string& name, int level);
//@}
static std::string getColorCode(int level);
public:
/// Get a logger with the given name. The level will be taken from the
/// "requestedLevels" static map or will be INFO by default.
static Log& getLog(const std::string& name);
public:
/// Get the priority level of this logger.
int getLevel() const {
return _level;
}
/// Set the priority level of this logger.
Log& setLevel(int level) {
_level = level;
return *this;
}
/// Get a log level enum from a string.
static Level getLevelFromName(const std::string& level);
/// Get the std::string representation of a log level.
static std::string getLevelName(int level);
/// Get the name of this logger.
std::string getName() const {
return _name;
}
/// Set the name of this logger.
Log& setName(const std::string& name) {
_name = name;
return *this;
}
/// Will this log level produce output on this logger at the moment?
bool isActive(int level) const {
return (level >= _level);
}
/// @name Explicit log methods
//@{
void trace(const std::string& message) { log(TRACE, message); }
void debug(const std::string& message) { log(DEBUG, message); }
void info(const std::string& message) { log(INFO, message); }
void warn(const std::string& message) { log(WARN, message); }
void error(const std::string& message) { log(ERROR, message); }
//@}
private:
/// This logger's name
std::string _name;
/// Threshold level for this logger.
int _level;
protected:
/// Write a message at a particular level.
void log(int level, const std::string& message);
/// Turn a message string into the current log format.
std::string formatMessage(int level, const std::string& message);
public:
- /// A null output stream, used for piping discarded output to nowhere.
- /// @todo Hide this...
- std::ostream* const _nostream;
-
/// The streaming operator can use Log's internals.
friend std::ostream& operator<<(Log& log, int level);
};
/// Streaming output to a logger must have a Log::Level/int as its first argument.
std::ostream& operator<<(Log& log, int level);
}
// Neat CPU-conserving logging macros. Use by preference!
// NB. Only usable in classes where a getLog() method is provided
#define MSG_LVL(lvl, x) \
do { \
if (getLog().isActive(lvl)) { \
getLog() << lvl << x << endl; \
} \
} while (0)
#define MSG_TRACE(x) MSG_LVL(Log::TRACE, x)
#define MSG_DEBUG(x) MSG_LVL(Log::DEBUG, x)
#define MSG_INFO(x) MSG_LVL(Log::INFO, x)
#define MSG_WARNING(x) MSG_LVL(Log::WARNING, x)
#define MSG_ERROR(x) MSG_LVL(Log::ERROR, x)
#endif
diff --git a/src/Tools/Logging.cc b/src/Tools/Logging.cc
--- a/src/Tools/Logging.cc
+++ b/src/Tools/Logging.cc
@@ -1,198 +1,203 @@
#include "Rivet/Tools/Logging.hh"
#include <ctime>
#include <unistd.h>
using namespace std;
namespace Rivet {
Log::LogMap Log::existingLogs;
Log::LevelMap Log::defaultLevels;
Log::ColorCodes Log::colorCodes;
string Log::endColorCode;
bool Log::showTimestamp = false;
bool Log::showLogLevel = true;
bool Log::showLoggerName = true;
bool Log::useShellColors = true;
Log::Log(const string& name)
- : _name(name), _level(INFO), _nostream(new ostream(0)) { }
+ : _name(name), _level(INFO) { }
Log::Log(const string& name, int level)
- : _name(name), _level(level), _nostream(new ostream(0)) { }
+ : _name(name), _level(level) { }
/// @todo Add single static setLevel
void _updateLevels(const Log::LevelMap& defaultLevels, Log::LogMap& existingLogs) {
/// @todo Check ordering - "Foo" should come before "Foo.Bar"
for (Log::LevelMap::const_iterator lev = defaultLevels.begin(); lev != defaultLevels.end(); ++lev) {
for (Log::LogMap::iterator log = existingLogs.begin(); log != existingLogs.end(); ++log) {
if (log->first.find(lev->first) == 0) {
- log->second->setLevel(lev->second);
+ log->second.setLevel(lev->second);
}
}
}
}
void Log::setLevel(const string& name, int level) {
defaultLevels[name] = level;
//cout << name << " -> " << level << endl;
_updateLevels(defaultLevels, existingLogs);
}
void Log::setLevels(const LevelMap& logLevels) {
for (LevelMap::const_iterator lev = logLevels.begin(); lev != logLevels.end(); ++lev) {
defaultLevels[lev->first] = lev->second;
}
_updateLevels(defaultLevels, existingLogs);
}
Log& Log::getLog(const string& name) {
- if (existingLogs.find(name) == existingLogs.end()) {
+ auto theLog = existingLogs.find(name);
+ if (theLog == existingLogs.end()) {
int level = INFO;
// Try running through all parent classes to find an existing level
string tmpname = name;
bool triedAllParents = false;
while (! triedAllParents) {
// Is there a default level?
if (defaultLevels.find(tmpname) != defaultLevels.end()) {
level = defaultLevels.find(tmpname)->second;
break;
}
- // Is there already such a logger? (NB. tmpname != name)
+ // Is there already such a logger? (NB. tmpname != name in later iterations)
if (existingLogs.find(tmpname) != existingLogs.end()) {
- level = existingLogs.find(tmpname)->second->getLevel();
+ level = existingLogs.find(tmpname)->second.getLevel();
break;
}
// Crop the string back to the next parent level
size_t lastDot = tmpname.find_last_of(".");
if (lastDot != string::npos) {
tmpname = tmpname.substr(0, lastDot);
} else {
triedAllParents = true;
}
}
// for (LevelMap::const_iterator l = defaultLevels.begin(); l != defaultLevels.end(); ++l) {
//
// }
- existingLogs[name] = new Log(name, level);
+
+ // emplace returns pair<iterator,bool>
+ auto result = existingLogs.emplace(name, Log(name, level));
+ theLog = result.first;
}
- return *existingLogs[name];
+ return theLog->second;
}
string Log::getLevelName(int level) {
/// @todo Do the map::upper_limit thing to find nearest level...
switch(level) {
case TRACE:
return "TRACE";
case DEBUG:
return "DEBUG";
case INFO:
return "INFO";
case WARN:
return "WARN";
case ERROR:
return "ERROR";
default:
return "";
}
//throw Error("Enum value was not a valid log level. How did that happen?");
}
string Log::getColorCode(int level) {
if (!Log::useShellColors) return "";
// If the codes haven't been initialized, do so now.
if (Log::colorCodes.empty()) {
// If stdout is a valid tty, try to use the appropriate codes.
if (isatty(1)) {
/// @todo Test for VT100 compliance?
Log::colorCodes[TRACE] = "\033[0;36m";
Log::colorCodes[DEBUG] = "\033[0;34m";
Log::colorCodes[INFO] = "\033[0;32m";
Log::colorCodes[WARN] = "\033[0;33m";
Log::colorCodes[ERROR] = "\033[0;31m";
Log::endColorCode = "\033[0m";
} else {
Log::colorCodes[TRACE] = "";
Log::colorCodes[DEBUG] = "";
Log::colorCodes[INFO] = "";
Log::colorCodes[WARN] = "";
Log::colorCodes[ERROR] = "";
}
}
// Return the appropriate code from the colour map.
/// @todo Do the map::upper_limit thing to find nearest level...
return colorCodes[level];
}
Log::Level Log::getLevelFromName(const string& level) {
if (level == "TRACE") return TRACE;
if (level == "DEBUG") return DEBUG;
if (level == "INFO") return INFO;
if (level == "WARN") return WARN;
if (level == "ERROR") return ERROR;
throw Error("Couldn't create a log level from string '" + level + "'");
}
string Log::formatMessage(int level, const string& message) {
string out;
if (Log::useShellColors) {
out += getColorCode(level);
}
if (Log::showLoggerName) {
out += getName();
out += ": ";
}
if (Log::showLogLevel) {
out += Log::getLevelName(level);
out += " ";
}
if (Log::showTimestamp) {
time_t rawtime;
time(&rawtime);
char* timestr = ctime(&rawtime);
timestr[24] = ' ';
out += timestr;
out += " ";
}
if (Log::useShellColors) {
out += endColorCode;
}
out += " ";
out += message;
return out;
}
void Log::log(int level, const string& message) {
if (isActive(level)) {
cout << formatMessage(level, message) << endl;
}
}
ostream& operator<<(Log& log, int level) {
if (log.isActive(level)) {
cout << log.formatMessage(level, "");
return cout;
} else {
- return *(log._nostream);
+ static ostream devNull(nullptr);
+ return devNull;
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 19, 2:41 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3804782
Default Alt Text
(11 KB)

Event Timeline