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