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