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/<app-name>/<exe-name>/
331  @endverbatim
332 
333 * The path for myApp and myExe would be:
334 
335  @verbatim
336  /tmp/legato_logs/myApp/myExe/
337  @endverbatim
338 
339 * The files in that directory look like this:
340 
341  @verbatim
342  core-myExe-1418694851
343  syslog-1418694851
344  @endverbatim
345 
346 * If the fault action for that app's process is to reboot the target, the output location is changed to
347 * this (and is preserved across reboots):
348 
349  @verbatim
350  /mnt/flash/legato_logs/<app-name>/<exe-name>/
351  @endverbatim
352 
353 * To save on RAM and flash space, only the most recent 4 copies of each file are preserved.
354 *
355  * @todo May need to support log format configuration through command-line arguments or a
356  * configuration file.
357  *
358  * @todo Write @ref c_log_retrieving section
359  *
360  * <HR>
361  *
362  * Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.
363  */
364 
365 
366 /** @file le_log.h
367  *
368  * Legato @ref c_logging include file.
369  *
370  * Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.
371  */
372 
373 #ifndef LEGATO_LOG_INCLUDE_GUARD
374 #define LEGATO_LOG_INCLUDE_GUARD
375 
376 //--------------------------------------------------------------------------------------------------
377 /**
378  * Local definitions that should not be used directly.
379  */
380 //--------------------------------------------------------------------------------------------------
381 typedef enum
382 {
383  LE_LOG_DEBUG, ///< Debug message.
384  LE_LOG_INFO, ///< Informational message. Normally expected.
385  LE_LOG_WARN, ///< Warning. Possibly indicates a problem. Should be addressed.
386  LE_LOG_ERR, ///< Error. Definitely indicates a fault that needs to be addressed.
387  /// Possibly resulted in a system failure.
388  LE_LOG_CRIT, ///< Critical error. Fault that almost certainly has or will result in a
389  /// system failure.
390  LE_LOG_EMERG ///< Emergency. A fatal error has occurred. A process is being terminated.
391 }
393 
394 
395 //--------------------------------------------------------------------------------------------------
396 /// @cond HIDDEN_IN_USER_DOCS
397 
398 typedef struct le_log_Session* le_log_SessionRef_t;
399 
400 typedef struct le_log_Trace* le_log_TraceRef_t;
401 
402 void _le_log_Send
403 (
404  const le_log_Level_t level,
405  const le_log_TraceRef_t traceRef,
406  le_log_SessionRef_t logSession,
407  const char* filenamePtr,
408  const char* functionNamePtr,
409  const unsigned int lineNumber,
410  const char* formatPtr,
411  ...
412 ) __attribute__ ((format (printf, 7, 8)));
413 
414 le_log_TraceRef_t _le_log_GetTraceRef
415 (
416  le_log_SessionRef_t logSession,
417  const char* keyword
418 );
419 
420 void _le_log_SetFilterLevel
421 (
422  le_log_SessionRef_t logSession,
423  le_log_Level_t level
424 );
425 
426 
427 //--------------------------------------------------------------------------------------------------
428 /**
429  * Filtering session reference for the current source file.
430  *
431  * @note The real name of this is passed in by the build system. This way it can be a unique
432  * variable for each component.
433  */
434 //--------------------------------------------------------------------------------------------------
435 #ifdef __cplusplus
436 extern
437 #endif
438 LE_SHARED le_log_SessionRef_t LE_LOG_SESSION;
439 
440 //--------------------------------------------------------------------------------------------------
441 /**
442  * Filtering level for the current source file.
443  *
444  * @note The real name of this is passed in by the build system. This way it can be a unique
445  * variable for each component.
446  */
447 //--------------------------------------------------------------------------------------------------
448 #ifdef __cplusplus
449 extern
450 #endif
451 LE_SHARED le_log_Level_t* LE_LOG_LEVEL_FILTER_PTR;
452 
453 
454 /// @endcond
455 //--------------------------------------------------------------------------------------------------
456 
457 //--------------------------------------------------------------------------------------------------
458 /**
459  * Internal macro to filter out messages that do not meet the current filtering level.
460  */
461 //--------------------------------------------------------------------------------------------------
462 #define _LE_LOG_MSG(level, formatString, ...) \
463  do { \
464  if ((LE_LOG_LEVEL_FILTER_PTR == NULL) || (level >= *LE_LOG_LEVEL_FILTER_PTR)) \
465  _le_log_Send(level, NULL, LE_LOG_SESSION, __FILE__, __func__, __LINE__, \
466  formatString, ##__VA_ARGS__); \
467  } while(0)
468 
469 
470 //--------------------------------------------------------------------------------------------------
471 /** @internal
472  * The following macros are used to send log messages at different severity levels:
473  *
474  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
475  * to be printed (depending on the contents of the format string).
476  */
477 //--------------------------------------------------------------------------------------------------
478 
479 /** @copydoc LE_LOG_DEBUG */
480 #define LE_DEBUG(formatString, ...) _LE_LOG_MSG(LE_LOG_DEBUG, formatString, ##__VA_ARGS__)
481 /** @copydoc LE_LOG_INFO */
482 #define LE_INFO(formatString, ...) _LE_LOG_MSG(LE_LOG_INFO, formatString, ##__VA_ARGS__)
483 /** @copydoc LE_LOG_WARN */
484 #define LE_WARN(formatString, ...) _LE_LOG_MSG(LE_LOG_WARN, formatString, ##__VA_ARGS__)
485 /** @copydoc LE_LOG_ERR */
486 #define LE_ERROR(formatString, ...) _LE_LOG_MSG(LE_LOG_ERR, formatString, ##__VA_ARGS__)
487 /** @copydoc LE_LOG_CRIT */
488 #define LE_CRIT(formatString, ...) _LE_LOG_MSG(LE_LOG_CRIT, formatString, ##__VA_ARGS__)
489 /** @copydoc LE_LOG_EMERG */
490 #define LE_EMERG(formatString, ...) _LE_LOG_MSG(LE_LOG_EMERG, formatString, ##__VA_ARGS__)
491 
492 
493 //--------------------------------------------------------------------------------------------------
494 /** @internal
495  * The following macros are used to send log messages at different severity levels conditionally.
496  * If the condition is true the message is logged. If the condition is false the message is not
497  * logged.
498  *
499  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
500  * to be printed (depending on the contents of the format string).
501  */
502 //--------------------------------------------------------------------------------------------------
503 
504 /** @ref LE_DEBUG if condition is met. */
505 #define LE_DEBUG_IF(condition, formatString, ...) \
506  if (condition) { _LE_LOG_MSG(LE_LOG_DEBUG, formatString, ##__VA_ARGS__); }
507 /** @ref LE_INFO if condition is met. */
508 #define LE_INFO_IF(condition, formatString, ...) \
509  if (condition) { _LE_LOG_MSG(LE_LOG_INFO, formatString, ##__VA_ARGS__); }
510 /** @ref LE_WARN if condition is met. */
511 #define LE_WARN_IF(condition, formatString, ...) \
512  if (condition) { _LE_LOG_MSG(LE_LOG_WARN, formatString, ##__VA_ARGS__); }
513 /** @ref LE_ERROR if condition is met. */
514 #define LE_ERROR_IF(condition, formatString, ...) \
515  if (condition) { _LE_LOG_MSG(LE_LOG_ERR, formatString, ##__VA_ARGS__); }
516 /** @ref LE_CRIT if condition is met. */
517 #define LE_CRIT_IF(condition, formatString, ...) \
518  if (condition) { _LE_LOG_MSG(LE_LOG_CRIT, formatString, ##__VA_ARGS__); }
519 /** @ref LE_EMERG if condition is met. */
520 #define LE_EMERG_IF(condition, formatString, ...) \
521  if (condition) { _LE_LOG_MSG(LE_LOG_EMERG, formatString, ##__VA_ARGS__); }
522 
523 
524 //--------------------------------------------------------------------------------------------------
525 /**
526  * Log fatal errors by killing the calling process after logging the message at EMERGENCY
527  * level. This macro never returns.
528  *
529  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
530  * to be printed (depending on the contents of the format string).
531  */
532 //--------------------------------------------------------------------------------------------------
533 #define LE_FATAL(formatString, ...) \
534  { LE_EMERG(formatString, ##__VA_ARGS__); exit(EXIT_FAILURE); }
535 
536 
537 //--------------------------------------------------------------------------------------------------
538 /**
539  * This macro does nothing if the condition is false, otherwise it logs the message at EMERGENCY
540  * level and then kills the calling process.
541  *
542  * Accepts printf-style arguments, consisting of a format string followed by zero or more parameters
543  * to be printed (depending on the contents of the format string).
544  */
545 //--------------------------------------------------------------------------------------------------
546 #define LE_FATAL_IF(condition, formatString, ...) \
547  if (condition) { LE_FATAL(formatString, ##__VA_ARGS__) }
548 
549 
550 //--------------------------------------------------------------------------------------------------
551 /**
552  * This macro does nothing if the condition is true, otherwise it logs the condition expression as
553  * a message at EMERGENCY level and then kills the calling process.
554  */
555 //--------------------------------------------------------------------------------------------------
556 #define LE_ASSERT(condition) \
557  if (!(condition)) { LE_FATAL("Assert Failed: '%s'", #condition) }
558 
559 
560 //--------------------------------------------------------------------------------------------------
561 /**
562  * This macro does nothing if the condition is LE_OK (0), otherwise it logs that the expression did
563  * not evaluate to LE_OK (0) in a message at EMERGENCY level and then kills the calling process.
564  */
565 //--------------------------------------------------------------------------------------------------
566 #define LE_ASSERT_OK(condition) \
567  if ((condition) != LE_OK) { LE_FATAL("Assert Failed: '%s' is not LE_OK (0)", #condition) }
568 
569 
570 //--------------------------------------------------------------------------------------------------
571 /**
572  * Get a null-terminated, printable string representing an le_result_t value.
573  *
574  * For example, LE_RESULT_TXT(LE_NOT_PERMITTED) would return a pointer to a string containing
575  * "LE_NOT_PERMITTED".
576  *
577  * "(unknown)" will be returned if the value given is out of range.
578  *
579  * @return Pointer to a string constant.
580  */
581 //--------------------------------------------------------------------------------------------------
582 #define LE_RESULT_TXT(v) _le_log_GetResultCodeString(v)
583 
584 /// Function that does the real work of translating result codes. See @ref LE_RESULT_TXT.
585 const char* _le_log_GetResultCodeString
586 (
587  le_result_t resultCode ///< [in] Result code value to be translated.
588 );
589 
590 
591 //--------------------------------------------------------------------------------------------------
592 /**
593  * Queries whether or not a trace keyword is enabled.
594  *
595  * @return
596  * true if the keyword is enabled.
597  * false otherwise.
598  */
599 //--------------------------------------------------------------------------------------------------
600 #define LE_IS_TRACE_ENABLED(traceRef) (le_log_IsTraceEnabled(traceRef))
601 
602 
603 //--------------------------------------------------------------------------------------------------
604 /**
605  * Logs the string if the keyword has been enabled by a runtime tool or configuration setting.
606  */
607 //--------------------------------------------------------------------------------------------------
608 #define LE_TRACE(traceRef, string, ...) \
609  if (le_log_IsTraceEnabled(traceRef)) \
610  { \
611  _le_log_Send((le_log_Level_t)-1, \
612  traceRef, \
613  LE_LOG_SESSION, \
614  __FILE__, \
615  __func__, \
616  __LINE__, \
617  string, \
618  ##__VA_ARGS__); \
619  }
620 
621 
622 //--------------------------------------------------------------------------------------------------
623 /**
624  * Gets a reference to a trace keyword's settings.
625  *
626  * @return Trace reference.
627  **/
628 //--------------------------------------------------------------------------------------------------
629 static inline le_log_TraceRef_t le_log_GetTraceRef
630 (
631  const char* keywordPtr ///< [IN] Pointer to the keyword string.
632 )
633 {
634  return _le_log_GetTraceRef(LE_LOG_SESSION, keywordPtr);
635 }
636 
637 
638 //--------------------------------------------------------------------------------------------------
639 /**
640  * Determines if a trace is currently enabled.
641  *
642  * @return true if enabled, false if not.
643  **/
644 //--------------------------------------------------------------------------------------------------
645 static inline bool le_log_IsTraceEnabled
646 (
647  const le_log_TraceRef_t traceRef ///< [IN] Trace reference obtained from le_log_GetTraceRef().
648 )
649 {
650  return *((bool*)traceRef);
651 }
652 
653 
654 //--------------------------------------------------------------------------------------------------
655 /**
656  * Sets the log filter level for the calling component.
657  *
658  * @note Normally not necessary as the log filter level can be controlled at
659  * runtime using the log control tool, and can be persistently configured.
660  * See @ref c_log_controlling.
661  **/
662 //--------------------------------------------------------------------------------------------------
663 static inline void le_log_SetFilterLevel
664 (
665  le_log_Level_t level ///< [IN] Log filter level to apply to the current log session.
666 )
667 {
668  _le_log_SetFilterLevel(LE_LOG_SESSION, level);
669 }
670 
671 
672 //--------------------------------------------------------------------------------------------------
673 /**
674  * Gets the log filter level for the calling component.
675  **/
676 //--------------------------------------------------------------------------------------------------
678 (
679  void
680 )
681 {
682  if (LE_LOG_LEVEL_FILTER_PTR != NULL)
683  {
684  return *LE_LOG_LEVEL_FILTER_PTR;
685  }
686  else
687  {
688  return LE_LOG_INFO; // Default.
689  }
690 }
691 
692 
693 //--------------------------------------------------------------------------------------------------
694 /**
695  * Enables a trace.
696  *
697  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
698  * log control tool and can be persistently configured. See @ref c_log_controlling.
699  **/
700 //--------------------------------------------------------------------------------------------------
701 static inline void le_log_EnableTrace
702 (
703  const le_log_TraceRef_t traceRef ///< [IN] Trace reference obtained from le_log_GetTraceRef().
704 )
705 {
706  *((bool*)traceRef) = true;
707 }
708 
709 
710 //--------------------------------------------------------------------------------------------------
711 /**
712  * Disables a trace.
713  *
714  * @note Normally, this is not necessary, since traces can be enabled at runtime using the
715  * log control tool and can be persistently configured. See @ref c_log_controlling.
716  **/
717 //--------------------------------------------------------------------------------------------------
718 static inline void le_log_DisableTrace
719 (
720  const le_log_TraceRef_t traceRef ///< [IN] Trace reference obtained from le_log_GetTraceRef()
721 )
722 {
723  *((bool*)traceRef) = false;
724 }
725 
726 
727 
728 #endif // LEGATO_LOG_INCLUDE_GUARD
static le_log_TraceRef_t le_log_GetTraceRef(const char *keywordPtr)
Definition: le_log.h:630
#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:702
static le_log_Level_t le_log_GetFilterLevel(void)
Definition: le_log.h:678
Warning. Possibly indicates a problem. Should be addressed.
Definition: le_log.h:385
le_log_Level_t
Definition: le_log.h:381
Debug message.
Definition: le_log.h:383
static void le_log_SetFilterLevel(le_log_Level_t level)
Definition: le_log.h:664
Definition: le_log.h:386
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:388
Informational message. Normally expected.
Definition: le_log.h:384
Emergency. A fatal error has occurred. A process is being terminated.
Definition: le_log.h:390
static bool le_log_IsTraceEnabled(const le_log_TraceRef_t traceRef)
Definition: le_log.h:646
static void le_log_DisableTrace(const le_log_TraceRef_t traceRef)
Definition: le_log.h:719