• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <iostream>
9 #include <memory>
10 #include <sstream>
11 #include <vector>
12 
13 namespace arm
14 {
15 
16 namespace pipe
17 {
18 
19 #if defined(__clang__) &&((__clang_major__>=3)||(__clang_major__==3 && __clang_minor__ >= 5))
20 #   define ARM_PIPE_FALLTHROUGH [[clang::fallthrough]]
21 #elif defined(__GNUC__) && (__GNUC__ >= 7)
22 #   define ARM_PIPE_FALLTHROUGH __attribute__((fallthrough))
23 #else
24 #   define ARM_PIPE_FALLTHROUGH ((void)0)
25 #endif
26 
27 enum class LogSeverity
28 {
29     Trace,
30     Debug,
31     Info,
32     Warning,
33     Error,
34     Fatal
35 };
36 
LevelToString(LogSeverity level)37 inline std::string LevelToString(LogSeverity level)
38 {
39     switch(level)
40     {
41         case LogSeverity::Trace:
42             return "Trace";
43         case LogSeverity::Debug:
44             return "Debug";
45         case LogSeverity::Info:
46             return "Info";
47         case LogSeverity::Warning:
48             return "Warning";
49         case LogSeverity::Error:
50             return "Error";
51         case LogSeverity::Fatal:
52             return "Fatal";
53         default:
54             return "Log";
55     }
56 }
57 
58 /// Configures the logging behaviour of the ARMNN library.
59 ///     printToStandardOutput: Set to true if log messages should be printed to the standard output.
60 ///     printToDebugOutput: Set to true if log messages be printed to a platform-specific debug output
61 ///       (where supported).
62 ///     severity: All log messages that are at this severity level or higher will be printed, others will be ignored.
63 void ConfigureLogging(bool printToStandardOutput, bool printToDebugOutput, LogSeverity severity);
64 
65 class LogSink
66 {
67 public:
~LogSink()68     virtual ~LogSink(){};
69 
70     virtual void Consume(const std::string&) = 0;
71 private:
72 
73 };
74 
75 class StandardOutputSink : public LogSink
76 {
77 public:
Consume(const std::string & s)78     void Consume(const std::string& s) override
79     {
80         std::cout << s << std::endl;
81     }
82 };
83 
84 struct ScopedRecord
85 {
ScopedRecordarm::pipe::ScopedRecord86     ScopedRecord(const std::vector<std::shared_ptr<LogSink>>& sinks, LogSeverity level, bool enabled)
87     : m_LogSinks(sinks)
88     , m_Enabled(enabled)
89     {
90         if (enabled)
91         {
92             m_Os << LevelToString(level) << ": ";
93         }
94     }
95 
~ScopedRecordarm::pipe::ScopedRecord96     ~ScopedRecord()
97     {
98         if (m_Enabled)
99         {
100             for (auto sink : m_LogSinks)
101             {
102                 if (sink)
103                 {
104                     sink->Consume(m_Os.str());
105                 }
106             }
107         }
108     }
109 
110     ScopedRecord(const ScopedRecord&) = delete;
111     ScopedRecord& operator=(const ScopedRecord&) = delete;
112     ScopedRecord& operator=(ScopedRecord&&) = delete;
113 
114     ScopedRecord(ScopedRecord&& other) = default;
115 
116     template<typename Streamable>
operator <<arm::pipe::ScopedRecord117     ScopedRecord& operator<<(const Streamable& s)
118     {
119         if (m_Enabled)
120         {
121             m_Os << s;
122         }
123         return (*this);
124     }
125 
126 private:
127     const std::vector<std::shared_ptr<LogSink>>& m_LogSinks;
128     std::ostringstream m_Os;
129     bool m_Enabled;
130 };
131 
132 template<LogSeverity Level>
133 class SimpleLogger
134 {
135 public:
SimpleLogger()136     SimpleLogger()
137         : m_Sinks{std::make_shared<StandardOutputSink>()}
138         , m_Enable(true)
139     {
140     }
141 
Get()142     static SimpleLogger<Level>& Get()
143     {
144         static SimpleLogger<Level> logger;
145         return logger;
146     }
147 
Enable(bool enable=true)148     void Enable(bool enable = true)
149     {
150         m_Enable = enable;
151     }
152 
StartNewRecord()153     ScopedRecord StartNewRecord()
154     {
155         ScopedRecord record(m_Sinks, Level, m_Enable);
156         return record;
157     }
158 
RemoveAllSinks()159     void RemoveAllSinks()
160     {
161         m_Sinks.clear();
162     }
163 
AddSink(std::shared_ptr<LogSink> sink)164     void AddSink(std::shared_ptr<LogSink> sink)
165     {
166         m_Sinks.push_back(sink);
167     }
168 private:
169     std::vector<std::shared_ptr<LogSink>> m_Sinks;
170     bool m_Enable;
171 };
172 
173 void SetLogFilter(LogSeverity level);
174 
175 void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured);
176 
177 enum class BoostLogSeverityMapping
178 {
179     trace,
180     debug,
181     info,
182     warning,
183     error,
184     fatal
185 };
186 
ConvertLogSeverity(BoostLogSeverityMapping severity)187 constexpr LogSeverity ConvertLogSeverity(BoostLogSeverityMapping severity)
188 {
189     return static_cast<LogSeverity>(severity);
190 }
191 
192 
193 #define ARM_PIPE_LOG(severity) \
194     arm::pipe::SimpleLogger<ConvertLogSeverity(arm::pipe::BoostLogSeverityMapping::severity)>::Get().StartNewRecord()
195 
196 } // namespace pipe
197 } // namespace arm
198