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 
425 /// Default log implementation is in use.
426 # define LE_LOG_DEFAULT_IMPL 1
427 
428 //--------------------------------------------------------------------------------------------------
429 /**
430  * Send a message to the logging target.
431  **/
432 //--------------------------------------------------------------------------------------------------
433 void _le_log_Send
434 (
435  const le_log_Level_t level, ///< Log level.
436  const le_log_TraceRef_t traceRef, ///< Trace reference. May be NULL.
437  le_log_SessionRef_t logSession, ///< Log session. May be NULL.
438  const char *filenamePtr, ///< File name.
439  const char *functionNamePtr, ///< Function name. May be NULL.
440  const unsigned int lineNumber, ///< Line number.
441  const char *formatPtr, ///< Format string.
442  ... ///< Positional parameters.
443 ) __attribute__((format (printf, 7, 8)));
444 
445 //--------------------------------------------------------------------------------------------------
446 /**
447  * Log data block. Provides a hex dump for debug.
448  */
449 //--------------------------------------------------------------------------------------------------
450 void _le_LogData
451 (
452  le_log_Level_t level, ///< Log level.
453  const uint8_t *dataPtr, ///< The buffer address to be dumped.
454  int dataLength, ///< The data length of buffer.
455  const char *filenamePtr, ///< The name of the source file that logged the
456  ///< message.
457  const char *functionNamePtr, ///< The name of the function that logged the message.
458  const unsigned int lineNumber ///< The line number in the source file that logged the
459  ///< message.
460 );
461 
462 //--------------------------------------------------------------------------------------------------
463 /**
464  * Gets a reference to a trace keyword's settings.
465  *
466  * @return Trace reference.
467  **/
468 //--------------------------------------------------------------------------------------------------
469 le_log_TraceRef_t _le_log_GetTraceRef
470 (
471  le_log_SessionRef_t logSession, ///< Log session.
472  const char *keyword ///< Trace keyword.
473 );
474 
475 //--------------------------------------------------------------------------------------------------
476 /**
477  * Sets the log filter level for the calling component.
478  **/
479 //--------------------------------------------------------------------------------------------------
480 void _le_log_SetFilterLevel
481 (
482  le_log_SessionRef_t logSession, ///< Log session.
483  le_log_Level_t level ///< Log level to apply.
484 );
485 
486 //--------------------------------------------------------------------------------------------------
487 /**
488  * Filtering session reference for the current source file.
489  *
490  * @note The real name of this is passed in by the build system. This way it can be a unique
491  * variable for each component.
492  */
493 //--------------------------------------------------------------------------------------------------
494 extern LE_SHARED le_log_SessionRef_t LE_LOG_SESSION;
495 
496 //--------------------------------------------------------------------------------------------------
497 /**
498  * Filtering level for the current source file.
499  *
500  * @note The real name of this is passed in by the build system. This way it can be a unique
501  * variable for each component.
502  */
503 //--------------------------------------------------------------------------------------------------
504 extern LE_SHARED le_log_Level_t* LE_LOG_LEVEL_FILTER_PTR;
505 
506 //--------------------------------------------------------------------------------------------------
507 /**
508  * Internal macro to set whether the function name is displayed with log messages.
509  */
510 //--------------------------------------------------------------------------------------------------
511 #if LE_CONFIG_LOG_FUNCTION_NAMES
512 # define _LE_LOG_FUNCTION_NAME __func__
513 #else
514 # define _LE_LOG_FUNCTION_NAME NULL
515 #endif
516 
517 /// @endcond
518 //--------------------------------------------------------------------------------------------------
519 
520 //--------------------------------------------------------------------------------------------------
521 /**
522  * Internal macro to filter out messages that do not meet the current filtering level.
523  */
524 //--------------------------------------------------------------------------------------------------
525 #define _LE_LOG_MSG(level, formatString, ...) \
526  do { \
527  if ((level >= LE_LOG_LEVEL_STATIC_FILTER) && \
528  ((LE_LOG_LEVEL_FILTER_PTR == NULL) || (level >= *LE_LOG_LEVEL_FILTER_PTR))) \
529  _le_log_Send(level, NULL, LE_LOG_SESSION, __FILE__, _LE_LOG_FUNCTION_NAME, __LINE__, \
530  formatString, ##__VA_ARGS__); \
531  } while(0)
532 
533 
534 //--------------------------------------------------------------------------------------------------
535 /** @internal
536  * The following macros are used to send log messages at different severity levels:
537  *
538  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
539  * to be printed (depending on the contents of the format string).
540  */
541 //--------------------------------------------------------------------------------------------------
542 
543 /** @copydoc LE_LOG_DEBUG */
544 #define LE_DEBUG(formatString, ...) _LE_LOG_MSG(LE_LOG_DEBUG, formatString, ##__VA_ARGS__)
545 
546 //--------------------------------------------------------------------------------------------------
547 /**
548  * Dump a buffer of data as hexadecimal to the log at debug level.
549  *
550  * @param dataPtr Binary data to dump.
551  * @param dataLength Length og the buffer.
552  */
553 //--------------------------------------------------------------------------------------------------
554 #define LE_DUMP(dataPtr, dataLength) \
555  _le_LogData(LE_LOG_DEBUG, dataPtr, dataLength, STRINGIZE(LE_FILENAME), _LE_LOG_FUNCTION_NAME, \
556  __LINE__)
557 
558 //--------------------------------------------------------------------------------------------------
559 /**
560  * Dump a buffer of data as hexadecimal to the log at the specified level.
561  *
562  * @param level Log level.
563  * @param dataPtr Binary data to dump.
564  * @param dataLength Length of the buffer.
565  */
566 //--------------------------------------------------------------------------------------------------
567 #define LE_LOG_DUMP(level, dataPtr, dataLength) \
568  _le_LogData(level, dataPtr, dataLength, STRINGIZE(LE_FILENAME), _LE_LOG_FUNCTION_NAME, __LINE__)
569 /** @copydoc LE_LOG_INFO */
570 #define LE_INFO(formatString, ...) _LE_LOG_MSG(LE_LOG_INFO, formatString, ##__VA_ARGS__)
571 /** @copydoc LE_LOG_WARN */
572 #define LE_WARN(formatString, ...) _LE_LOG_MSG(LE_LOG_WARN, formatString, ##__VA_ARGS__)
573 /** @copydoc LE_LOG_ERR */
574 #define LE_ERROR(formatString, ...) _LE_LOG_MSG(LE_LOG_ERR, formatString, ##__VA_ARGS__)
575 /** @copydoc LE_LOG_CRIT */
576 #define LE_CRIT(formatString, ...) _LE_LOG_MSG(LE_LOG_CRIT, formatString, ##__VA_ARGS__)
577 /** @copydoc LE_LOG_EMERG */
578 #define LE_EMERG(formatString, ...) _LE_LOG_MSG(LE_LOG_EMERG, formatString, ##__VA_ARGS__)
579 
580 
581 //--------------------------------------------------------------------------------------------------
582 /**
583  * Queries whether or not a trace keyword is enabled.
584  *
585  * @return
586  * true if the keyword is enabled.
587  * false otherwise.
588  */
589 //--------------------------------------------------------------------------------------------------
590 #define LE_IS_TRACE_ENABLED(traceRef) (le_log_IsTraceEnabled(traceRef))
591 
592 
593 //--------------------------------------------------------------------------------------------------
594 /**
595  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
596  */
597 //--------------------------------------------------------------------------------------------------
598 #define LE_TRACE(traceRef, string, ...) \
599  if (le_log_IsTraceEnabled(traceRef)) \
600  { \
601  _le_log_Send((le_log_Level_t)-1, \
602  traceRef, \
603  LE_LOG_SESSION, \
604  STRINGIZE(LE_FILENAME), \
605  _LE_LOG_FUNCTION_NAME, \
606  __LINE__, \
607  string, \
608  ##__VA_ARGS__); \
609  }
610 
611 
612 //--------------------------------------------------------------------------------------------------
613 /**
614  * Gets a reference to a trace keyword's settings.
615  *
616  * @param keywordPtr [IN] Pointer to the keyword string.
617  *
618  * @return Trace reference.
619  **/
620 //--------------------------------------------------------------------------------------------------
621 #define le_log_GetTraceRef(keywordPtr) \
622  _le_log_GetTraceRef(LE_LOG_SESSION, (keywordPtr))
623 
624 
625 //--------------------------------------------------------------------------------------------------
626 /**
627  * Determines if a trace is currently enabled.
628  *
629  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
630  *
631  * @return true if enabled, false if not.
632  **/
633 //--------------------------------------------------------------------------------------------------
634 #define le_log_IsTraceEnabled(traceRef) ((traceRef) == NULL ? false : *((bool *) (traceRef)))
635 
636 
637 //--------------------------------------------------------------------------------------------------
638 /**
639  * Sets the log filter level for the calling component.
640  *
641  * @note Normally not necessary as the log filter level can be controlled at
642  * runtime using the log control tool, and can be persistently configured.
643  * See @ref c_log_controlling.
644  *
645  * @param level [IN] Log filter level to apply to the current log session.
646  **/
647 //--------------------------------------------------------------------------------------------------
648 #define le_log_SetFilterLevel(level) \
649  _le_log_SetFilterLevel(LE_LOG_SESSION, (level))
650 
651 
652 //--------------------------------------------------------------------------------------------------
653 /**
654  * Gets the log filter level for the calling component.
655  **/
656 //--------------------------------------------------------------------------------------------------
657 #define le_log_GetFilterLevel() \
658  ((LE_LOG_LEVEL_FILTER_PTR != NULL)?(*LE_LOG_LEVEL_FILTER_PTR):(LE_LOG_INFO))
659 
660 
661 //--------------------------------------------------------------------------------------------------
662 /**
663  * Enables a trace.
664  *
665  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
666  * log control tool and can be persistently configured. See @ref c_log_controlling.
667  *
668  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
669  *
670  **/
671 //--------------------------------------------------------------------------------------------------
672 #define le_log_EnableTrace(traceRef) \
673  ((void)(*((bool*)(traceRef)) = true))
674 
675 
676 //--------------------------------------------------------------------------------------------------
677 /**
678  * Disables a trace.
679  *
680  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
681  * log control tool and can be persistently configured. See @ref c_log_controlling.
682  *
683  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
684  *
685  **/
686 //--------------------------------------------------------------------------------------------------
687 #define le_log_DisableTrace(traceRef) \
688  ((void)(*((bool*)(traceRef)) = false))
689 
690 #else
691 
692 // If any logging macro is overridden, all logging macros must be overridden.
693 #if !defined(LE_DEBUG)
694 # error "Logging are overridden, but LE_DEBUG not defined. Define LE_DEBUG."
695 #endif
696 
697 #if !defined(LE_DUMP)
698 # error "Logging are overridden, but LE_DUMP not defined. Define LE_DUMP."
699 #endif
700 
701 #if !defined(LE_LOG_DUMP)
702 # error "Logging are overridden, but LE_LOG_DUMP not defined. Define LE_LOG_DUMP."
703 #endif
704 
705 #if !defined(LE_INFO)
706 # error "Logging are overridden, but LE_INFO not defined. Define LE_INFO."
707 #endif
708 
709 #if !defined(LE_WARN)
710 # error "Logging are overridden, but LE_WARN not defined. Define LE_WARN."
711 #endif
712 
713 #if !defined(LE_ERROR)
714 # error "Logging are overridden, but LE_ERROR not defined. Define LE_ERROR."
715 #endif
716 
717 #if !defined(LE_CRIT)
718 # error "Logging are overridden, but LE_CRIT not defined. Define LE_CRIT."
719 #endif
720 
721 #if !defined(LE_EMERG)
722 # error "Logging are overridden, but LE_EMERG not defined. Define LE_EMERG."
723 #endif
724 
725 // If SetFilterLevel is not defined when logging is overridden,
726 // assume it cannot be set programatically
727 #ifndef le_log_SetFilterLevel
728 //--------------------------------------------------------------------------------------------------
729 /**
730  * Sets the log filter level for the calling component.
731  *
732  * @note Normally not necessary as the log filter level can be controlled at
733  * runtime using the log control tool, and can be persistently configured.
734  * See @ref c_log_controlling.
735  *
736  * @param level [IN] Log filter level to apply to the current log session.
737  **/
738 //--------------------------------------------------------------------------------------------------
739 #define le_log_SetFilterLevel(level) ((void)(level))
740 #endif
741 
742 
743 // If le_log_GetFilterLevel is not defined when logging is overridden, assume it
744 // cannot be obtained programatically. In this case code should assume filter level
745 // is equal to static filter level
746 #ifndef le_log_GetFilterLevel
747 //--------------------------------------------------------------------------------------------------
748 /**
749  * Gets the log filter level for the calling component.
750  **/
751 //--------------------------------------------------------------------------------------------------
752 #define le_log_GetFilterLevel() (LE_LOG_LEVEL_STATIC_FILTER)
753 #endif
754 
755 //--------------------------------------------------------------------------------------------------
756 /*
757  * If logging is overridden, disable Legato tracing mechanism. Tracing is noisy and should
758  * not be put into general logs.
759  */
760 //--------------------------------------------------------------------------------------------------
761 
762 //--------------------------------------------------------------------------------------------------
763 /**
764  * Queries whether or not a trace keyword is enabled.
765  *
766  * @return
767  * true if the keyword is enabled.
768  * false otherwise.
769  */
770 //--------------------------------------------------------------------------------------------------
771 #define LE_IS_TRACE_ENABLED(traceRef) (false)
772 
773 
774 //--------------------------------------------------------------------------------------------------
775 /**
776  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
777  */
778 //--------------------------------------------------------------------------------------------------
779 #define LE_TRACE(traceRef, string, ...) ((void)0)
780 
781 
782 //--------------------------------------------------------------------------------------------------
783 /**
784  * Gets a reference to a trace keyword's settings.
785  *
786  * @param keywordPtr [IN] Pointer to the keyword string.
787  *
788  * @return Trace reference.
789  **/
790 //--------------------------------------------------------------------------------------------------
791 #define le_log_GetTraceRef(keywordPtr) ((le_log_TraceRef_t)NULL)
792 
793 
794 //--------------------------------------------------------------------------------------------------
795 /**
796  * Determines if a trace is currently enabled.
797  *
798  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
799  *
800  * @return true if enabled, false if not.
801  **/
802 //--------------------------------------------------------------------------------------------------
803 #define le_log_IsTraceEnabled(traceRef) (false)
804 
805 
806 //--------------------------------------------------------------------------------------------------
807 /**
808  * Enables a trace.
809  *
810  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
811  * log control tool and can be persistently configured. See @ref c_log_controlling.
812  *
813  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
814  *
815  **/
816 //--------------------------------------------------------------------------------------------------
817 #define le_log_EnableTrace(traceRef) ((void)(0))
818 
819 
820 //--------------------------------------------------------------------------------------------------
821 /**
822  * Disables a trace.
823  *
824  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
825  * log control tool and can be persistently configured. See @ref c_log_controlling.
826  *
827  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
828  *
829  **/
830 //--------------------------------------------------------------------------------------------------
831 #define le_log_DisableTrace(traceRef) ((void)(0))
832 
833 #endif /* Logging macro override */
834 
835 /// Function that does the real work of translating result codes. See @ref LE_RESULT_TXT.
836 const char* _le_log_GetResultCodeString
837 (
838  le_result_t resultCode ///< [in] Result code value to be translated.
839 );
840 
841 /// Function that exits in a race-free manner -- work around glibc BZ#14333
842 __attribute__((noreturn))
844 (
845  void
846 );
847 
848 //--------------------------------------------------------------------------------------------------
849 /** @internal
850  * The following macros are used to send log messages at different severity levels conditionally.
851  * If the condition is true the message is logged. If the condition is false the message is not
852  * logged.
853  *
854  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
855  * to be printed (depending on the contents of the format string).
856  */
857 //--------------------------------------------------------------------------------------------------
858 
859 /** @ref LE_DEBUG if condition is met. */
860 #define LE_DEBUG_IF(condition, formatString, ...) \
861  if (condition) { LE_DEBUG(formatString, ##__VA_ARGS__); }
862 /** @ref LE_INFO if condition is met. */
863 #define LE_INFO_IF(condition, formatString, ...) \
864  if (condition) { LE_INFO(formatString, ##__VA_ARGS__); }
865 /** @ref LE_WARN if condition is met. */
866 #define LE_WARN_IF(condition, formatString, ...) \
867  if (condition) { LE_WARN(formatString, ##__VA_ARGS__); }
868 /** @ref LE_ERROR if condition is met. */
869 #define LE_ERROR_IF(condition, formatString, ...) \
870  if (condition) { LE_ERROR(formatString, ##__VA_ARGS__); }
871 /** @ref LE_CRIT if condition is met. */
872 #define LE_CRIT_IF(condition, formatString, ...) \
873  if (condition) { LE_CRIT(formatString, ##__VA_ARGS__); }
874 /** @ref LE_EMERG if condition is met. */
875 #define LE_EMERG_IF(condition, formatString, ...) \
876  if (condition) { LE_EMERG(formatString, ##__VA_ARGS__); }
877 
878 
879 //--------------------------------------------------------------------------------------------------
880 /**
881  * Log fatal errors by killing the calling process after logging the message at EMERGENCY
882  * level. This macro never returns.
883  *
884  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
885  * to be printed (depending on the contents of the format string).
886  */
887 //--------------------------------------------------------------------------------------------------
888 #if !LE_CONFIG_DEBUG
889 #define LE_FATAL(formatString, ...) \
890  { LE_EMERG(formatString, ##__VA_ARGS__); _le_log_ExitFatal(); }
891 #else
892 #define LE_FATAL(formatString, ...) \
893  { LE_EMERG(formatString, ##__VA_ARGS__); abort(); }
894 #endif
895 
896 
897 //--------------------------------------------------------------------------------------------------
898 /**
899  * This macro does nothing if the condition is false, otherwise it logs the message at EMERGENCY
900  * level and then kills the calling process.
901  *
902  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
903  * to be printed (depending on the contents of the format string).
904  */
905 //--------------------------------------------------------------------------------------------------
906 #define LE_FATAL_IF(condition, formatString, ...) \
907  if (condition) { LE_FATAL(formatString, ##__VA_ARGS__) }
908 
909 
910 //--------------------------------------------------------------------------------------------------
911 /**
912  * This macro does nothing if the condition is true, otherwise it logs the condition expression as
913  * a message at EMERGENCY level and then kills the calling process.
914  */
915 //--------------------------------------------------------------------------------------------------
916 #define LE_ASSERT(condition) \
917  LE_FATAL_IF(!(condition), "Assert Failed: '%s'", #condition)
918 
919 
920 //--------------------------------------------------------------------------------------------------
921 /**
922  * This macro does nothing if the condition is LE_OK (0), otherwise it logs that the expression did
923  * not evaluate to LE_OK (0) in a message at EMERGENCY level and then kills the calling process.
924  */
925 //--------------------------------------------------------------------------------------------------
926 #define LE_ASSERT_OK(condition) \
927  LE_FATAL_IF((condition) != LE_OK, "Assert Failed: '%s' is not LE_OK (0)", #condition)
928 
929 
930 //--------------------------------------------------------------------------------------------------
931 /**
932  * Get a null-terminated, printable string representing an le_result_t value.
933  *
934  * For example, LE_RESULT_TXT(LE_NOT_PERMITTED) would return a pointer to a string containing
935  * "LE_NOT_PERMITTED".
936  *
937  * "(unknown)" will be returned if the value given is out of range.
938  *
939  * @return Pointer to a string constant.
940  */
941 //--------------------------------------------------------------------------------------------------
942 #define LE_RESULT_TXT(v) _le_log_GetResultCodeString(v)
943 
944 //--------------------------------------------------------------------------------------------------
945 /**
946  * Connects to the Log Control Daemon. This must not be done until after the Messaging system
947  * is initialized, but must be done before the main thread's Event Loop starts to ensure that
948  * all log settings are received from the Log Control Daemon and applied to sessions in the local
949  * process before any component initialization functions are run.
950  */
951 //--------------------------------------------------------------------------------------------------
953 (
954  void
955 );
956 
957 //--------------------------------------------------------------------------------------------------
958 /**
959  * Registers a named component with the logging system.
960  *
961  * @return
962  * A log session reference. This reference must be kept by the component and accessible
963  * through a local macro with the name LE_LOG_SESSION.
964  */
965 //--------------------------------------------------------------------------------------------------
966 LE_FULL_API le_log_SessionRef_t le_log_RegComponent
967 (
968  const char *componentNamePtr, ///< [IN] A pointer to the component's name.
969  le_log_Level_t **levelFilterPtrPtr ///< [OUT] Set to point to the component's level filter.
970 );
971 
972 #endif // LEGATO_LOG_INCLUDE_GUARD
LE_FULL_API le_log_SessionRef_t le_log_RegComponent(const char *componentNamePtr, le_log_Level_t **levelFilterPtrPtr)
#define LE_SHARED
Definition: le_basics.h:273
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.
LE_FULL_API void le_log_ConnectToControlDaemon(void)
Definition: le_log.h:381
#define LE_FULL_API
Definition: le_apiFeatures.h:40
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
void _le_log_ExitFatal(void)
Function that exits in a race-free manner -- work around glibc BZ#14333.