blob: 7a265d552df2b7a4c33249d07a4f75850b0273c8 [file] [log] [blame]
Jim Flynnbbfe6032020-07-20 16:57:44 +01001//
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
13namespace arm
14{
15
16namespace pipe
17{
18
Jim Flynn6c9f17d2022-03-10 23:13:01 +000019#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
Jim Flynnbbfe6032020-07-20 16:57:44 +010027enum class LogSeverity
28{
29 Trace,
30 Debug,
31 Info,
32 Warning,
33 Error,
34 Fatal
35};
36
37inline 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
Jim Flynn6c9f17d2022-03-10 23:13:01 +000058/// 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.
63void ConfigureLogging(bool printToStandardOutput, bool printToDebugOutput, LogSeverity severity);
64
Jim Flynnbbfe6032020-07-20 16:57:44 +010065class LogSink
66{
67public:
68 virtual ~LogSink(){};
69
70 virtual void Consume(const std::string&) = 0;
71private:
72
73};
74
75class StandardOutputSink : public LogSink
76{
77public:
78 void Consume(const std::string& s) override
79 {
80 std::cout << s << std::endl;
81 }
82};
83
84struct ScopedRecord
85{
86 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
96 ~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>
117 ScopedRecord& operator<<(const Streamable& s)
118 {
119 if (m_Enabled)
120 {
121 m_Os << s;
122 }
123 return (*this);
124 }
125
126private:
127 const std::vector<std::shared_ptr<LogSink>>& m_LogSinks;
128 std::ostringstream m_Os;
129 bool m_Enabled;
130};
131
132template<LogSeverity Level>
133class SimpleLogger
134{
135public:
136 SimpleLogger()
137 : m_Sinks{std::make_shared<StandardOutputSink>()}
138 , m_Enable(true)
139 {
140 }
141
Jim Flynn6c9f17d2022-03-10 23:13:01 +0000142 static SimpleLogger<Level>& Get()
Jim Flynnbbfe6032020-07-20 16:57:44 +0100143 {
144 static SimpleLogger<Level> logger;
145 return logger;
146 }
147
148 void Enable(bool enable = true)
149 {
150 m_Enable = enable;
151 }
152
153 ScopedRecord StartNewRecord()
154 {
155 ScopedRecord record(m_Sinks, Level, m_Enable);
156 return record;
157 }
158
159 void RemoveAllSinks()
160 {
161 m_Sinks.clear();
162 }
163
164 void AddSink(std::shared_ptr<LogSink> sink)
165 {
166 m_Sinks.push_back(sink);
167 }
168private:
169 std::vector<std::shared_ptr<LogSink>> m_Sinks;
170 bool m_Enable;
171};
172
173void SetLogFilter(LogSeverity level);
174
175void SetAllLoggingSinks(bool standardOut, bool debugOut, bool coloured);
176
177enum class BoostLogSeverityMapping
178{
179 trace,
180 debug,
181 info,
182 warning,
183 error,
184 fatal
185};
186
187constexpr 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