| // |
| // Copyright © 2019 Arm Ltd. All rights reserved. |
| // SPDX-License-Identifier: MIT |
| // |
| |
| #pragma once |
| |
| #include <iostream> |
| |
| #include "Utils.hpp" |
| |
| |
| #if defined(_MSC_VER) |
| #include <Windows.h> |
| #endif |
| |
| #if defined(__ANDROID__) |
| #include <android/log.h> |
| #endif |
| |
| #include <boost/assert.hpp> |
| |
| |
| 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"; |
| } |
| } |
| |
| class LogSink |
| { |
| public: |
| virtual ~LogSink(){}; |
| |
| virtual void Consume(const std::string& s) = 0; |
| private: |
| |
| }; |
| |
| class StandardOutputColourSink : public LogSink |
| { |
| public: |
| StandardOutputColourSink(LogSeverity level = LogSeverity::Info) |
| : m_Level(level) |
| { |
| } |
| |
| void Consume(const std::string& s) override |
| { |
| std::cout << GetColour(m_Level) << s << ResetColour() << std::endl; |
| } |
| |
| private: |
| std::string ResetColour() |
| { |
| return "\033[0m"; |
| } |
| |
| std::string GetColour(LogSeverity level) |
| { |
| switch(level) |
| { |
| case LogSeverity::Trace: |
| return "\033[35m"; |
| case LogSeverity::Debug: |
| return "\033[32m"; |
| case LogSeverity::Info: |
| return "\033[0m"; |
| case LogSeverity::Warning: |
| return "\033[33m"; |
| case LogSeverity::Error: |
| return "\033[31m"; |
| case LogSeverity::Fatal: |
| return "\033[41;30m"; |
| |
| default: |
| return "\033[0m"; |
| } |
| } |
| LogSeverity m_Level; |
| }; |
| |
| class StandardOutputSink : public LogSink |
| { |
| public: |
| void Consume(const std::string& s) override |
| { |
| std::cout << s << std::endl; |
| } |
| }; |
| |
| class DebugOutputSink : public LogSink |
| { |
| public: |
| void Consume(const std::string& s) override |
| { |
| #if defined(_MSC_VER) |
| OutputDebugString(s.c_str()); |
| OutputDebugString("\n"); |
| #endif |
| #if defined(__ANDROID__) |
| __android_log_write(ANDROID_LOG_DEBUG, "armnn", s.c_str()); |
| #endif |
| } |
| }; |
| |
| 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(ScopedRecord&& other) = default; |
| ScopedRecord& operator=(ScopedRecord&&) = default; |
| |
| 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() |
| { |
| static SimpleLogger<Level> logger; |
| return logger; |
| } |
| |
| void Enable(bool enable = true) |
| { |
| m_Enable = enable; |
| } |
| |
| ScopedRecord StartNewRecord() |
| { |
| ScopedRecord record(m_Sinks, Level, m_Enable); |
| return record; |
| } |
| |
| 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; |
| }; |
| |
| inline void SetLogFilter(LogSeverity level) |
| { |
| SimpleLogger<LogSeverity::Trace>::Get().Enable(false); |
| SimpleLogger<LogSeverity::Debug>::Get().Enable(false); |
| SimpleLogger<LogSeverity::Info>::Get().Enable(false); |
| SimpleLogger<LogSeverity::Warning>::Get().Enable(false); |
| SimpleLogger<LogSeverity::Error>::Get().Enable(false); |
| SimpleLogger<LogSeverity::Fatal>::Get().Enable(false); |
| switch (level) |
| { |
| case LogSeverity::Trace: |
| SimpleLogger<LogSeverity::Trace>::Get().Enable(true); |
| ARMNN_FALLTHROUGH; |
| case LogSeverity::Debug: |
| SimpleLogger<LogSeverity::Debug>::Get().Enable(true); |
| ARMNN_FALLTHROUGH; |
| case LogSeverity::Info: |
| SimpleLogger<LogSeverity::Info>::Get().Enable(true); |
| ARMNN_FALLTHROUGH; |
| case LogSeverity::Warning: |
| SimpleLogger<LogSeverity::Warning>::Get().Enable(true); |
| ARMNN_FALLTHROUGH; |
| case LogSeverity::Error: |
| SimpleLogger<LogSeverity::Error>::Get().Enable(true); |
| ARMNN_FALLTHROUGH; |
| case LogSeverity::Fatal: |
| SimpleLogger<LogSeverity::Fatal>::Get().Enable(true); |
| break; |
| default: |
| BOOST_ASSERT(false); |
| } |
| } |
| |
| template<LogSeverity Level> |
| inline void SetLoggingSinks(bool standardOut, bool debugOut, bool coloured) |
| { |
| SimpleLogger<Level>::Get().RemoveAllSinks(); |
| |
| if (standardOut) |
| { |
| if (coloured) |
| { |
| SimpleLogger<Level>::Get().AddSink( |
| std::make_shared<StandardOutputColourSink>(Level)); |
| } else |
| { |
| SimpleLogger<Level>::Get().AddSink( |
| std::make_shared<StandardOutputSink>()); |
| } |
| } |
| |
| if (debugOut) |
| { |
| SimpleLogger<Level>::Get().AddSink( |
| std::make_shared<DebugOutputSink>()); |
| } |
| } |
| |
| inline void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured) |
| { |
| SetLoggingSinks<LogSeverity::Trace>(standardOut, debugOut, coloured); |
| SetLoggingSinks<LogSeverity::Debug>(standardOut, debugOut, coloured); |
| SetLoggingSinks<LogSeverity::Info>(standardOut, debugOut, coloured); |
| SetLoggingSinks<LogSeverity::Warning>(standardOut, debugOut, coloured); |
| SetLoggingSinks<LogSeverity::Error>(standardOut, debugOut, coloured); |
| SetLoggingSinks<LogSeverity::Fatal>(standardOut, debugOut, 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 |