le_log.h

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