Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : #pragma once
4 :
5 : #include "logger/EntryBuffer.h"
6 : #include "logger/EntrySerializer.h"
7 : #include "logger/IEntryOutput.h"
8 : #include "logger/ILoggerListener.h"
9 : #include "logger/ILoggerTime.h"
10 :
11 : #include <etl/intrusive_list.h>
12 : #include <etl/span.h>
13 : #include <util/logger/IComponentMapping.h>
14 : #include <util/logger/ILoggerOutput.h>
15 :
16 : namespace logger
17 : {
18 : template<
19 : class Lock,
20 : uint8_t MaxEntrySize = 64,
21 : class T = uint16_t,
22 : class E = uint32_t,
23 : class Timestamp = uint32_t,
24 : class ReadOnlyPredicate = SectionPredicate>
25 : class BufferedLoggerOutput : public ::util::logger::ILoggerOutput
26 : {
27 : public:
28 : using EntryIndexType = E;
29 : using EntryRefType = typename EntryBuffer<MaxEntrySize, E>::EntryRef;
30 : using TimestampType = Timestamp;
31 :
32 : BufferedLoggerOutput(
33 : ::util::logger::IComponentMapping& componentMapping,
34 : ILoggerTime<Timestamp>& timestamp,
35 : ::etl::span<uint8_t> outputBuffer);
36 : BufferedLoggerOutput(
37 : ::util::logger::IComponentMapping& componentMapping,
38 : ILoggerTime<Timestamp>& timestamp,
39 : ::etl::span<uint8_t> outputBuffer,
40 : ReadOnlyPredicate const& readOnlyPredicate);
41 :
42 : void addListener(ILoggerListener& listener);
43 : void removeListener(ILoggerListener& listener);
44 :
45 : bool outputEntry(IEntryOutput<E, Timestamp>& output, EntryRefType& entryRef) const;
46 :
47 : void logOutput(
48 : ::util::logger::ComponentInfo const& componentInfo,
49 : ::util::logger::LevelInfo const& levelInfo,
50 : char const* str,
51 : va_list ap) override;
52 :
53 : private:
54 : class EntryOutputAdapter : public IEntrySerializerCallback<Timestamp>
55 : {
56 : public:
57 : EntryOutputAdapter(
58 : ::util::logger::IComponentMapping& componentMapping,
59 : E entryIndex,
60 : IEntryOutput<E, Timestamp>& output);
61 :
62 : void onEntry(
63 : Timestamp timestamp,
64 : uint8_t componentIndex,
65 : ::util::logger::Level level,
66 : char const* str,
67 : ::util::format::IPrintfArgumentReader& argReader) override;
68 :
69 : private:
70 : ::util::logger::IComponentMapping& _parentComponentMapping;
71 : E _entryIndex;
72 : IEntryOutput<E, Timestamp>& _output;
73 : };
74 :
75 : ::util::logger::IComponentMapping& _componentMapping;
76 : ILoggerTime<Timestamp>& _timestamp;
77 : EntryBuffer<MaxEntrySize, E> _entryBuffer;
78 : EntrySerializer<T, Timestamp, ReadOnlyPredicate> _entrySerializer;
79 : ::etl::intrusive_list<ILoggerListener, ::etl::bidirectional_link<0>> _listeners;
80 : };
81 :
82 : namespace declare
83 : {
84 :
85 : template<
86 : uint32_t BufferSize,
87 : class Lock,
88 : uint8_t MaxEntrySize = 64,
89 : class T = uint16_t,
90 : class E = uint32_t,
91 : class Timestamp = uint32_t,
92 : class ReadOnlyPredicate = SectionPredicate>
93 : class BufferedLoggerOutput
94 : : public ::logger::BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>
95 : {
96 : public:
97 : BufferedLoggerOutput(
98 : ::util::logger::IComponentMapping& componentMapping, ILoggerTime<Timestamp>& timestamp);
99 : BufferedLoggerOutput(
100 : ::util::logger::IComponentMapping& componentMapping,
101 : ILoggerTime<Timestamp>& timestamp,
102 : ReadOnlyPredicate const readOnlyPredicate);
103 :
104 : private:
105 : uint8_t _buffer[BufferSize];
106 : };
107 :
108 : template<
109 : uint32_t BufferSize,
110 : class Lock,
111 : uint8_t MaxEntrySize,
112 : class T,
113 : class E,
114 : class Timestamp,
115 : class ReadOnlyPredicate>
116 1 : inline BufferedLoggerOutput<BufferSize, Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::
117 : BufferedLoggerOutput(
118 : ::util::logger::IComponentMapping& componentMapping, ILoggerTime<Timestamp>& timestamp)
119 : : ::logger::BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>(
120 1 : componentMapping, timestamp, _buffer)
121 4097 : , _buffer()
122 1 : {}
123 :
124 : template<
125 : uint32_t BufferSize,
126 : class Lock,
127 : uint8_t MaxEntrySize,
128 : class T,
129 : class E,
130 : class Timestamp,
131 : class ReadOnlyPredicate>
132 1 : inline BufferedLoggerOutput<BufferSize, Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::
133 : BufferedLoggerOutput(
134 : ::util::logger::IComponentMapping& componentMapping,
135 : ILoggerTime<Timestamp>& timestamp,
136 : ReadOnlyPredicate const readOnlyPredicate)
137 : : ::logger::BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>(
138 1 : componentMapping, timestamp, _buffer, readOnlyPredicate)
139 21 : , _buffer()
140 1 : {}
141 :
142 : } // namespace declare
143 :
144 : template<
145 : class Lock,
146 : uint8_t MaxEntrySize,
147 : class T,
148 : class E,
149 : class Timestamp,
150 : class ReadOnlyPredicate>
151 1 : BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::BufferedLoggerOutput(
152 : ::util::logger::IComponentMapping& componentMapping,
153 : ILoggerTime<Timestamp>& timestamp,
154 : ::etl::span<uint8_t> const outputBuffer)
155 : : ::util::logger::ILoggerOutput()
156 1 : , _componentMapping(componentMapping)
157 1 : , _timestamp(timestamp)
158 1 : , _entryBuffer(outputBuffer)
159 1 : , _entrySerializer(ReadOnlyPredicate())
160 2 : , _listeners()
161 1 : {}
162 :
163 : template<
164 : class Lock,
165 : uint8_t MaxEntrySize,
166 : class T,
167 : class E,
168 : class Timestamp,
169 : class ReadOnlyPredicate>
170 1 : BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::BufferedLoggerOutput(
171 : ::util::logger::IComponentMapping& componentMapping,
172 : ILoggerTime<Timestamp>& timestamp,
173 : ::etl::span<uint8_t> const outputBuffer,
174 : ReadOnlyPredicate const& readOnlyPredicate)
175 : : ::util::logger::ILoggerOutput()
176 1 : , _componentMapping(componentMapping)
177 1 : , _timestamp(timestamp)
178 1 : , _entryBuffer(outputBuffer)
179 1 : , _entrySerializer(readOnlyPredicate)
180 2 : , _listeners()
181 1 : {}
182 :
183 : template<
184 : class Lock,
185 : uint8_t MaxEntrySize,
186 : class T,
187 : class E,
188 : class Timestamp,
189 : class ReadOnlyPredicate>
190 1 : void BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::addListener(
191 : ILoggerListener& listener)
192 : {
193 1 : _listeners.push_back(listener);
194 1 : }
195 :
196 : template<
197 : class Lock,
198 : uint8_t MaxEntrySize,
199 : class T,
200 : class E,
201 : class Timestamp,
202 : class ReadOnlyPredicate>
203 1 : void BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::removeListener(
204 : ILoggerListener& listener)
205 : {
206 1 : _listeners.erase(listener);
207 1 : }
208 :
209 : template<
210 : class Lock,
211 : uint8_t MaxEntrySize,
212 : class T,
213 : class E,
214 : class Timestamp,
215 : class ReadOnlyPredicate>
216 3 : bool BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::outputEntry(
217 : IEntryOutput<E, Timestamp>& output, EntryRefType& entryRef) const
218 : {
219 : uint8_t entryBuffer[MaxEntrySize];
220 : uint32_t size;
221 : {
222 3 : Lock const lock;
223 3 : size = _entryBuffer.getNextEntry(entryBuffer, entryRef);
224 : }
225 3 : if (size > 0U)
226 : {
227 2 : EntryOutputAdapter outputAdapter(_componentMapping, entryRef.getIndex(), output);
228 :
229 2 : _entrySerializer.deserialize(::etl::span<uint8_t>(entryBuffer).first(size), outputAdapter);
230 : }
231 3 : return size > 0U;
232 : }
233 :
234 : template<
235 : class Lock,
236 : uint8_t MaxEntrySize,
237 : class T,
238 : class E,
239 : class Timestamp,
240 : class ReadOnlyPredicate>
241 2 : void BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::logOutput(
242 : ::util::logger::ComponentInfo const& componentInfo,
243 : ::util::logger::LevelInfo const& levelInfo,
244 : char const* const str,
245 : va_list ap)
246 : {
247 : uint8_t entryBuffer[MaxEntrySize];
248 2 : Timestamp const timestamp = _timestamp.getTimestamp();
249 4 : T const size = _entrySerializer.serialize(
250 2 : entryBuffer, timestamp, componentInfo.getIndex(), levelInfo.getLevel(), str, ap);
251 : {
252 2 : Lock const lock;
253 2 : _entryBuffer.addEntry(::etl::span<uint8_t>(entryBuffer).first(size));
254 : }
255 5 : for (auto& it : _listeners)
256 : {
257 1 : it.logAvailable();
258 : }
259 2 : }
260 :
261 : template<
262 : class Lock,
263 : uint8_t MaxEntrySize,
264 : class T,
265 : class E,
266 : class Timestamp,
267 : class ReadOnlyPredicate>
268 2 : BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::EntryOutputAdapter::
269 : EntryOutputAdapter(
270 : ::util::logger::IComponentMapping& componentMapping,
271 : E const entryIndex,
272 : IEntryOutput<E, Timestamp>& output)
273 : : IEntrySerializerCallback<Timestamp>()
274 2 : , _parentComponentMapping(componentMapping)
275 2 : , _entryIndex(entryIndex)
276 2 : , _output(output)
277 2 : {}
278 :
279 : template<
280 : class Lock,
281 : uint8_t MaxEntrySize,
282 : class T,
283 : class E,
284 : class Timestamp,
285 : class ReadOnlyPredicate>
286 2 : void BufferedLoggerOutput<Lock, MaxEntrySize, T, E, Timestamp, ReadOnlyPredicate>::
287 : EntryOutputAdapter::onEntry(
288 : Timestamp timestamp,
289 : uint8_t componentIndex,
290 : ::util::logger::Level level,
291 : char const* str,
292 : ::util::format::IPrintfArgumentReader& argReader)
293 : {
294 2 : _output.outputEntry(
295 : _entryIndex,
296 : timestamp,
297 2 : _parentComponentMapping.getComponentInfo(componentIndex),
298 2 : _parentComponentMapping.getLevelInfo(level),
299 : str,
300 : argReader);
301 2 : }
302 :
303 : } /* namespace logger */
|