1 //
2 // Copyright © 2019 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include <armnn/Logging.hpp>
7 #include <armnn/utility/IgnoreUnused.hpp>
8 #include <armnn/Utils.hpp>
9 #include <armnn/utility/Assert.hpp>
10
11 #if defined(_MSC_VER)
12 #include <common/include/WindowsWrapper.hpp>
13 #endif
14
15 #if defined(__ANDROID__)
16 #include <android/log.h>
17 #endif
18
19 #include <iostream>
20
21 namespace armnn
22 {
23
24 template<LogSeverity Level>
Get()25 SimpleLogger<Level>& SimpleLogger<Level>::Get()
26 {
27 static SimpleLogger<Level> logger;
28 return logger;
29 }
30
31 template<>
Get()32 SimpleLogger<LogSeverity::Debug>& SimpleLogger<LogSeverity::Debug>::Get()
33 {
34 static SimpleLogger<LogSeverity::Debug> logger;
35 return logger;
36 }
37
38 template<>
Get()39 SimpleLogger<LogSeverity::Trace>& SimpleLogger<LogSeverity::Trace>::Get()
40 {
41 static SimpleLogger<LogSeverity::Trace> logger;
42 return logger;
43 }
44
45 template<>
Get()46 SimpleLogger<LogSeverity::Info>& SimpleLogger<LogSeverity::Info>::Get()
47 {
48 static SimpleLogger<LogSeverity::Info> logger;
49 return logger;
50 }
51
52 template<>
Get()53 SimpleLogger<LogSeverity::Warning>& SimpleLogger<LogSeverity::Warning>::Get()
54 {
55 static SimpleLogger<LogSeverity::Warning> logger;
56 return logger;
57 }
58
59 template<>
Get()60 SimpleLogger<LogSeverity::Error>& SimpleLogger<LogSeverity::Error>::Get()
61 {
62 static SimpleLogger<LogSeverity::Error> logger;
63 return logger;
64 }
65
66 template<>
Get()67 SimpleLogger<LogSeverity::Fatal>& SimpleLogger<LogSeverity::Fatal>::Get()
68 {
69 static SimpleLogger<LogSeverity::Fatal> logger;
70 return logger;
71 }
72
SetLogFilter(LogSeverity level)73 void SetLogFilter(LogSeverity level)
74 {
75 SimpleLogger<LogSeverity::Trace>::Get().Enable(false);
76 SimpleLogger<LogSeverity::Debug>::Get().Enable(false);
77 SimpleLogger<LogSeverity::Info>::Get().Enable(false);
78 SimpleLogger<LogSeverity::Warning>::Get().Enable(false);
79 SimpleLogger<LogSeverity::Error>::Get().Enable(false);
80 SimpleLogger<LogSeverity::Fatal>::Get().Enable(false);
81 switch (level)
82 {
83 case LogSeverity::Trace:
84 SimpleLogger<LogSeverity::Trace>::Get().Enable(true);
85 ARMNN_FALLTHROUGH;
86 case LogSeverity::Debug:
87 SimpleLogger<LogSeverity::Debug>::Get().Enable(true);
88 ARMNN_FALLTHROUGH;
89 case LogSeverity::Info:
90 SimpleLogger<LogSeverity::Info>::Get().Enable(true);
91 ARMNN_FALLTHROUGH;
92 case LogSeverity::Warning:
93 SimpleLogger<LogSeverity::Warning>::Get().Enable(true);
94 ARMNN_FALLTHROUGH;
95 case LogSeverity::Error:
96 SimpleLogger<LogSeverity::Error>::Get().Enable(true);
97 ARMNN_FALLTHROUGH;
98 case LogSeverity::Fatal:
99 SimpleLogger<LogSeverity::Fatal>::Get().Enable(true);
100 break;
101 default:
102 ARMNN_ASSERT(false);
103 }
104 }
105
106 class StandardOutputColourSink : public LogSink
107 {
108 public:
StandardOutputColourSink(LogSeverity level=LogSeverity::Info)109 StandardOutputColourSink(LogSeverity level = LogSeverity::Info)
110 : m_Level(level)
111 {
112 }
113
Consume(const std::string & s)114 void Consume(const std::string& s) override
115 {
116 std::cout << GetColour(m_Level) << s << ResetColour() << std::endl;
117 }
118
119 private:
ResetColour()120 std::string ResetColour()
121 {
122 return "\033[0m";
123 }
124
GetColour(LogSeverity level)125 std::string GetColour(LogSeverity level)
126 {
127 switch(level)
128 {
129 case LogSeverity::Trace:
130 return "\033[35m";
131 case LogSeverity::Debug:
132 return "\033[32m";
133 case LogSeverity::Info:
134 return "\033[0m";
135 case LogSeverity::Warning:
136 return "\033[33m";
137 case LogSeverity::Error:
138 return "\033[31m";
139 case LogSeverity::Fatal:
140 return "\033[41;30m";
141
142 default:
143 return "\033[0m";
144 }
145 }
146 LogSeverity m_Level;
147 };
148
149 class DebugOutputSink : public LogSink
150 {
151 public:
Consume(const std::string & s)152 void Consume(const std::string& s) override
153 {
154 IgnoreUnused(s);
155 #if defined(_MSC_VER)
156 OutputDebugString(s.c_str());
157 OutputDebugString("\n");
158 #elif defined(__ANDROID__)
159 __android_log_write(ANDROID_LOG_DEBUG, "armnn", s.c_str());
160 #else
161 IgnoreUnused(s);
162 #endif
163 }
164 };
165
166 template<LogSeverity Level>
SetLoggingSinks(bool standardOut,bool debugOut,bool coloured)167 inline void SetLoggingSinks(bool standardOut, bool debugOut, bool coloured)
168 {
169 SimpleLogger<Level>::Get().RemoveAllSinks();
170
171 if (standardOut)
172 {
173 if (coloured)
174 {
175 SimpleLogger<Level>::Get().AddSink(
176 std::make_shared<StandardOutputColourSink>(Level));
177 } else
178 {
179 SimpleLogger<Level>::Get().AddSink(
180 std::make_shared<StandardOutputSink>());
181 }
182 }
183
184 if (debugOut)
185 {
186 SimpleLogger<Level>::Get().AddSink(
187 std::make_shared<DebugOutputSink>());
188 }
189 }
190
SetAllLoggingSinks(bool standardOut,bool debugOut,bool coloured)191 void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured)
192 {
193 SetLoggingSinks<LogSeverity::Trace>(standardOut, debugOut, coloured);
194 SetLoggingSinks<LogSeverity::Debug>(standardOut, debugOut, coloured);
195 SetLoggingSinks<LogSeverity::Info>(standardOut, debugOut, coloured);
196 SetLoggingSinks<LogSeverity::Warning>(standardOut, debugOut, coloured);
197 SetLoggingSinks<LogSeverity::Error>(standardOut, debugOut, coloured);
198 SetLoggingSinks<LogSeverity::Fatal>(standardOut, debugOut, coloured);
199 }
200
201 } //namespace armnn
202