le_log.h

Go to the documentation of this file.
1 /**
2  * @page c_logging Logging API
3  *
4  * @subpage le_log.h "API Reference" <br>
5  *
6  * The Legato Logging API provides a toolkit allowing code to be instrumented with error, warning,
7  * informational, and debugging messages. These messages can be turned on or off remotely and pushed or pulled
8  * from the device through a secure shell, cloud services interfaces, e-mail, SMS, etc.
9  *
10  * @section c_log_logging Logging Basics
11  *
12  * Legato's logging can be configured through this API, and there's also a command-line target
13  * @ref toolsTarget_log tool available.
14  *
15  * @subsection c_log_levels Levels
16  *
17  * Log messages are categorized according to the severity of the information being logged.
18  * A log message may be purely informational, describing something that is
19  * expected to occur from time-to-time during normal operation; or it may be a report of a fault
20  * that might have a significant negative impact on the operation of the system. To
21  * differentiate these, each log entry is associated with one of the following log levels:
22  *
23  * - @ref LE_LOG_DEBUG "DEBUG":
24  * Handy for troubleshooting.
25  * - @ref LE_LOG_INFO "INFORMATION":
26  * Expected to happen; can be interesting even when not troubleshooting.
27  * - @ref LE_LOG_WARN "WARNING":
28  * Should not normally happen; may not have any real impact on system performance.
29  * - @ref LE_LOG_ERR "ERROR":
30  * Fault that may result in noticeable short-term system misbehaviour. Needs attention.
31  * - @ref LE_LOG_CRIT "CRITICAL":
32  * Fault needs urgent attention. Will likely result in system failure.
33  * - @ref LE_LOG_EMERG "EMERGENCY":
34  * Definite system failure.
35  *
36  * @subsection c_log_basic_defaultSyslog Standard Out and Standard Error in Syslog
37  *
38  * By default, app processes will have their @c stdout and @c stderr redirected to the @c syslog. Each
39  * process’s stdout will be logged at INFO severity level; it’s stderr will be logged at
40  * “ERR” severity level.
41 
42  * There are two limitations with this feature:
43  * - the PID reported in the logs generally refer to the PID of the process that
44  * generates the stdout/stderr message. If a process forks, then both the parent and
45  * child processes’ stdout/stderr will share the same connection to the syslog, and the parent’s
46  * PID will be reported in the logs for both processes.
47  * - stdout is line buffered when connected to a terminal, which means
48  * <code>printf(“hello\n”)</code> will be printed to the terminal immediately. If stdout is
49  * connected to something like a pipe it's bulk buffered, which means a flush doesn't occur until the buffer is full.
50  *
51  * To make your process line buffer stdout so that printf will show up in the logs as expected,
52  * the @c setlinebuf(stdout) system call can be used. Alternatively, @c fflush(stdout) can be called \
53  * to force a flush of the stdout buffer.
54  *
55  * This issue doesn't exist with stderr as stderr is never buffered.
56  *
57  * @subsection c_log_basic_logging Basic Logging
58  *
59  * A series of macros are available to make logging easy.
60  *
61  * None of them return anything.
62  *
63  * All of them accept printf-style arguments, consisting of a format string followed by zero or more
64  * parameters to be printed (depending on the contents of the format string).
65  *
66  * There is a logging macro for each of the log levels:
67  *
68  * - @ref LE_DEBUG(formatString, ...)
69  * - @ref LE_INFO(formatString, ...)
70  * - @ref LE_WARN(formatString, ...)
71  * - @ref LE_ERROR(formatString, ...)
72  * - @ref LE_CRIT(formatString, ...)
73  * - @ref LE_EMERG(formatString, ...)
74  *
75  * For example,
76  * @code
77  * LE_INFO("Obtained new IP address %s.", ipAddrStr);
78  * @endcode
79  *
80  * @subsection c_log_conditional_logging Conditional Logging
81  *
82  * Similar to the basic macros, but these contain a conditional expression as their first parameter. If this expression equals
83  * true, then the macro will generate this log output:
84  *
85  * - @ref LE_DEBUG_IF(expression, formatString, ...)
86  * - @ref LE_INFO_IF(expression, formatString, ...)
87  * - @ref LE_WARN_IF(expression, formatString, ...)
88  * - @ref LE_ERROR_IF(expression, formatString, ...)
89  * - @ref LE_CRIT_IF(expression, formatString, ...)
90  * - @ref LE_EMERG_IF(expression, formatString, ...)
91  *
92  * Instead of writing
93  * @code
94  * if (result == -1)
95  * {
96  * LE_WARN("Failed to send message to server. Errno = %d.", errno);
97  * }
98  * @endcode
99  *
100  * you could write this:
101  * @code
102  * LE_WARN_IF(result == -1, "Failed to send message to server. Errno = %d.", errno);
103  * @endcode
104  *
105  * @subsection c_log_loging_fatals Fatal Errors
106  *
107  * There are some special logging macros intended for fatal errors:
108  *
109  * - @ref LE_FATAL(formatString, ...) \n
110  * Always kills the calling process after logging the message at EMERGENCY level (never returns).
111  * - @ref LE_FATAL_IF(condition, formatString, ...) \n
112  * If the condition is true, kills the calling process after logging the message at EMERGENCY
113  * level.
114  * - @ref LE_ASSERT(condition) \n
115  * If the condition is true, does nothing. If the condition is false, logs the source
116  * code text of the condition at EMERGENCY level and kills the calling process.
117  * - @ref LE_ASSERT_OK(condition) \n
118  * If the condition is LE_OK (0), does nothing. If the condition is anything else, logs the
119  * a message at EMERGENCY level, containing the source code text of the condition, indicating
120  * that it did not evaluate to LE_OK, and kills the calling process.
121  *
122  * For example,
123  * @code
124  * if (NULL == objPtr)
125  * {
126  * LE_FATAL("Object pointer is NULL!");
127  * }
128  *
129  * // Now I can go ahead and use objPtr, knowing that if it was NULL then LE_FATAL() would have
130  * // been called and LE_FATAL() never returns.
131  * @endcode
132  *
133  * or,
134  *
135  * @code
136  * LE_FATAL_IF(NULL == objPtr, "Object pointer is NULL!");
137  *
138  * // Now I can go ahead and use objPtr, knowing that if it was NULL then LE_FATAL_IF() would not
139  * // have returned.
140  * @endcode
141  *
142  * or,
143  *
144  * @code
145  * LE_ASSERT(NULL != objPtr);
146  *
147  * // Now I can go ahead and use objPtr, knowing that if it was NULL then LE_ASSERT() would not
148  * // have returned.
149  * @endcode
150  *
151  * @subsection c_log_tracing Tracing
152  *
153  * Finally, a macro is provided for tracing:
154  *
155  * - @ref LE_TRACE(traceRef, string, ...)
156  *
157  * This macro is special because it's independent of log level. Instead, trace messages are
158  * associated with a trace keyword. Tracing can be enabled and disabled based on these keywords.
159  *
160  * If a developer wanted to trace the creation of "shape"
161  * objects in their GUI package, they could add trace statements like the following:
162  *
163  * @code
164  * LE_TRACE(NewShapeTraceRef, "Created %p with position (%d,%d).", shapePtr, shapePtr->x, shapePtr->y);
165  * @endcode
166  *
167  * The reference to the trace is obtained at start-up as follows:
168  *
169  * @code
170  * NewShapeTraceRef = le_log_GetTraceRef("newShape");
171  * @endcode
172  *
173  * This allows enabling and disabling these LE_TRACE() calls using the "newShape" keyword
174  * through configuration settings and runtime log control tools. See @ref c_log_controlling below.
175  *
176  * Applications can use @ref LE_IS_TRACE_ENABLED(NewShapeTraceRef) to query whether
177  * a trace keyword is enabled.
178  *
179  * These allow apps to hook into the trace management system to use it to implement
180  * sophisticated, app-specific tracing or profiling features.
181  *
182  * @subsection c_log_resultTxt Result Code Text
183  *
184  * The @ref le_result_t macro supports printing an error condition in a human-readable text string.
185  *
186  * @code
187  * result = le_foo_DoSomething();
188  *
189  * if (result != LE_OK)
190  * {
191  * LE_ERROR("Failed to do something. Result = %d (%s).", result, LE_RESULT_TXT(result));
192  * }
193  * @endcode
194  *
195  *
196  * @section c_log_controlling Log Controls
197  *
198  * Log level filtering and tracing can be controlled at runtime using:
199  * - the command-line Log Control Tool (@ref toolsTarget_log)
200  * - configuration settings
201  * - environment variables
202  * - function calls.
203  *
204  * @subsection c_log_control_tool Log Control Tool
205  *
206  * The log control tool is used from the command-line to control the log
207  * level filtering, log output location (syslog/stderr), and tracing for different components
208  * within a running system.
209  *
210  * Online documentation can be accessed from the log control tool by running "log help".
211  *
212  * Here are some code samples.
213  *
214  * To set the log level to INFO for a component "myComp" running in all processes with the
215  * name "myProc":
216  * @verbatim
217 $ log level INFO myProc/myComp
218 @endverbatim
219  *
220  * To set the log level to DEBUG for a component "myComp" running in a process with PID 1234:
221  * @verbatim
222 $ log level DEBUG 1234/myComp
223 @endverbatim
224  *
225  * To enable all LE_TRACE statements tagged with the keyword "foo" in a component called "myComp"
226  * running in all processes called "myProc":
227  * @verbatim
228 $ log trace foo myProc/myComp
229 @endverbatim
230  *
231  * To disable the trace statements tagged with "foo" in the component "myComp" in processes
232  * called "myProc":
233  * @verbatim
234 $ log stoptrace foo myProc/myComp
235 @endverbatim
236  *
237  * With all of the above examples "*" can be used in place of the process name or a component
238  * name (or both) to mean "all processes" and/or "all components".
239  *
240  * @subsection c_log_control_config Log Control Configuration Settings
241  *
242  * @note The configuration settings haven't been implemented yet.
243  *
244  * @todo Write @ref c_log_control_config section.
245  *
246  * @subsection c_log_control_environment_vars Environment Variables
247  *
248  * Environment variables can be used to control the default log settings, taking effect immediately
249  * at process start-up; even before the Log Control Daemon has been connected to.
250  *
251  * Settings in the Log Control Daemon (applied through configuration and/or the log control tool)
252  * will override the environment variable settings when the process connects to the Log
253  * Control Daemon.
254  *
255  * @subsubsection c_log_control_env_level LE_LOG_LEVEL
256  *
257  * @c LE_LOG_LEVEL can be used to set the default log filter level for all components
258  * in the process. Valid values are:
259  *
260  * - @c EMERGENCY
261  * - @c CRITICAL
262  * - @c ERROR
263  * - @c WARNING
264  * - @c INFO
265  * - @c DEBUG
266  *
267  * For example,
268  * @verbatim
269 $ export LE_LOG_LEVEL=DEBUG
270 @endverbatim
271  *
272  * @subsubsection c_log_control_env_trace LE_LOG_TRACE
273  *
274  * @c LE_LOG_TRACE allows trace keywords to be enabled by default. The contents of this
275  * variable is a colon-separated list of keywords that should be enabled. Each keyword
276  * must be prefixed with a component name followed by a slash ('/').
277  *
278  * For example,
279  * @verbatim
280 $ export LE_LOG_TRACE=framework/fdMonitor:framework/logControl
281 @endverbatim
282  *
283  * @subsection c_log_control_functions Programmatic Log Control
284  *
285  * Normally, configuration settings and the log control tool should suffice for controlling
286  * logging functionality. In some situations, it can be convenient
287  * to control logging programmatically in C.
288  *
289  * le_log_SetFilterLevel() sets the log filter level.
290  *
291  * le_log_GetFilterLevel() gets the log filter level.
292  *
293  * Trace keywords can be enabled and disabled programmatically by calling
294  * @subpage le_log_EnableTrace() and @ref le_log_DisableTrace().
295  *
296  *
297  * @section c_log_format Log Formats
298  *
299  * Log entries can also contain any of these:
300  * - timestamp (century, year, month, day, hours, minutes, seconds, milliseconds, microseconds)
301  * - level (debug, info, warning, etc.) @b or trace keyword
302  * - process ID
303  * - component name
304  * - thread name
305  * - source code file name
306  * - function name
307  * - source code line number
308  *
309  * Log messages have the following format:
310  *
311  * @verbatim
312 Jan 3 02:37:56 INFO | processName[pid]/componentName T=threadName | fileName.c funcName() lineNum | Message
313 @endverbatim
314  *
315  * @section c_log_debugFiles App Crash Logs
316 
317 * When a process within an app faults or exits in error, a copy of the current syslog buffer
318 * is captured along with a core file of the process crash (if generated).
319 
320 * The core file maximum size is determined by the process settings @c maxCoreDumpFileBytes and
321 * @c maxFileBytes found in the processes section of your app's @c .adef file. By default, the
322 * @c maxCoreDumpFileBytes is set to 0, do not create a core file.
323 
324 * To help save the target from flash burnout, the syslog and core files are stored in the RAM
325 * FS under /tmp. When a crash occurs, this directory is created:
326 
327  @verbatim
328  /tmp/legato_logs/
329  @endverbatim
330 
331 * The files in that directory look like this:
332 
333  @verbatim
334  core-myProc-1418694851
335  syslog-myApp-myProc-1418694851
336  @endverbatim
337 
338 * To save on RAM space, only the most recent 4 copies of each file are preserved.
339 
340 * If the fault action for that app's process is to reboot the target, the output location is changed to
341 * this (and the most recent files in RAM space are preserved across reboots):
342 
343  @verbatim
344  /mnt/flash/legato_logs/
345  @endverbatim
346 
347 *
348  * @todo May need to support log format configuration through command-line arguments or a
349  * configuration file.
350  *
351  * @todo Write @ref c_log_retrieving section
352  *
353  * <HR>
354  *
355  * Copyright (C) Sierra Wireless Inc.
356  */
357 
358 
359 /** @file le_log.h
360  *
361  * Legato @ref c_logging include file.
362  *
363  * Copyright (C) Sierra Wireless Inc.
364  */
365 
366 #ifndef LEGATO_LOG_INCLUDE_GUARD
367 #define LEGATO_LOG_INCLUDE_GUARD
368 
369 //--------------------------------------------------------------------------------------------------
370 /**
371  * Local definitions that should not be used directly.
372  */
373 //--------------------------------------------------------------------------------------------------
374 typedef enum
375 {
376  LE_LOG_DEBUG, ///< Debug message.
377  LE_LOG_INFO, ///< Informational message. Normally expected.
378  LE_LOG_WARN, ///< Warning. Possibly indicates a problem. Should be addressed.
379  LE_LOG_ERR, ///< Error. Definitely indicates a fault that needs to be addressed.
380  /// Possibly resulted in a system failure.
381  LE_LOG_CRIT, ///< Critical error. Fault that almost certainly has or will result in a
382  /// system failure.
383  LE_LOG_EMERG ///< Emergency. A fatal error has occurred. A process is being terminated.
384 }
386 
387 //--------------------------------------------------------------------------------------------------
388 /**
389  * Compile-time filtering level.
390  *
391  * @note Logs below this filter level will be removed at compile-time and cannot be enabled
392  * at runtime.
393  */
394 //--------------------------------------------------------------------------------------------------
395 #if LE_CONFIG_LOG_STATIC_FILTER_EMERG
396 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_EMERG
397 #elif LE_CONFIG_LOG_STATIC_FILTER_CRIT
398 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_CRIT
399 #elif LE_CONFIG_LOG_STATIC_FILTER_ERR
400 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_ERR
401 #elif LE_CONFIG_LOG_STATIC_FILTER_WARN
402 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_WARN
403 #elif LE_CONFIG_LOG_STATIC_FILTER_INFO
404 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_INFO
405 #else /* default to LE_DEBUG */
406 # define LE_LOG_LEVEL_STATIC_FILTER LE_LOG_DEBUG
407 #endif
408 
409 //--------------------------------------------------------------------------------------------------
410 /// @cond HIDDEN_IN_USER_DOCS
411 
412 typedef struct le_log_Session* le_log_SessionRef_t;
413 
414 typedef struct le_log_Trace* le_log_TraceRef_t;
415 
416 #if !defined(LE_DEBUG) && \
417  !defined(LE_DUMP) && \
418  !defined(LE_LOG_DUMP) && \
419  !defined(LE_INFO) && \
420  !defined(LE_WARN) && \
421  !defined(LE_ERROR) && \
422  !defined(LE_CRIT) && \
423  !defined(LE_EMERG)
424 void _le_log_Send
425 (
426  const le_log_Level_t level,
427  const le_log_TraceRef_t traceRef,
428  le_log_SessionRef_t logSession,
429  const char* filenamePtr,
430  const char* functionNamePtr,
431  const unsigned int lineNumber,
432  const char* formatPtr,
433  ...
434 ) __attribute__ ((format (printf, 7, 8)));
435 
436 le_log_TraceRef_t _le_log_GetTraceRef
437 (
438  le_log_SessionRef_t logSession,
439  const char* keyword
440 );
441 
442 void _le_log_SetFilterLevel
443 (
444  le_log_SessionRef_t logSession,
445  le_log_Level_t level
446 );
447 
448 void _le_LogData
449 (
450  const le_log_Level_t level, // log level
451  const uint8_t* dataPtr, // The buffer address to be dumped
452  int dataLength, // The data length of buffer
453  const char* filenamePtr, // The name of the source file that logged the message.
454  const char* functionNamePtr, // The name of the function that logged the message.
455  const unsigned int lineNumber // The line number in the source file that logged the message.
456 );
457 
458 
459 //--------------------------------------------------------------------------------------------------
460 /**
461  * Filtering session reference for the current source file.
462  *
463  * @note The real name of this is passed in by the build system. This way it can be a unique
464  * variable for each component.
465  */
466 //--------------------------------------------------------------------------------------------------
467 extern LE_SHARED le_log_SessionRef_t LE_LOG_SESSION;
468 
469 //--------------------------------------------------------------------------------------------------
470 /**
471  * Filtering level for the current source file.
472  *
473  * @note The real name of this is passed in by the build system. This way it can be a unique
474  * variable for each component.
475  */
476 //--------------------------------------------------------------------------------------------------
477 extern LE_SHARED le_log_Level_t* LE_LOG_LEVEL_FILTER_PTR;
478 
479 //--------------------------------------------------------------------------------------------------
480 /**
481  * Internal macro to set whether the function name is displayed with log messages.
482  */
483 //--------------------------------------------------------------------------------------------------
484 #ifndef LE_LOG_EXCLUDE_FUNCTION_NAME
485 # define _LE_LOG_FUNCTION_NAME __func__
486 #else
487 # define _LE_LOG_FUNCTION_NAME NULL
488 #endif
489 
490 /// @endcond
491 //--------------------------------------------------------------------------------------------------
492 
493 //--------------------------------------------------------------------------------------------------
494 /**
495  * Internal macro to filter out messages that do not meet the current filtering level.
496  */
497 //--------------------------------------------------------------------------------------------------
498 #define _LE_LOG_MSG(level, formatString, ...) \
499  do { \
500  if ((level >= LE_LOG_LEVEL_STATIC_FILTER) && \
501  ((LE_LOG_LEVEL_FILTER_PTR == NULL) || (level >= *LE_LOG_LEVEL_FILTER_PTR))) \
502  _le_log_Send(level, NULL, LE_LOG_SESSION, __FILE__, _LE_LOG_FUNCTION_NAME, __LINE__, \
503  formatString, ##__VA_ARGS__); \
504  } while(0)
505 
506 
507 //--------------------------------------------------------------------------------------------------
508 /** @internal
509  * The following macros are used to send log messages at different severity levels:
510  *
511  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
512  * to be printed (depending on the contents of the format string).
513  */
514 //--------------------------------------------------------------------------------------------------
515 
516 /** @copydoc LE_LOG_DEBUG */
517 #define LE_DEBUG(formatString, ...) _LE_LOG_MSG(LE_LOG_DEBUG, formatString, ##__VA_ARGS__)
518 
519 //--------------------------------------------------------------------------------------------------
520 /**
521  * Dump a buffer of data as hexadecimal to the log at debug level.
522  *
523  * @param dataPtr Binary data to dump.
524  * @param dataLength Length og the buffer.
525  */
526 //--------------------------------------------------------------------------------------------------
527 #define LE_DUMP(dataPtr, dataLength) \
528  _le_LogData(LE_LOG_DEBUG, dataPtr, dataLength, STRINGIZE(LE_FILENAME), _LE_LOG_FUNCTION_NAME, \
529  __LINE__)
530 
531 //--------------------------------------------------------------------------------------------------
532 /**
533  * Dump a buffer of data as hexadecimal to the log at the specified level.
534  *
535  * @param level Log level.
536  * @param dataPtr Binary data to dump.
537  * @param dataLength Length of the buffer.
538  */
539 //--------------------------------------------------------------------------------------------------
540 #define LE_LOG_DUMP(level, dataPtr, dataLength) \
541  _le_LogData(level, dataPtr, dataLength, STRINGIZE(LE_FILENAME), _LE_LOG_FUNCTION_NAME, __LINE__)
542 /** @copydoc LE_LOG_INFO */
543 #define LE_INFO(formatString, ...) _LE_LOG_MSG(LE_LOG_INFO, formatString, ##__VA_ARGS__)
544 /** @copydoc LE_LOG_WARN */
545 #define LE_WARN(formatString, ...) _LE_LOG_MSG(LE_LOG_WARN, formatString, ##__VA_ARGS__)
546 /** @copydoc LE_LOG_ERR */
547 #define LE_ERROR(formatString, ...) _LE_LOG_MSG(LE_LOG_ERR, formatString, ##__VA_ARGS__)
548 /** @copydoc LE_LOG_CRIT */
549 #define LE_CRIT(formatString, ...) _LE_LOG_MSG(LE_LOG_CRIT, formatString, ##__VA_ARGS__)
550 /** @copydoc LE_LOG_EMERG */
551 #define LE_EMERG(formatString, ...) _LE_LOG_MSG(LE_LOG_EMERG, formatString, ##__VA_ARGS__)
552 
553 
554 //--------------------------------------------------------------------------------------------------
555 /**
556  * Queries whether or not a trace keyword is enabled.
557  *
558  * @return
559  * true if the keyword is enabled.
560  * false otherwise.
561  */
562 //--------------------------------------------------------------------------------------------------
563 #define LE_IS_TRACE_ENABLED(traceRef) (le_log_IsTraceEnabled(traceRef))
564 
565 
566 //--------------------------------------------------------------------------------------------------
567 /**
568  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
569  */
570 //--------------------------------------------------------------------------------------------------
571 #define LE_TRACE(traceRef, string, ...) \
572  if (le_log_IsTraceEnabled(traceRef)) \
573  { \
574  _le_log_Send((le_log_Level_t)-1, \
575  traceRef, \
576  LE_LOG_SESSION, \
577  STRINGIZE(LE_FILENAME), \
578  _LE_LOG_FUNCTION_NAME, \
579  __LINE__, \
580  string, \
581  ##__VA_ARGS__); \
582  }
583 
584 
585 //--------------------------------------------------------------------------------------------------
586 /**
587  * Gets a reference to a trace keyword's settings.
588  *
589  * @param keywordPtr [IN] Pointer to the keyword string.
590  *
591  * @return Trace reference.
592  **/
593 //--------------------------------------------------------------------------------------------------
594 #define le_log_GetTraceRef(keywordPtr) \
595  _le_log_GetTraceRef(LE_LOG_SESSION, (keywordPtr))
596 
597 
598 //--------------------------------------------------------------------------------------------------
599 /**
600  * Determines if a trace is currently enabled.
601  *
602  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
603  *
604  * @return true if enabled, false if not.
605  **/
606 //--------------------------------------------------------------------------------------------------
607 #define le_log_IsTraceEnabled(traceRef) \
608  (*((bool*)(traceRef)))
609 
610 
611 //--------------------------------------------------------------------------------------------------
612 /**
613  * Sets the log filter level for the calling component.
614  *
615  * @note Normally not necessary as the log filter level can be controlled at
616  * runtime using the log control tool, and can be persistently configured.
617  * See @ref c_log_controlling.
618  *
619  * @param level [IN] Log filter level to apply to the current log session.
620  **/
621 //--------------------------------------------------------------------------------------------------
622 #define le_log_SetFilterLevel(level) \
623  _le_log_SetFilterLevel(LE_LOG_SESSION, (level))
624 
625 
626 //--------------------------------------------------------------------------------------------------
627 /**
628  * Gets the log filter level for the calling component.
629  **/
630 //--------------------------------------------------------------------------------------------------
631 #define le_log_GetFilterLevel() \
632  ((LE_LOG_LEVEL_FILTER_PTR != NULL)?(*LE_LOG_LEVEL_FILTER_PTR):(LE_LOG_INFO))
633 
634 
635 //--------------------------------------------------------------------------------------------------
636 /**
637  * Enables a trace.
638  *
639  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
640  * log control tool and can be persistently configured. See @ref c_log_controlling.
641  *
642  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
643  *
644  **/
645 //--------------------------------------------------------------------------------------------------
646 #define le_log_EnableTrace(traceRef) \
647  ((void)(*((bool*)(traceRef)) = true))
648 
649 
650 //--------------------------------------------------------------------------------------------------
651 /**
652  * Disables a trace.
653  *
654  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
655  * log control tool and can be persistently configured. See @ref c_log_controlling.
656  *
657  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
658  *
659  **/
660 //--------------------------------------------------------------------------------------------------
661 #define le_log_DisableTrace(traceRef) \
662  ((void)(*((bool*)(traceRef)) = false))
663 
664 #else
665 
666 // If any logging macro is overridden, all logging macros must be overridden.
667 #if !defined(LE_DEBUG)
668 # error "Logging are overridden, but LE_DEBUG not defined. Define LE_DEBUG."
669 #endif
670 
671 #if !defined(LE_DUMP)
672 # error "Logging are overridden, but LE_DUMP not defined. Define LE_DUMP."
673 #endif
674 
675 #if !defined(LE_LOG_DUMP)
676 # error "Logging are overridden, but LE_LOG_DUMP not defined. Define LE_LOG_DUMP."
677 #endif
678 
679 #if !defined(LE_INFO)
680 # error "Logging are overridden, but LE_INFO not defined. Define LE_INFO."
681 #endif
682 
683 #if !defined(LE_WARN)
684 # error "Logging are overridden, but LE_WARN not defined. Define LE_WARN."
685 #endif
686 
687 #if !defined(LE_ERROR)
688 # error "Logging are overridden, but LE_ERROR not defined. Define LE_ERROR."
689 #endif
690 
691 #if !defined(LE_CRIT)
692 # error "Logging are overridden, but LE_CRIT not defined. Define LE_CRIT."
693 #endif
694 
695 #if !defined(LE_EMERG)
696 # error "Logging are overridden, but LE_EMERG not defined. Define LE_EMERG."
697 #endif
698 
699 // If SetFilterLevel is not defined when logging is overridden,
700 // assume it cannot be set programatically
701 #ifndef le_log_SetFilterLevel
702 //--------------------------------------------------------------------------------------------------
703 /**
704  * Sets the log filter level for the calling component.
705  *
706  * @note Normally not necessary as the log filter level can be controlled at
707  * runtime using the log control tool, and can be persistently configured.
708  * See @ref c_log_controlling.
709  *
710  * @param level [IN] Log filter level to apply to the current log session.
711  **/
712 //--------------------------------------------------------------------------------------------------
713 #define le_log_SetFilterLevel(level) ((void)(level))
714 #endif
715 
716 
717 // If le_log_GetFilterLevel is not defined when logging is overridden, assume it
718 // cannot be obtained programatically. In this case code should assume filter level
719 // is equal to static filter level
720 #ifndef le_log_GetFilterLevel
721 //--------------------------------------------------------------------------------------------------
722 /**
723  * Gets the log filter level for the calling component.
724  **/
725 //--------------------------------------------------------------------------------------------------
726 #define le_log_GetFilterLevel() (LE_LOG_LEVEL_STATIC_FILTER)
727 #endif
728 
729 //--------------------------------------------------------------------------------------------------
730 /*
731  * If logging is overridden, disable Legato tracing mechanism. Tracing is noisy and should
732  * not be put into general logs.
733  */
734 //--------------------------------------------------------------------------------------------------
735 
736 //--------------------------------------------------------------------------------------------------
737 /**
738  * Queries whether or not a trace keyword is enabled.
739  *
740  * @return
741  * true if the keyword is enabled.
742  * false otherwise.
743  */
744 //--------------------------------------------------------------------------------------------------
745 #define LE_IS_TRACE_ENABLED(traceRef) (false)
746 
747 
748 //--------------------------------------------------------------------------------------------------
749 /**
750  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
751  */
752 //--------------------------------------------------------------------------------------------------
753 #define LE_TRACE(traceRef, string, ...) ((void)0)
754 
755 
756 //--------------------------------------------------------------------------------------------------
757 /**
758  * Gets a reference to a trace keyword's settings.
759  *
760  * @param keywordPtr [IN] Pointer to the keyword string.
761  *
762  * @return Trace reference.
763  **/
764 //--------------------------------------------------------------------------------------------------
765 #define le_log_GetTraceRef(keywordPtr) ((le_log_TraceRef_t)NULL)
766 
767 
768 //--------------------------------------------------------------------------------------------------
769 /**
770  * Determines if a trace is currently enabled.
771  *
772  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
773  *
774  * @return true if enabled, false if not.
775  **/
776 //--------------------------------------------------------------------------------------------------
777 #define le_log_IsTraceEnabled(traceRef) (false)
778 
779 
780 //--------------------------------------------------------------------------------------------------
781 /**
782  * Enables a trace.
783  *
784  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
785  * log control tool and can be persistently configured. See @ref c_log_controlling.
786  *
787  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
788  *
789  **/
790 //--------------------------------------------------------------------------------------------------
791 #define le_log_EnableTrace(traceRef) ((void)(0))
792 
793 
794 //--------------------------------------------------------------------------------------------------
795 /**
796  * Disables a trace.
797  *
798  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
799  * log control tool and can be persistently configured. See @ref c_log_controlling.
800  *
801  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
802  *
803  **/
804 //--------------------------------------------------------------------------------------------------
805 #define le_log_DisableTrace(traceRef) ((void)(0))
806 
807 #endif /* Logging macro override */
808 
809 /// Function that does the real work of translating result codes. See @ref LE_RESULT_TXT.
810 const char* _le_log_GetResultCodeString
811 (
812  le_result_t resultCode ///< [in] Result code value to be translated.
813 );
814 
815 //--------------------------------------------------------------------------------------------------
816 /** @internal
817  * The following macros are used to send log messages at different severity levels conditionally.
818  * If the condition is true the message is logged. If the condition is false the message is not
819  * logged.
820  *
821  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
822  * to be printed (depending on the contents of the format string).
823  */
824 //--------------------------------------------------------------------------------------------------
825 
826 /** @ref LE_DEBUG if condition is met. */
827 #define LE_DEBUG_IF(condition, formatString, ...) \
828  if (condition) { LE_DEBUG(formatString, ##__VA_ARGS__); }
829 /** @ref LE_INFO if condition is met. */
830 #define LE_INFO_IF(condition, formatString, ...) \
831  if (condition) { LE_INFO(formatString, ##__VA_ARGS__); }
832 /** @ref LE_WARN if condition is met. */
833 #define LE_WARN_IF(condition, formatString, ...) \
834  if (condition) { LE_WARN(formatString, ##__VA_ARGS__); }
835 /** @ref LE_ERROR if condition is met. */
836 #define LE_ERROR_IF(condition, formatString, ...) \
837  if (condition) { LE_ERROR(formatString, ##__VA_ARGS__); }
838 /** @ref LE_CRIT if condition is met. */
839 #define LE_CRIT_IF(condition, formatString, ...) \
840  if (condition) { LE_CRIT(formatString, ##__VA_ARGS__); }
841 /** @ref LE_EMERG if condition is met. */
842 #define LE_EMERG_IF(condition, formatString, ...) \
843  if (condition) { LE_EMERG(formatString, ##__VA_ARGS__); }
844 
845 
846 //--------------------------------------------------------------------------------------------------
847 /**
848  * Log fatal errors by killing the calling process after logging the message at EMERGENCY
849  * level. This macro never returns.
850  *
851  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
852  * to be printed (depending on the contents of the format string).
853  */
854 //--------------------------------------------------------------------------------------------------
855 #define LE_FATAL(formatString, ...) \
856  { LE_EMERG(formatString, ##__VA_ARGS__); exit(EXIT_FAILURE); }
857 
858 
859 //--------------------------------------------------------------------------------------------------
860 /**
861  * This macro does nothing if the condition is false, otherwise it logs the message at EMERGENCY
862  * level and then kills the calling process.
863  *
864  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
865  * to be printed (depending on the contents of the format string).
866  */
867 //--------------------------------------------------------------------------------------------------
868 #define LE_FATAL_IF(condition, formatString, ...) \
869  if (condition) { LE_FATAL(formatString, ##__VA_ARGS__) }
870 
871 
872 //--------------------------------------------------------------------------------------------------
873 /**
874  * This macro does nothing if the condition is true, otherwise it logs the condition expression as
875  * a message at EMERGENCY level and then kills the calling process.
876  */
877 //--------------------------------------------------------------------------------------------------
878 #define LE_ASSERT(condition) \
879  if (!(condition)) \
880  { \
881  LE_EMERG("Assert Failed: '%s'", #condition); \
882  LE_BACKTRACE("Assertion Call Stack"); \
883  exit(EXIT_FAILURE); \
884  }
885 
886 
887 //--------------------------------------------------------------------------------------------------
888 /**
889  * This macro does nothing if the condition is LE_OK (0), otherwise it logs that the expression did
890  * not evaluate to LE_OK (0) in a message at EMERGENCY level and then kills the calling process.
891  */
892 //--------------------------------------------------------------------------------------------------
893 #define LE_ASSERT_OK(condition) \
894  if ((condition) != LE_OK) \
895  { \
896  LE_EMERG("Assert Failed: '%s' is not LE_OK (0)", #condition); \
897  LE_BACKTRACE("Assertion Call Stack"); \
898  exit(EXIT_FAILURE); \
899  }
900 
901 
902 //--------------------------------------------------------------------------------------------------
903 /**
904  * Get a null-terminated, printable string representing an le_result_t value.
905  *
906  * For example, LE_RESULT_TXT(LE_NOT_PERMITTED) would return a pointer to a string containing
907  * "LE_NOT_PERMITTED".
908  *
909  * "(unknown)" will be returned if the value given is out of range.
910  *
911  * @return Pointer to a string constant.
912  */
913 //--------------------------------------------------------------------------------------------------
914 #define LE_RESULT_TXT(v) _le_log_GetResultCodeString(v)
915 
916 
917 #endif // LEGATO_LOG_INCLUDE_GUARD
#define LE_SHARED
Definition: le_basics.h:241
le_result_t
Definition: le_basics.h:35
Warning. Possibly indicates a problem. Should be addressed.
Definition: le_log.h:378
le_log_Level_t
Definition: le_log.h:374
Debug message.
Definition: le_log.h:376
Definition: le_log.h:379
const char * _le_log_GetResultCodeString(le_result_t resultCode)
Function that does the real work of translating result codes. See LE_RESULT_TXT.
Definition: le_log.h:381
Informational message. Normally expected.
Definition: le_log.h:377
Emergency. A fatal error has occurred. A process is being terminated.
Definition: le_log.h:383