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