Commit 02a9aaae authored by Nguyen, Thien's avatar Nguyen, Thien
Browse files

Initial work on logging update


Signed-off-by: Nguyen, Thien's avatarThien Nguyen <nguyentm@ornl.gov>
parent de6c5ce7
......@@ -164,19 +164,80 @@ void trim(std::string &s) {
}
XACCLogger::XACCLogger()
: useColor(!RuntimeOptions::instance()->exists("no-color")),
useCout(RuntimeOptions::instance()->exists("use-cout")) {
std::string loggerName = "xacc-logger";
if (RuntimeOptions::instance()->exists("logger-name")) {
loggerName = (*RuntimeOptions::instance())["logger-name"];
}
auto _log = spdlog::get(loggerName);
if (_log) {
logger = _log;
} else {
logger = spdlog::stdout_logger_mt(loggerName);
useCout(RuntimeOptions::instance()->exists("use-cout")),
useFile(RuntimeOptions::instance()->exists("use-file")) {
// Create a std::out logger instance
{
std::string loggerName = "xacc-logger";
if (RuntimeOptions::instance()->exists("logger-name")) {
loggerName = (*RuntimeOptions::instance())["logger-name"];
}
auto _log = spdlog::get(loggerName);
if (_log) {
stdOutLogger = _log;
} else {
stdOutLogger = spdlog::stdout_logger_mt(loggerName);
}
stdOutLogger->set_level(spdlog::level::info);
}
// Create a file logger instance
{
std::string loggerName = "xacc-file-logger";
auto _log = spdlog::get(loggerName);
if (_log) {
fileLogger = _log;
} else {
const std::string DEFAULT_FILE_NAME = "xacc_log";
fileLogger = spdlog::basic_logger_mt(loggerName, DEFAULT_FILE_NAME);
}
fileLogger->set_level(spdlog::level::info);
}
}
void XACCLogger::logToFile(bool enable) {
// Switching the current setting
if (enable != useFile) {
// Always dump any enqueued messages before switching.
dumpQueue();
// Set runtime *useFile* flag, this will redirect
// log message to the appropriate logger.
useFile = enable;
}
}
void XACCLogger::setLoggingLevel(int level) {
if (level < 0 || level > 2) {
// Ignored
return;
}
// Converted the level to the spd-log enum
if (level == 0) {
// Warning and above
getLogger()->set_level(spdlog::level::warn);
}
if (level == 1) {
// Info and above
getLogger()->set_level(spdlog::level::info);
}
if (level == 2) {
// Debug and above
getLogger()->set_level(spdlog::level::debug);
}
logger->set_level(spdlog::level::info);
// Notify subscribers
for (const auto& callback : loggingLevelSubscribers) {
try {
callback(level);
}
catch (...) {
// Do nothing. This is to prevent any rogue subscribers.
}
}
}
void XACCLogger::info(const std::string &msg, MessagePredicate predicate) {
......@@ -190,10 +251,10 @@ void XACCLogger::info(const std::string &msg, MessagePredicate predicate) {
}
} else {
if (predicate() && globalPredicate()) {
if (useColor) {
logger->info("\033[1;34m" + msg + "\033[0m");
if (useColor & !useFile) {
getLogger()->info("\033[1;34m" + msg + "\033[0m");
} else {
logger->info(msg);
getLogger()->info(msg);
}
}
}
......@@ -210,10 +271,10 @@ void XACCLogger::warning(const std::string &msg, MessagePredicate predicate) {
}
} else {
if (predicate() && globalPredicate()) {
if (useColor) {
logger->info("\033[1;33m" + msg + "\033[0m");
if (useColor & !useFile) {
getLogger()->info("\033[1;33m" + msg + "\033[0m");
} else {
logger->info(msg);
getLogger()->info(msg);
}
}
}
......@@ -230,10 +291,10 @@ void XACCLogger::debug(const std::string &msg, MessagePredicate predicate) {
}
} else {
if (predicate() && globalPredicate()) {
if (useColor) {
logger->info("\033[1;32m" + msg + "\033[0m");
if (useColor & !useFile) {
getLogger()->info("\033[1;32m" + msg + "\033[0m");
} else {
logger->info(msg);
getLogger()->info(msg);
}
}
}
......@@ -244,7 +305,7 @@ void XACCLogger::error(const std::string &msg, MessagePredicate predicate) {
std::cerr << msg << "\n";
} else {
if (predicate() && globalPredicate()) {
logger->error("\033[1;31m[XACC Error] " + msg + "\033[0m");
getLogger()->error("\033[1;31m[XACC Error] " + msg + "\033[0m");
}
}
}
......
......@@ -139,21 +139,34 @@ void tuple_for_each(TupleType &&t, FunctionType f) {
}
using MessagePredicate = std::function<bool(void)>;
// Notify subscribers when the logging level was changed.
// This can be used to control logging level/verbosity of
// external libraries (e.g. those used by plugins) to
// match that of XACC.
using LoggingLevelNotification = std::function<void(int)>;
class XACCLogger : public Singleton<XACCLogger> {
protected:
std::shared_ptr<spdlog::logger> logger;
std::shared_ptr<spdlog::logger> stdOutLogger;
std::shared_ptr<spdlog::logger> fileLogger;
bool useCout = false;
// Should we log to file?
bool useFile = false;
bool useColor = true;
MessagePredicate globalPredicate = []() { return true; };
std::vector<LoggingLevelNotification> loggingLevelSubscribers;
std::queue<std::string> logQueue;
XACCLogger();
std::shared_ptr<spdlog::logger> getLogger() { return useFile ? fileLogger : stdOutLogger; }
public:
// Overriding here so we can have a custom constructor
......@@ -164,6 +177,22 @@ public:
return instance_;
}
// If enable = true, switch to File logging (if not already logging to file).
// If enable = false, stop logging to File if currently is.
// This enables dev to scope a section which should log to File.
void logToFile(bool enable);
// Set level for log filtering:
// 0: Errors and Warnings only
// 1: Info and above
// 2: Debug and above
// Note: this will only take effect when xacc::verbose is set.
void setLoggingLevel(int level);
void subscribeLoggingLevel(LoggingLevelNotification onLevelChangeFn) {
loggingLevelSubscribers.emplace_back(onLevelChangeFn);
}
void enqueueLog(const std::string log) { logQueue.push(log); }
void dumpQueue() {
......
......@@ -111,6 +111,18 @@ void setGlobalLoggerPredicate(MessagePredicate predicate) {
XACCLogger::instance()->dumpQueue();
}
void logToFile(bool enable) {
XACCLogger::instance()->logToFile(enable);
}
void setLoggingLevel(int level) {
XACCLogger::instance()->setLoggingLevel(level);
}
void subscribeLoggingLevel(LoggingLevelNotification callback) {
XACCLogger::instance()->subscribeLoggingLevel(callback);
}
void info(const std::string &msg, MessagePredicate predicate) {
if (verbose) XACCLogger::instance()->info(msg, predicate);
}
......
......@@ -95,6 +95,10 @@ void addCommandLineOptions(const std::string &category,
void addCommandLineOptions(const std::map<std::string, std::string> &options);
void setGlobalLoggerPredicate(MessagePredicate predicate);
void logToFile(bool enable);
void setLoggingLevel(int level);
void subscribeLoggingLevel(LoggingLevelNotification callback);
void info(const std::string &msg,
MessagePredicate predicate = std::function<bool(void)>([]() {
return true;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment