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