forked from Qortal/Brooklyn
209 lines
4.2 KiB
C++
209 lines
4.2 KiB
C++
//
|
|
// Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <armnn/Utils.hpp>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
namespace armnn
|
|
{
|
|
|
|
inline std::string LevelToString(LogSeverity level)
|
|
{
|
|
switch(level)
|
|
{
|
|
case LogSeverity::Trace:
|
|
return "Trace";
|
|
case LogSeverity::Debug:
|
|
return "Debug";
|
|
case LogSeverity::Info:
|
|
return "Info";
|
|
case LogSeverity::Warning:
|
|
return "Warning";
|
|
case LogSeverity::Error:
|
|
return "Error";
|
|
case LogSeverity::Fatal:
|
|
return "Fatal";
|
|
default:
|
|
return "Log";
|
|
}
|
|
}
|
|
|
|
inline LogSeverity StringToLogLevel(std::string level)
|
|
{
|
|
// Transfer to lower case
|
|
std::transform(level.begin(), level.end(), level.begin(),
|
|
[](unsigned char c){ return std::tolower(c); }
|
|
);
|
|
|
|
if (level == "trace")
|
|
{
|
|
return LogSeverity::Trace;
|
|
}
|
|
else if (level == "debug")
|
|
{
|
|
return LogSeverity::Debug;
|
|
}
|
|
else if (level == "info")
|
|
{
|
|
return LogSeverity::Info;
|
|
}
|
|
else if (level == "warning")
|
|
{
|
|
return LogSeverity::Warning;
|
|
}
|
|
else if (level == "error")
|
|
{
|
|
return LogSeverity::Error;
|
|
}
|
|
else if (level == "fatal")
|
|
{
|
|
return LogSeverity::Fatal;
|
|
}
|
|
else
|
|
{
|
|
throw armnn::Exception("Unknown severity level for logging: '" + level +
|
|
"'. Valid options: trace, debug, info, warning, error, fatal");
|
|
}
|
|
}
|
|
|
|
class LogSink
|
|
{
|
|
public:
|
|
virtual ~LogSink(){};
|
|
|
|
virtual void Consume(const std::string&) = 0;
|
|
private:
|
|
|
|
};
|
|
|
|
class StandardOutputSink : public LogSink
|
|
{
|
|
public:
|
|
void Consume(const std::string& s) override
|
|
{
|
|
std::cout << s << std::endl;
|
|
}
|
|
};
|
|
|
|
struct ScopedRecord
|
|
{
|
|
ScopedRecord(const std::vector<std::shared_ptr<LogSink>>& sinks, LogSeverity level, bool enabled)
|
|
: m_LogSinks(sinks)
|
|
, m_Enabled(enabled)
|
|
{
|
|
if (enabled)
|
|
{
|
|
m_Os << LevelToString(level) << ": ";
|
|
}
|
|
}
|
|
|
|
~ScopedRecord()
|
|
{
|
|
if (m_Enabled)
|
|
{
|
|
for (auto sink : m_LogSinks)
|
|
{
|
|
if (sink)
|
|
{
|
|
sink->Consume(m_Os.str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ScopedRecord(const ScopedRecord&) = delete;
|
|
ScopedRecord& operator=(const ScopedRecord&) = delete;
|
|
ScopedRecord& operator=(ScopedRecord&&) = delete;
|
|
|
|
ScopedRecord(ScopedRecord&& other)
|
|
: m_LogSinks(other.m_LogSinks)
|
|
, m_Os(std::move(other.m_Os))
|
|
, m_Enabled(other.m_Enabled)
|
|
{
|
|
// Disable the moved-from ScopedRecord, to prevent it from sending its (now empty) message to
|
|
// its sinks.
|
|
other.m_Enabled = false;
|
|
}
|
|
|
|
template<typename Streamable>
|
|
ScopedRecord& operator<<(const Streamable& s)
|
|
{
|
|
if (m_Enabled)
|
|
{
|
|
m_Os << s;
|
|
}
|
|
return (*this);
|
|
}
|
|
|
|
private:
|
|
const std::vector<std::shared_ptr<LogSink>>& m_LogSinks;
|
|
std::ostringstream m_Os;
|
|
bool m_Enabled;
|
|
};
|
|
|
|
template<LogSeverity Level>
|
|
class SimpleLogger
|
|
{
|
|
public:
|
|
SimpleLogger()
|
|
: m_Sinks{std::make_shared<StandardOutputSink>()}
|
|
, m_Enable(true)
|
|
{
|
|
}
|
|
|
|
static SimpleLogger& Get();
|
|
|
|
void Enable(bool enable = true)
|
|
{
|
|
m_Enable = enable;
|
|
}
|
|
|
|
ScopedRecord StartNewRecord()
|
|
{
|
|
return ScopedRecord(m_Sinks, Level, m_Enable);
|
|
}
|
|
|
|
void RemoveAllSinks()
|
|
{
|
|
m_Sinks.clear();
|
|
}
|
|
|
|
void AddSink(std::shared_ptr<LogSink> sink)
|
|
{
|
|
m_Sinks.push_back(sink);
|
|
}
|
|
private:
|
|
std::vector<std::shared_ptr<LogSink>> m_Sinks;
|
|
bool m_Enable;
|
|
};
|
|
|
|
void SetLogFilter(LogSeverity level);
|
|
|
|
void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured);
|
|
|
|
enum class BoostLogSeverityMapping
|
|
{
|
|
trace,
|
|
debug,
|
|
info,
|
|
warning,
|
|
error,
|
|
fatal
|
|
};
|
|
|
|
constexpr LogSeverity ConvertLogSeverity(BoostLogSeverityMapping severity)
|
|
{
|
|
return static_cast<LogSeverity>(severity);
|
|
}
|
|
|
|
|
|
#define ARMNN_LOG(severity) \
|
|
armnn::SimpleLogger<ConvertLogSeverity(armnn::BoostLogSeverityMapping::severity)>::Get().StartNewRecord()
|
|
|
|
} //namespace armnn
|