1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #pragma once
7
8 #include <armnn/Utils.hpp>
9 #include <iostream>
10
11 namespace armnn
12 {
13
LevelToString(LogSeverity level)14 inline std::string LevelToString(LogSeverity level)
15 {
16 switch(level)
17 {
18 case LogSeverity::Trace:
19 return "Trace";
20 case LogSeverity::Debug:
21 return "Debug";
22 case LogSeverity::Info:
23 return "Info";
24 case LogSeverity::Warning:
25 return "Warning";
26 case LogSeverity::Error:
27 return "Error";
28 case LogSeverity::Fatal:
29 return "Fatal";
30 default:
31 return "Log";
32 }
33 }
34
35 class LogSink
36 {
37 public:
~LogSink()38 virtual ~LogSink(){};
39
40 virtual void Consume(const std::string&) = 0;
41 private:
42
43 };
44
45 class StandardOutputSink : public LogSink
46 {
47 public:
Consume(const std::string & s)48 void Consume(const std::string& s) override
49 {
50 std::cout << s << std::endl;
51 }
52 };
53
54 struct ScopedRecord
55 {
ScopedRecordarmnn::ScopedRecord56 ScopedRecord(const std::vector<std::shared_ptr<LogSink>>& sinks, LogSeverity level, bool enabled)
57 : m_LogSinks(sinks)
58 , m_Enabled(enabled)
59 {
60 if (enabled)
61 {
62 m_Os << LevelToString(level) << ": ";
63 }
64 }
65
~ScopedRecordarmnn::ScopedRecord66 ~ScopedRecord()
67 {
68 if (m_Enabled)
69 {
70 for (auto sink : m_LogSinks)
71 {
72 if (sink)
73 {
74 sink->Consume(m_Os.str());
75 }
76 }
77 }
78 }
79
80 ScopedRecord(const ScopedRecord&) = delete;
81 ScopedRecord& operator=(const ScopedRecord&) = delete;
82 ScopedRecord& operator=(ScopedRecord&&) = delete;
83
84 ScopedRecord(ScopedRecord&& other) = default;
85
86 template<typename Streamable>
operator <<armnn::ScopedRecord87 ScopedRecord& operator<<(const Streamable& s)
88 {
89 if (m_Enabled)
90 {
91 m_Os << s;
92 }
93 return (*this);
94 }
95
96 private:
97 const std::vector<std::shared_ptr<LogSink>>& m_LogSinks;
98 std::ostringstream m_Os;
99 bool m_Enabled;
100 };
101
102 template<LogSeverity Level>
103 class SimpleLogger
104 {
105 public:
SimpleLogger()106 SimpleLogger()
107 : m_Sinks{std::make_shared<StandardOutputSink>()}
108 , m_Enable(true)
109 {
110 }
111
Get()112 static SimpleLogger& Get()
113 {
114 static SimpleLogger<Level> logger;
115 return logger;
116 }
117
Enable(bool enable=true)118 void Enable(bool enable = true)
119 {
120 m_Enable = enable;
121 }
122
StartNewRecord()123 ScopedRecord StartNewRecord()
124 {
125 ScopedRecord record(m_Sinks, Level, m_Enable);
126 return record;
127 }
128
RemoveAllSinks()129 void RemoveAllSinks()
130 {
131 m_Sinks.clear();
132 }
133
AddSink(std::shared_ptr<LogSink> sink)134 void AddSink(std::shared_ptr<LogSink> sink)
135 {
136 m_Sinks.push_back(sink);
137 }
138 private:
139 std::vector<std::shared_ptr<LogSink>> m_Sinks;
140 bool m_Enable;
141 };
142
143 void SetLogFilter(LogSeverity level);
144
145 void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured);
146
147 enum class BoostLogSeverityMapping
148 {
149 trace,
150 debug,
151 info,
152 warning,
153 error,
154 fatal
155 };
156
ConvertLogSeverity(BoostLogSeverityMapping severity)157 constexpr LogSeverity ConvertLogSeverity(BoostLogSeverityMapping severity)
158 {
159 return static_cast<LogSeverity>(severity);
160 }
161
162
163 #define ARMNN_LOG(severity) \
164 armnn::SimpleLogger<ConvertLogSeverity(armnn::BoostLogSeverityMapping::severity)>::Get().StartNewRecord()
165
166 } //namespace armnn
167