Line data Source code
1 : /** \file software_log.hpp
2 : * \brief The MagAO-X logger software_log log type.
3 : * \author Jared R. Males (jaredmales@gmail.com)
4 : *
5 : * \ingroup logger_types_files
6 : *
7 : * History:
8 : * - 2018-08-18 created by JRM
9 : */
10 : #ifndef logger_types_software_log_hpp
11 : #define logger_types_software_log_hpp
12 :
13 : #include <source_location>
14 :
15 : #include "generated/software_log_generated.h"
16 : #include "flatbuffer_log.hpp"
17 :
18 : namespace MagAOX
19 : {
20 : namespace logger
21 : {
22 :
23 : /// Base class for software logs
24 : /** Such logs are used to log software status, warnings, and errors. Does not have defaultLevel, so this can not be used
25 : * as a log type in logger.
26 : *
27 : * \includedoc sw_logs.dox.inc
28 : *
29 : *
30 : * \ingroup logger_types__basic
31 : */
32 : struct software_log : public flatbuffer_log
33 : {
34 : /// The event code
35 : static const flatlogs::eventCodeT eventCode = eventCodes::SOFTWARE_LOG;
36 :
37 : /// The type of the message
38 : struct messageT : public fbMessage
39 : {
40 : /// C'tor with full specification.
41 9 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
42 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
43 : const int32_t errnoCode, ///< [in] The errno code at the time of the log entry. Only errno should be
44 : ///< passed here, so strerror can be used later.
45 : const int32_t otherCode, ///< [in] Some other error code, such as a return value or library code.
46 : const char *explanation ///< [in] explanatory text about the software event
47 : )
48 9 : {
49 9 : auto _file = builder.CreateString( file );
50 9 : auto _expl = builder.CreateString( explanation );
51 :
52 9 : auto gs = CreateSoftware_log_fb( builder, _file, line, errnoCode, otherCode, _expl );
53 9 : builder.Finish( gs );
54 9 : }
55 :
56 : /// C'tor with full specification, overloaded for a std::string in explanation.
57 : /** \overload
58 : */
59 6 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
60 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
61 : const int32_t errnoCode, ///< [in] The errno code at the time of the log entry. Only errno should be
62 : ///< passed here, so strerror can be used later.
63 : const int32_t otherCode, ///< [in] Some other error code, such as a return value or library code.
64 : const std::string &explanation ///< [in] explanatory text about the software event
65 : )
66 6 : {
67 6 : auto _file = builder.CreateString( file );
68 6 : auto _expl = builder.CreateString( explanation );
69 :
70 6 : auto gs = CreateSoftware_log_fb( builder, _file, line, errnoCode, otherCode, _expl );
71 6 : builder.Finish( gs );
72 6 : }
73 :
74 : /// C'tor for errno only -- code explanation can be looked up later.
75 1 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
76 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
77 : const int32_t errnoCode ///< [in] The errno code at the time of the log entry. Only errno should be
78 : ///< passed here, so strerror can be used later.
79 : )
80 1 : {
81 1 : auto _file = builder.CreateString( file );
82 :
83 1 : auto gs = CreateSoftware_log_fb( builder, _file, line, errnoCode, 0, 0 );
84 1 : builder.Finish( gs );
85 1 : }
86 :
87 : /// C'tor for errno with additional explanation.
88 10 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
89 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
90 : const int32_t errnoCode, ///< [in] The errno code at the time of the log entry. Only errno should be
91 : ///< passed here, so strerror can be used later.
92 : const char *explanation ///< [in] explanatory text about the software event
93 : )
94 10 : {
95 10 : auto _file = builder.CreateString( file );
96 10 : auto _expl = builder.CreateString( explanation );
97 :
98 10 : auto gs = CreateSoftware_log_fb( builder, _file, line, errnoCode, 0, _expl );
99 10 : builder.Finish( gs );
100 10 : }
101 :
102 : /// C'tor for errno with additional explanation, std::string overload.
103 1 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
104 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
105 : const int32_t errnoCode, ///< [in] The errno code at the time of the log entry. Only errno should be
106 : ///< passed here, so strerror can be used later.
107 : const std::string &explanation ///< [in] explanatory text about the software event
108 : )
109 1 : {
110 1 : auto _file = builder.CreateString( file );
111 1 : auto _expl = builder.CreateString( explanation );
112 :
113 1 : auto gs = CreateSoftware_log_fb( builder, _file, line, errnoCode, 0, _expl );
114 1 : builder.Finish( gs );
115 1 : }
116 :
117 : /// C'tor with no codes, just the explanation.
118 141 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
119 : const uint32_t line, ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
120 : const std::string &explanation ///< [in] explanatory text about the software event
121 : )
122 141 : {
123 141 : auto _file = builder.CreateString( file );
124 141 : auto _expl = builder.CreateString( explanation );
125 :
126 141 : auto gs = CreateSoftware_log_fb( builder, _file, line, 0, 0, _expl );
127 141 : builder.Finish( gs );
128 141 : }
129 :
130 : /// C'tor for a trace log, only the file and line.
131 13 : messageT( const char *file, ///< [in] The file of the error, should always be \c \_\_FILE\_\_
132 : const uint32_t line ///< [in] The line number of the error, should always be \c \_\_LINE\_\_
133 : )
134 13 : {
135 13 : auto _file = builder.CreateString( file );
136 :
137 13 : auto gs = CreateSoftware_log_fb( builder, _file, line, 0, 0, 0 );
138 13 : builder.Finish( gs );
139 13 : }
140 :
141 : // constructors using source location
142 :
143 1 : messageT( const int32_t errnoCode, /**< [in] The errno code at the time of the log entry. Only
144 : errno should be passed here, so strerror can be used later.*/
145 : const int32_t otherCode, /**< [in] Some other error code, such as a return value or
146 : library code. */
147 : const char *explanation, /**< [in] explanatory text about the software event*/
148 : const std::source_location &loc /**< [in] [opt] source location */
149 1 : = std::source_location::current() )
150 1 : {
151 1 : auto _file = builder.CreateString( loc.file_name() );
152 1 : auto _expl = builder.CreateString( explanation );
153 :
154 1 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), errnoCode, otherCode, _expl );
155 1 : builder.Finish( gs );
156 1 : }
157 :
158 1 : messageT( const int32_t errnoCode, /**< [in] The errno code at the time of the log entry. Only
159 : errno should be passed here, so strerror can be used later.*/
160 : const int32_t otherCode, /**< [in] Some other error code, such as a return value or
161 : library code. */
162 : const std::string &explanation, /**< [in] explanatory text about the software event*/
163 : const std::source_location &loc /**< [in] [opt] source location */
164 1 : = std::source_location::current() )
165 1 : {
166 1 : auto _file = builder.CreateString( loc.file_name() );
167 1 : auto _expl = builder.CreateString( explanation );
168 :
169 1 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), errnoCode, otherCode, _expl );
170 1 : builder.Finish( gs );
171 1 : }
172 :
173 : /// C'tor for errno only -- code explanation can be looked up later.
174 1 : messageT( const int32_t errnoCode, /**< [in] The errno code at the time of the log entry. Only errno should be
175 : passed here, so strerror can be used later.*/
176 : const std::source_location &loc /**< [in] [opt] source location */
177 1 : = std::source_location::current() )
178 1 : {
179 1 : auto _file = builder.CreateString( loc.file_name() );
180 :
181 1 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), errnoCode, 0, 0 );
182 1 : builder.Finish( gs );
183 1 : }
184 :
185 : /// C'tor for errno with additional explanation.
186 1 : messageT( const int32_t errnoCode, /**< [in] The errno code at the time of the log entry. Only errno should be
187 : passed here, so strerror can be used later.*/
188 : const char *explanation, ///< [in] explanatory text about the software event
189 : const std::source_location &loc /**< [in] [opt] source location */
190 1 : = std::source_location::current() )
191 1 : {
192 1 : auto _file = builder.CreateString( loc.file_name() );
193 1 : auto _expl = builder.CreateString( explanation );
194 :
195 1 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), errnoCode, 0, _expl );
196 1 : builder.Finish( gs );
197 1 : }
198 :
199 : /// C'tor for errno with additional explanation.
200 3 : messageT( const int32_t errnoCode, /**< [in] The errno code at the time of the log entry. Only errno should be
201 : passed here, so strerror can be used later.*/
202 : const std::string &explanation, ///< [in] explanatory text about the software event
203 : const std::source_location &loc /**< [in] [opt] source location */
204 5 : = std::source_location::current() )
205 3 : {
206 3 : auto _file = builder.CreateString( loc.file_name() );
207 3 : auto _expl = builder.CreateString( explanation );
208 :
209 3 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), errnoCode, 0, _expl );
210 3 : builder.Finish( gs );
211 3 : }
212 :
213 : /// C'tor with no codes, just the explanation.
214 44 : messageT( const char *explanation, /**< [in] explanatory text about the software event */
215 : const std::source_location &loc /**< [in] [opt] source location */
216 87 : = std::source_location::current() )
217 44 : {
218 44 : auto _file = builder.CreateString( loc.file_name() );
219 44 : auto _expl = builder.CreateString( explanation );
220 :
221 44 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), 0, 0, _expl );
222 :
223 44 : builder.Finish( gs );
224 44 : }
225 :
226 : /// C'tor with no codes, just the explanation.
227 10 : messageT( const std::string &explanation, /**< [in] explanatory text about the software event */
228 : const std::source_location &loc /**< [in] [opt] source location */
229 19 : = std::source_location::current() )
230 10 : {
231 10 : auto _file = builder.CreateString( loc.file_name() );
232 10 : auto _expl = builder.CreateString( explanation );
233 :
234 10 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), 0, 0, _expl );
235 :
236 10 : builder.Finish( gs );
237 10 : }
238 :
239 : /// C'tor for a trace log, only the file and line.
240 5 : messageT( const std::source_location &loc /**< [in] [opt] source location */
241 9 : = std::source_location::current() )
242 5 : {
243 5 : auto _file = builder.CreateString( loc.file_name() );
244 :
245 5 : auto gs = CreateSoftware_log_fb( builder, _file, loc.line(), 0, 0, 0 );
246 5 : builder.Finish( gs );
247 5 : }
248 : };
249 :
250 15 : static bool verify( flatlogs::bufferPtrT &logBuff, ///< [in] Buffer containing the flatbuffer serialized message.
251 : flatlogs::msgLenT len ///< [in] length of msgBuffer.
252 : )
253 : {
254 15 : auto verifier = flatbuffers::Verifier( static_cast<uint8_t *>( flatlogs::logHeader::messageBuffer( logBuff ) ),
255 15 : static_cast<size_t>( len ) );
256 30 : return VerifySoftware_log_fbBuffer( verifier );
257 : }
258 :
259 : /// Get the message formatted for human consumption.
260 229 : static std::string msgString( void *msgBuffer, /**< [in] Buffer containing the flatbuffer serialized message.*/
261 : flatlogs::msgLenT len /**< [in] [unused] length of msgBuffer.*/
262 : )
263 : {
264 :
265 : static_cast<void>( len );
266 :
267 229 : auto rgs = GetSoftware_log_fb( msgBuffer );
268 :
269 229 : std::string ret = "SW FILE: ";
270 229 : if( rgs->file() != nullptr )
271 : {
272 229 : ret += rgs->file()->c_str();
273 : }
274 : else
275 : {
276 0 : ret += "????";
277 : }
278 :
279 229 : ret += std::format( " LINE: {}", rgs->line() );
280 :
281 229 : if( rgs->errnoCode() )
282 : {
283 17 : ret += std::format( " ERRNO: {} [{}]", rgs->errnoCode(), rgs->errnoCode() );
284 : }
285 229 : if( rgs->otherCode() )
286 : {
287 5 : ret += std::format( " CODE: {}", rgs->otherCode() );
288 5 : if( rgs->explanation() )
289 : {
290 5 : ret += std::format( " [{}]", rgs->explanation()->c_str() );
291 : }
292 : }
293 224 : else if( rgs->explanation() )
294 : {
295 208 : ret += " >";
296 208 : ret += rgs->explanation()->c_str();
297 : }
298 229 : return ret;
299 0 : }
300 :
301 : /// Get an empty logMetaDetail because meta data doesn't make sense for this log
302 : /**
303 : * \returns an empty logMetaDetail
304 : */
305 1 : static logMetaDetail getAccessor( const std::string &member /**< [in] the name of the member */ )
306 : {
307 : static_cast<void>( member );
308 :
309 1 : std::cerr << "meta data doesn't make sense for software_log.\n";
310 1 : return logMetaDetail();
311 : }
312 : };
313 :
314 : /// Software EMERGENCY log entry
315 : /** This should only be used for a system-wide emergency requiring operator or automatic shutdown. Not for a process
316 : * specific problem.
317 : * \includedoc sw_logs.dox.inc
318 : * \ingroup logger_types
319 : */
320 : struct software_emergency : public software_log
321 : {
322 : /// The default level
323 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_EMERGENCY;
324 : };
325 :
326 : /// Software ALERT log entry
327 : /** This should only be used for a system-wide emergency requiring operator or automatic action. Not for a process
328 : * specific problem.
329 : * \includedoc sw_logs.dox.inc
330 : * \ingroup logger_types
331 : */
332 : struct software_alert : public software_log
333 : {
334 : /// The default level
335 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_ALERT;
336 : };
337 :
338 : /// Software CRITICAL log entry
339 : /** This should only be used if the process is going to shutdown.
340 : * \includedoc sw_logs.dox.inc
341 : * \ingroup logger_types
342 : */
343 : struct software_critical : public software_log
344 : {
345 : /// The default level
346 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_CRITICAL;
347 : };
348 :
349 : /// Software ERR log entry
350 : /** Used to record and error that the process will attempt to recover from.
351 : * \includedoc sw_logs.dox.inc
352 : * \ingroup logger_types
353 : */
354 : struct software_error : public software_log
355 : {
356 : /// The default level
357 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_ERROR;
358 : };
359 :
360 : /// Software WARN log entry
361 : /** Used to record an abnormal condition.
362 : * \includedoc sw_logs.dox.inc
363 : * \ingroup logger_types
364 : */
365 : struct software_warning : public software_log
366 : {
367 : /// The default level
368 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_WARNING;
369 : };
370 :
371 : /// Software NOTICE log entry
372 : /** Used to record a normal but signficant event or condition.
373 : * \includedoc sw_logs.dox.inc
374 : * \ingroup logger_types
375 : */
376 : struct software_notice : public software_log
377 : {
378 : /// The default level
379 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_NOTICE;
380 : };
381 :
382 : /// Software INFO log entry
383 : /** \includedoc sw_logs.dox.inc
384 : * Used to record a normal event or condition. This is the lowest priority used in normal operations.
385 : * \ingroup logger_types
386 : */
387 : struct software_info : public software_log
388 : {
389 : /// The default level
390 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_INFO;
391 : };
392 :
393 : /// Software DEBUG log entry
394 : /** \includedoc sw_logs.dox.inc
395 : * \ingroup logger_types
396 : */
397 : struct software_debug : public software_log
398 : {
399 : /// The default level
400 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_DEBUG;
401 : };
402 :
403 : /// Software DEBUG2 log entry
404 : /** \includedoc sw_logs.dox.inc
405 : * \ingroup logger_types
406 : */
407 : struct software_debug2 : public software_log
408 : {
409 : /// The default level
410 : static const flatlogs::logPrioT defaultLevel = flatlogs::logPrio::LOG_DEBUG2;
411 : };
412 :
413 : } // namespace logger
414 : } // namespace MagAOX
415 :
416 : #endif // logger_types_software_log_hpp
|