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 _le_log_Level_t
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  * Mark tracing as used, so trace-related code can be compiled in.
584  */
585 //--------------------------------------------------------------------------------------------------
586 #define LE_LOG_CAN_TRACE 1
587 
588 
589 //--------------------------------------------------------------------------------------------------
590 /**
591  * Queries whether or not a trace keyword is enabled.
592  *
593  * @return
594  * true if the keyword is enabled.
595  * false otherwise.
596  */
597 //--------------------------------------------------------------------------------------------------
598 #define LE_IS_TRACE_ENABLED(traceRef) (le_log_IsTraceEnabled(traceRef))
599 
600 
601 //--------------------------------------------------------------------------------------------------
602 /**
603  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
604  */
605 //--------------------------------------------------------------------------------------------------
606 #define LE_TRACE(traceRef, string, ...) \
607  if (le_log_IsTraceEnabled(traceRef)) \
608  { \
609  _le_log_Send((le_log_Level_t)-1, \
610  traceRef, \
611  LE_LOG_SESSION, \
612  STRINGIZE(LE_FILENAME), \
613  _LE_LOG_FUNCTION_NAME, \
614  __LINE__, \
615  string, \
616  ##__VA_ARGS__); \
617  }
618 
619 
620 //--------------------------------------------------------------------------------------------------
621 /**
622  * Gets a reference to a trace keyword's settings.
623  *
624  * @param keywordPtr [IN] Pointer to the keyword string.
625  *
626  * @return Trace reference.
627  **/
628 //--------------------------------------------------------------------------------------------------
629 #define le_log_GetTraceRef(keywordPtr) \
630  _le_log_GetTraceRef(LE_LOG_SESSION, (keywordPtr))
631 
632 
633 //--------------------------------------------------------------------------------------------------
634 /**
635  * Determines if a trace is currently enabled.
636  *
637  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
638  *
639  * @return true if enabled, false if not.
640  **/
641 //--------------------------------------------------------------------------------------------------
642 #define le_log_IsTraceEnabled(traceRef) ((traceRef) == NULL ? false : *((bool *) (traceRef)))
643 
644 
645 //--------------------------------------------------------------------------------------------------
646 /**
647  * Sets the log filter level for the calling component.
648  *
649  * @note Normally not necessary as the log filter level can be controlled at
650  * runtime using the log control tool, and can be persistently configured.
651  * See @ref c_log_controlling.
652  *
653  * @param level [IN] Log filter level to apply to the current log session.
654  **/
655 //--------------------------------------------------------------------------------------------------
656 #define le_log_SetFilterLevel(level) \
657  _le_log_SetFilterLevel(LE_LOG_SESSION, (level))
658 
659 
660 //--------------------------------------------------------------------------------------------------
661 /**
662  * Gets the log filter level for the calling component.
663  **/
664 //--------------------------------------------------------------------------------------------------
665 #define le_log_GetFilterLevel() \
666  ((LE_LOG_LEVEL_FILTER_PTR != NULL)?(*LE_LOG_LEVEL_FILTER_PTR):(LE_LOG_INFO))
667 
668 
669 //--------------------------------------------------------------------------------------------------
670 /**
671  * Enables a trace.
672  *
673  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
674  * log control tool and can be persistently configured. See @ref c_log_controlling.
675  *
676  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
677  *
678  **/
679 //--------------------------------------------------------------------------------------------------
680 #define le_log_EnableTrace(traceRef) \
681  ((void)(*((bool*)(traceRef)) = true))
682 
683 
684 //--------------------------------------------------------------------------------------------------
685 /**
686  * Disables a trace.
687  *
688  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
689  * log control tool and can be persistently configured. See @ref c_log_controlling.
690  *
691  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
692  *
693  **/
694 //--------------------------------------------------------------------------------------------------
695 #define le_log_DisableTrace(traceRef) \
696  ((void)(*((bool*)(traceRef)) = false))
697 
698 #else
699 
700 // If any logging macro is overridden, all logging macros must be overridden.
701 #if !defined(LE_DEBUG)
702 # error "Logging are overridden, but LE_DEBUG not defined. Define LE_DEBUG."
703 #endif
704 
705 #if !defined(LE_DUMP)
706 # error "Logging are overridden, but LE_DUMP not defined. Define LE_DUMP."
707 #endif
708 
709 #if !defined(LE_LOG_DUMP)
710 # error "Logging are overridden, but LE_LOG_DUMP not defined. Define LE_LOG_DUMP."
711 #endif
712 
713 #if !defined(LE_INFO)
714 # error "Logging are overridden, but LE_INFO not defined. Define LE_INFO."
715 #endif
716 
717 #if !defined(LE_WARN)
718 # error "Logging are overridden, but LE_WARN not defined. Define LE_WARN."
719 #endif
720 
721 #if !defined(LE_ERROR)
722 # error "Logging are overridden, but LE_ERROR not defined. Define LE_ERROR."
723 #endif
724 
725 #if !defined(LE_CRIT)
726 # error "Logging are overridden, but LE_CRIT not defined. Define LE_CRIT."
727 #endif
728 
729 #if !defined(LE_EMERG)
730 # error "Logging are overridden, but LE_EMERG not defined. Define LE_EMERG."
731 #endif
732 
733 // If SetFilterLevel is not defined when logging is overridden,
734 // assume it cannot be set programatically
735 #ifndef le_log_SetFilterLevel
736 //--------------------------------------------------------------------------------------------------
737 /**
738  * Sets the log filter level for the calling component.
739  *
740  * @note Normally not necessary as the log filter level can be controlled at
741  * runtime using the log control tool, and can be persistently configured.
742  * See @ref c_log_controlling.
743  *
744  * @param level [IN] Log filter level to apply to the current log session.
745  **/
746 //--------------------------------------------------------------------------------------------------
747 #define le_log_SetFilterLevel(level) ((void)(level))
748 #endif
749 
750 
751 // If le_log_GetFilterLevel is not defined when logging is overridden, assume it
752 // cannot be obtained programatically. In this case code should assume filter level
753 // is equal to static filter level
754 #ifndef le_log_GetFilterLevel
755 //--------------------------------------------------------------------------------------------------
756 /**
757  * Gets the log filter level for the calling component.
758  **/
759 //--------------------------------------------------------------------------------------------------
760 #define le_log_GetFilterLevel() (LE_LOG_LEVEL_STATIC_FILTER)
761 #endif
762 
763 //--------------------------------------------------------------------------------------------------
764 /*
765  * If logging is overridden, disable Legato tracing mechanism. Tracing is noisy and should
766  * not be put into general logs.
767  */
768 //--------------------------------------------------------------------------------------------------
769 
770 //--------------------------------------------------------------------------------------------------
771 /**
772  * Queries whether or not a trace keyword is enabled.
773  *
774  * @return
775  * true if the keyword is enabled.
776  * false otherwise.
777  */
778 //--------------------------------------------------------------------------------------------------
779 #define LE_IS_TRACE_ENABLED(traceRef) (false)
780 
781 
782 //--------------------------------------------------------------------------------------------------
783 /**
784  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
785  */
786 //--------------------------------------------------------------------------------------------------
787 #define LE_TRACE(traceRef, string, ...) ((void)(traceRef))
788 
789 
790 //--------------------------------------------------------------------------------------------------
791 /**
792  * Gets a reference to a trace keyword's settings.
793  *
794  * @param keywordPtr [IN] Pointer to the keyword string.
795  *
796  * @return Trace reference.
797  **/
798 //--------------------------------------------------------------------------------------------------
799 #define le_log_GetTraceRef(keywordPtr) ((le_log_TraceRef_t)NULL)
800 
801 
802 //--------------------------------------------------------------------------------------------------
803 /**
804  * Determines if a trace is currently enabled.
805  *
806  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
807  *
808  * @return true if enabled, false if not.
809  **/
810 //--------------------------------------------------------------------------------------------------
811 #define le_log_IsTraceEnabled(traceRef) (false)
812 
813 
814 //--------------------------------------------------------------------------------------------------
815 /**
816  * Enables a trace.
817  *
818  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
819  * log control tool and can be persistently configured. See @ref c_log_controlling.
820  *
821  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
822  *
823  **/
824 //--------------------------------------------------------------------------------------------------
825 #define le_log_EnableTrace(traceRef) ((void)(0))
826 
827 
828 //--------------------------------------------------------------------------------------------------
829 /**
830  * Disables a trace.
831  *
832  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
833  * log control tool and can be persistently configured. See @ref c_log_controlling.
834  *
835  * @param traceRef [IN] Trace reference obtained from le_log_GetTraceRef()
836  *
837  **/
838 //--------------------------------------------------------------------------------------------------
839 #define le_log_DisableTrace(traceRef) ((void)(0))
840 
841 #endif /* Logging macro override */
842 
843 /// Function that does the real work of translating result codes. See @ref LE_RESULT_TXT.
844 const char* _le_log_GetResultCodeString
845 (
846  le_result_t resultCode ///< [in] Result code value to be translated.
847 );
848 
849 /// Function that exits in a race-free manner -- work around glibc BZ#14333
850 __attribute__((noreturn))
852 (
853  void
854 );
855 
856 //--------------------------------------------------------------------------------------------------
857 /** @internal
858  * The following macros are used to send log messages at different severity levels conditionally.
859  * If the condition is true the message is logged. If the condition is false the message is not
860  * logged.
861  *
862  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
863  * to be printed (depending on the contents of the format string).
864  */
865 //--------------------------------------------------------------------------------------------------
866 
867 /** @ref LE_DEBUG if condition is met. */
868 #define LE_DEBUG_IF(condition, formatString, ...) \
869  if (condition) { LE_DEBUG(formatString, ##__VA_ARGS__); }
870 /** @ref LE_INFO if condition is met. */
871 #define LE_INFO_IF(condition, formatString, ...) \
872  if (condition) { LE_INFO(formatString, ##__VA_ARGS__); }
873 /** @ref LE_WARN if condition is met. */
874 #define LE_WARN_IF(condition, formatString, ...) \
875  if (condition) { LE_WARN(formatString, ##__VA_ARGS__); }
876 /** @ref LE_ERROR if condition is met. */
877 #define LE_ERROR_IF(condition, formatString, ...) \
878  if (condition) { LE_ERROR(formatString, ##__VA_ARGS__); }
879 /** @ref LE_CRIT if condition is met. */
880 #define LE_CRIT_IF(condition, formatString, ...) \
881  if (condition) { LE_CRIT(formatString, ##__VA_ARGS__); }
882 /** @ref LE_EMERG if condition is met. */
883 #define LE_EMERG_IF(condition, formatString, ...) \
884  if (condition) { LE_EMERG(formatString, ##__VA_ARGS__); }
885 
886 
887 //--------------------------------------------------------------------------------------------------
888 /**
889  * Log fatal errors by killing the calling process after logging the message at EMERGENCY
890  * level. This macro never returns.
891  *
892  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
893  * to be printed (depending on the contents of the format string).
894  */
895 //--------------------------------------------------------------------------------------------------
896 #if !LE_CONFIG_DEBUG
897 #define LE_FATAL(formatString, ...) \
898  { LE_EMERG(formatString, ##__VA_ARGS__); _le_log_ExitFatal(); }
899 #else
900 #define LE_FATAL(formatString, ...) \
901  { LE_EMERG(formatString, ##__VA_ARGS__); abort(); }
902 #endif
903 
904 
905 //--------------------------------------------------------------------------------------------------
906 /**
907  * This macro does nothing if the condition is false, otherwise it logs the message at EMERGENCY
908  * level and then kills the calling process.
909  *
910  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
911  * to be printed (depending on the contents of the format string).
912  */
913 //--------------------------------------------------------------------------------------------------
914 #define LE_FATAL_IF(condition, formatString, ...) \
915  if (condition) { LE_FATAL(formatString, ##__VA_ARGS__) }
916 
917 
918 //--------------------------------------------------------------------------------------------------
919 /**
920  * This macro does nothing if the condition is true, otherwise it logs the condition expression as
921  * a message at EMERGENCY level and then kills the calling process.
922  */
923 //--------------------------------------------------------------------------------------------------
924 #define LE_ASSERT(condition) \
925  LE_FATAL_IF(!(condition), "Assert Failed: '%s'", #condition)
926 
927 
928 //--------------------------------------------------------------------------------------------------
929 /**
930  * This macro does nothing if the condition is LE_OK (0), otherwise it logs that the expression did
931  * not evaluate to LE_OK (0) in a message at EMERGENCY level and then kills the calling process.
932  */
933 //--------------------------------------------------------------------------------------------------
934 #define LE_ASSERT_OK(condition) \
935  LE_FATAL_IF((condition) != LE_OK, "Assert Failed: '%s' is not LE_OK (0)", #condition)
936 
937 
938 //--------------------------------------------------------------------------------------------------
939 /**
940  * Get a null-terminated, printable string representing an le_result_t value.
941  *
942  * For example, LE_RESULT_TXT(LE_NOT_PERMITTED) would return a pointer to a string containing
943  * "LE_NOT_PERMITTED".
944  *
945  * "(unknown)" will be returned if the value given is out of range.
946  *
947  * @return Pointer to a string constant.
948  */
949 //--------------------------------------------------------------------------------------------------
950 #define LE_RESULT_TXT(v) _le_log_GetResultCodeString(v)
951 
952 //--------------------------------------------------------------------------------------------------
953 /**
954  * Connects to the Log Control Daemon. This must not be done until after the Messaging system
955  * is initialized, but must be done before the main thread's Event Loop starts to ensure that
956  * all log settings are received from the Log Control Daemon and applied to sessions in the local
957  * process before any component initialization functions are run.
958  */
959 //--------------------------------------------------------------------------------------------------
961 (
962  void
963 );
964 
965 //--------------------------------------------------------------------------------------------------
966 /**
967  * Registers a named component with the logging system.
968  *
969  * @return
970  * A log session reference. This reference must be kept by the component and accessible
971  * through a local macro with the name LE_LOG_SESSION.
972  */
973 //--------------------------------------------------------------------------------------------------
974 LE_FULL_API le_log_SessionRef_t le_log_RegComponent
975 (
976  const char *componentNamePtr, ///< [IN] A pointer to the component's name.
977  le_log_Level_t **levelFilterPtrPtr ///< [OUT] Set to point to the component's level filter.
978 );
979 
980 #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:284
le_result_t
Definition: le_basics.h:45
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.