• 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 enum class LogSeverity
20 {
21     Trace,
22     Debug,
23     Info,
24     Warning,
25     Error,
26     Fatal
27 };
28 
LevelToString(LogSeverity level)29 inline std::string LevelToString(LogSeverity level)
30 {
31     switch(level)
32     {
33         case LogSeverity::Trace:
34             return "Trace";
35         case LogSeverity::Debug:
36             return "Debug";
37         case LogSeverity::Info:
38             return "Info";
39         case LogSeverity::Warning:
40             return "Warning";
41         case LogSeverity::Error:
42             return "Error";
43         case LogSeverity::Fatal:
44             return "Fatal";
45         default:
46             return "Log";
47     }
48 }
49 
50 class LogSink
51 {
52 public:
~LogSink()53     virtual ~LogSink(){};
54 
55     virtual void Consume(const std::string&) = 0;
56 private:
57 
58 };
59 
60 class StandardOutputSink : public LogSink
61 {
62 public:
Consume(const std::string & s)63     void Consume(const std::string& s) override
64     {
65         std::cout << s << std::endl;
66     }
67 };
68 
69 struct ScopedRecord
70 {
ScopedRecordarm::pipe::ScopedRecord71     ScopedRecord(const std::vector<std::shared_ptr<LogSink>>& sinks, LogSeverity level, bool enabled)
72     : m_LogSinks(sinks)
73     , m_Enabled(enabled)
74     {
75         if (enabled)
76         {
77             m_Os << LevelToString(level) << ": ";
78         }
79     }
80 
~ScopedRecordarm::pipe::ScopedRecord81     ~ScopedRecord()
82     {
83         if (m_Enabled)
84         {
85             for (auto sink : m_LogSinks)
86             {
87                 if (sink)
88                 {
89                     sink->Consume(m_Os.str());
90                 }
91             }
92         }
93     }
94 
95     ScopedRecord(const ScopedRecord&) = delete;
96     ScopedRecord& operator=(const ScopedRecord&) = delete;
97     ScopedRecord& operator=(ScopedRecord&&) = delete;
98 
99     ScopedRecord(ScopedRecord&& other) = default;
100 
101     template<typename Streamable>
operator <<arm::pipe::ScopedRecord102     ScopedRecord& operator<<(const Streamable& s)
103     {
104         if (m_Enabled)
105         {
106             m_Os << s;
107         }
108         return (*this);
109     }
110 
111 private:
112     const std::vector<std::shared_ptr<LogSink>>& m_LogSinks;
113     std::ostringstream m_Os;
114     bool m_Enabled;
115 };
116 
117 template<LogSeverity Level>
118 class SimpleLogger
119 {
120 public:
SimpleLogger()121     SimpleLogger()
122         : m_Sinks{std::make_shared<StandardOutputSink>()}
123         , m_Enable(true)
124     {
125     }
126 
Get()127     static SimpleLogger& Get()
128     {
129         static SimpleLogger<Level> logger;
130         return logger;
131     }
132 
Enable(bool enable=true)133     void Enable(bool enable = true)
134     {
135         m_Enable = enable;
136     }
137 
StartNewRecord()138     ScopedRecord StartNewRecord()
139     {
140         ScopedRecord record(m_Sinks, Level, m_Enable);
141         return record;
142     }
143 
RemoveAllSinks()144     void RemoveAllSinks()
145     {
146         m_Sinks.clear();
147     }
148 
AddSink(std::shared_ptr<LogSink> sink)149     void AddSink(std::shared_ptr<LogSink> sink)
150     {
151         m_Sinks.push_back(sink);
152     }
153 private:
154     std::vector<std::shared_ptr<LogSink>> m_Sinks;
155     bool m_Enable;
156 };
157 
158 void SetLogFilter(LogSeverity level);
159 
160 void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured);
161 
162 enum class BoostLogSeverityMapping
163 {
164     trace,
165     debug,
166     info,
167     warning,
168     error,
169     fatal
170 };
171 
ConvertLogSeverity(BoostLogSeverityMapping severity)172 constexpr LogSeverity ConvertLogSeverity(BoostLogSeverityMapping severity)
173 {
174     return static_cast<LogSeverity>(severity);
175 }
176 
177 
178 #define ARM_PIPE_LOG(severity) \
179     arm::pipe::SimpleLogger<ConvertLogSeverity(arm::pipe::BoostLogSeverityMapping::severity)>::Get().StartNewRecord()
180 
181 } // namespace pipe
182 } // namespace arm
183