1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_BASE_C_LOG_H_
28 #define EMBB_BASE_C_LOG_H_
29 
30 #include <embb/base/c/internal/config.h>
31 #include <stdarg.h>
32 
33 /**
34  * \defgroup C_LOG Logging
35  * \ingroup C_BASE
36  * Simple logging facilities.
37  */
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * Log levels available for filtering the log.
45  * \ingroup C_LOG
46  */
47 typedef enum {
48   EMBB_LOG_LEVEL_NONE,                 /**< show no log messages */
49   EMBB_LOG_LEVEL_ERROR,                /**< show errors only */
50   EMBB_LOG_LEVEL_WARNING,              /**< show warnings and errors */
51   EMBB_LOG_LEVEL_INFO,                 /**< show info, warnings, and errors */
52   EMBB_LOG_LEVEL_TRACE                 /**< show everything */
53 } embb_log_level_t;
54 
55 /**
56  * Logging function type.
57  * This function is used by embb_log_write() to transfer a log message to its
58  * desired destination. The user may specify a pointer to a context that
59  * contains additional data (filter rules, file handles etc.) needed to put the
60  * message where it should go. This pointer might be NULL if no additional data
61  * is needed.
62  * \ingroup C_LOG
63  * \threadsafe
64  */
65 typedef void(*embb_log_function_t)(void * context, char const * message);
66 
67 /**
68  * Default logging function.
69  * Writes to the given file (context needs to be a FILE*).
70  * \pre \c context is not NULL.
71  * \ingroup C_LOG
72  * \threadsafe
73  */
74 void embb_log_write_file(
75   void * context,                      /**< [in] User data, in this case a FILE*
76                                             file handle. */
77   char const * message                 /**< [in] The message to write */
78   );
79 
80 /**
81  * Sets the global log level.
82  * This determines what messages will be shown, messages with a more detailed
83  * log level will be filtered out. The default log level is EMBB_LOG_LEVEL_NONE.
84  * \ingroup C_LOG
85  * \notthreadsafe
86  */
87 void embb_log_set_log_level(
88   embb_log_level_t log_level           /**< [in] Log level to use for
89                                             filtering */
90   );
91 
92 /**
93  * Sets the global logging function.
94  * The logging function implements the mechanism for transferring log messages
95  * to their destination. \c context is a pointer to data the user needs in the
96  * function to determine where the messages should go (may be NULL if no
97  * additional data is needed). The default logging function is
98  * embb_log_write_file() with context set to \c stdout.
99  * \see embb_log_function_t
100  * \ingroup C_LOG
101  * \notthreadsafe
102  */
103 void embb_log_set_log_function(
104   void * context,                      /**< [in] User context to supply as the
105                                             first parameter of the logging
106                                             function*/
107   embb_log_function_t func             /**< [in] The logging function */
108   );
109 
110 /**
111  * Logs a message to the given channel with the specified log level.
112  * If the log level is greater than the configured log level for the channel,
113  * the message will be ignored.
114  * \see embb_log_set_log_level, embb_log_set_log_function
115  * \ingroup C_LOG
116  * \threadsafe
117  */
118 void embb_log_write(
119   char const * channel,                /**< [in] User specified channel id
120                                             for filtering the log later on.
121                                             Might be NULL, channel identifier
122                                             will be "global" in that case */
123   embb_log_level_t log_level,          /**< [in] Log level to use */
124   char const * message,                /**< [in] Message to convey, may use
125                                             \c printf style formatting */
126   ...                                  /**< Additional parameters determined by
127                                             the format specifiers in
128                                             \c message */
129   );
130 
131 #if defined(EMBB_DEBUG) || defined(DOXYGEN)
132 /**
133  * Logs a message to the given channel with EMBB_LOG_LEVEL_TRACE using
134  * embb_log_write().
135  * In non-debug builds, this function does nothing.
136  * \see embb_log_write
137  * \ingroup C_LOG
138  * \threadsafe
139  */
140 void embb_log_trace(
141   char const * channel,                /**< [in] User specified channel id */
142   char const * message,                /**< [in] Message to convey, may use
143                                             \c printf style formatting */
144   ...                                  /**< Additional parameters determined by
145                                             the format specifiers in
146                                             \c message */
147   );
148 
149 /**
150  * Logs a message to the given channel with EMBB_LOG_LEVEL_INFO using
151  * embb_log_write().
152  * In non-debug builds, this function does nothing.
153  * \see embb_log_write
154  * \ingroup C_LOG
155  * \threadsafe
156  */
157 void embb_log_info(
158   char const * channel,                /**< [in] User specified channel id */
159   char const * message,                /**< [in] Message to convey, may use
160                                             \c printf style formatting */
161   ...                                  /**< Additional parameters determined by
162                                             the format specifiers in
163                                             \c message */
164   );
165 #else
166 #define embb_log_trace(...)
167 #define embb_log_info(...)
168 #endif
169 
170 /**
171  * Logs a message to the given channel with EMBB_LOG_LEVEL_WARNING using
172  * embb_log_write().
173  * \see embb_log_write
174  * \ingroup C_LOG
175  * \threadsafe
176  */
177 void embb_log_warning(
178   char const * channel,                /**< [in] User specified channel id */
179   char const * message,                /**< [in] Message to convey, may use
180                                             \c printf style formatting */
181   ...                                  /**< Additional parameters determined by
182                                             the format specifiers in
183                                             \c message */
184   );
185 
186 /**
187  * Logs a message to the given channel with EMBB_LOG_LEVEL_ERROR using
188  * embb_log_write().
189  * \see embb_log_write
190  * \ingroup C_LOG
191  * \threadsafe
192  */
193 void embb_log_error(
194   char const * channel,                /**< [in] User specified channel id */
195   char const * message,                /**< [in] Message to convey, may use
196                                             \c printf style formatting */
197   ...                                  /**< Additional parameters determined by
198                                             the format specifiers in
199                                             \c message */
200   );
201 
202 /* function for internal use only */
203 void embb_log_write_internal(
204   char const * channel,
205   embb_log_level_t log_level,
206   char const * message,
207   va_list argp);
208 
209 #ifdef __cplusplus
210 }
211 #endif
212 
213 #endif /* EMBB_BASE_C_LOG_H_ */
214