2 //! @brief Flog - The F logging library
3 //! @author Nabeel Sowan (nabeel.sowan@vibes.se)
5 //! Useful as the main logger of a program
10 /* FLOG_MSG_TYPE_ENUM_API allows switching to an enum API for flog.
11 What this means is that FLOG_MSG_TYPE_T will be defined as an int
12 (instead of unsigned char) In return, enums may yield stronger
13 type checking and therefore easier debugging. */
15 #ifdef FLOG_MSG_TYPE_ENUM_API
17 typedef enum flog_msg_type
{
19 FLOG_NOTHING
= FLOG_NONE
,
22 FLOG_CRITICAL
= FLOG_CRIT
,
25 FLOG_ERROR
= FLOG_ERR
,
28 FLOG_WARNING
= FLOG_WARN
,
29 FLOG_ALERT
= FLOG_WARN
,
32 FLOG_NOTIFY
= FLOG_NOTE
,
34 FLOG_IMPORTANT
= FLOG_NOTE
,
37 FLOG_INFORMATION
= FLOG_INFO
,
39 FLOG_MESSAGE
= FLOG_INFO
,
42 FLOG_VERBOSE
= FLOG_VINFO
,
46 FLOG_FLOG_DEBUG
= 0x80,
48 FLOG_ACCEPT_ONLY_CRITICAL
= FLOG_CRIT
,
49 FLOG_ACCEPT_ONLY_ERROR
= FLOG_CRIT
| FLOG_ERR
,
50 FLOG_ACCEPT_ERROR_AND_WARNING
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
,
51 FLOG_ACCEPT_IMPORTANT_NOTES
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
| FLOG_NOTE
,
52 FLOG_ACCEPT_INFO
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
| FLOG_NOTE
| FLOG_INFO
,
53 FLOG_ACCEPT_VERBOSE_INFO
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
| FLOG_NOTE
| FLOG_INFO
| FLOG_VINFO
,
54 FLOG_ACCEPT_ALL
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
| FLOG_NOTE
| FLOG_INFO
| FLOG_VINFO
| FLOG_DEBUG
,
55 FLOG_ACCEPT_FLOG_DEBUG
= FLOG_CRIT
| FLOG_ERR
| FLOG_WARN
| FLOG_NOTE
| FLOG_INFO
| FLOG_VINFO
| FLOG_DEBUG
| FLOG_FLOG_DEBUG
58 #else /* FLOG_MSG_TYPE_ENUM_API */
60 //! @addtogroup FLOG_MSG_TYPE_T
61 //! @brief Types of messages supported by FLOG
62 //! @details Use where ever a @ref FLOG_MSG_TYPE_T is referred
65 typedef unsigned char FLOG_MSG_TYPE_T
;
68 #define FLOG_NONE 0x00
69 #define FLOG_NOTHING FLOG_NONE
72 #define FLOG_CRIT 0x01
73 #define FLOG_CRITICAL FLOG_CRIT
77 #define FLOG_ERROR FLOG_ERR
80 #define FLOG_WARN 0x04
81 #define FLOG_WARNING FLOG_WARN
82 #define FLOG_ALERT FLOG_WARN
85 #define FLOG_NOTE 0x08
86 #define FLOG_NOTIFY FLOG_NOTE
87 #define FLOG_IMP FLOG_NOTE
88 #define FLOG_IMPORTANT FLOG_NOTE
91 #define FLOG_INFO 0x10
92 #define FLOG_INFORMATION FLOG_INFO
93 #define FLOG_MSG FLOG_INFO
94 #define FLOG_MESSAGE FLOG_INFO
96 //! Info in verbose mode
97 #define FLOG_VINFO 0x20
98 #define FLOG_VERBOSE FLOG_VINFO
101 #define FLOG_DEBUG 0x40
103 //! Debug info for flog itself
104 #define FLOG_FLOG_DEBUG 0x80
109 //! @addtogroup FLOG_ACCEPT_BITMASKS
110 //! @brief Bitmasks for filtering messages
111 //! @details Set the variable @ref FLOG_T->accepted_message_type
114 //! Bitmask to accept only critical
115 #define FLOG_ACCEPT_ONLY_CRITICAL FLOG_CRIT
116 //! Bitmask to accept only errors
117 #define FLOG_ACCEPT_ONLY_ERROR FLOG_CRIT | FLOG_ERR
118 //! Bitmask to accept error and warning
119 #define FLOG_ACCEPT_ERROR_AND_WARNING FLOG_CRIT | FLOG_ERR | FLOG_WARN
120 //! Bitmask to accept all important messages
121 #define FLOG_ACCEPT_IMPORTANT_NOTE FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE
122 //! Bitmask to accept informational messages
123 #define FLOG_ACCEPT_INFO FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO
124 //! Bitmask to accept verbose messages
125 #define FLOG_ACCEPT_VERBOSE_INFO FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO
126 //! Bitmask to accept all messages (except flog internal debug)
127 #define FLOG_ACCEPT_ALL FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG
128 //! Bitmask to accept all messages
129 #define FLOG_ACCEPT_FLOG_DEBUG FLOG_CRIT | FLOG_ERR | FLOG_WARN | FLOG_NOTE | FLOG_INFO | FLOG_VINFO | FLOG_DEBUG | FLOG_FLOG_DEBUG
133 #endif /* FLOG_MSG_TYPE_ENUM_API */
135 // Macros to insert source info into print strings
136 // Maybe it is better to use __func__ than __FUNCTION__ ?
138 //! emit an flog message
140 //! use this when you need to emit simple text messages and flog_printf() when formatting is needed
141 //! @param[out] p log to emit message to
142 //! @param[in] type use one of the FLOG_* defines
143 //! @param[in] subsystem which part of the program is outputing this message
144 //! @param[in] text message text
145 //! @retval 0 success
146 //! @see _flog_print(), flog_printf(), flog_dprint()
148 #define flog_print(p, type, subsystem, text) _flog_print (p, __FILE__, __LINE__, __FUNCTION__, type, subsystem, text)
150 #define flog_print(p, type, subsystem, text) _flog_print (p, type, subsystem, text)
153 //! emit a formatted flog message (calls flog_print())
155 //! use this when you need to emit formatted text messages and flog_print() when no formatting is needed
156 //! @param[out] p log to emit message to
157 //! @param[in] type use one of the FLOG_* defines
158 //! @param[in] subsystem which part of the program is outputing this message
159 //! @param[in] ... formatted message text
160 //! @retval 0 success
161 //! @see _flog_printf(), flog_print(), flog_dprintf()
163 #define flog_printf(p, type, subsystem, ...) _flog_printf (p, __FILE__, __LINE__, __FUNCTION__, type, subsystem, __VA_ARGS__)
165 #define flog_printf(p, type, subsystem, ...) _flog_printf (p, type, subsystem, __VA_ARGS__)
168 //! Macro for flog assert functionality
170 //! @param[out] p log to emit message to
171 //! @param[in] cond statement to evaluate
172 #define flog_assert(p, cond) ((cond) || flog_printf(p,FLOG_ERROR,"assert","Assertion failed: %s",#cond))
174 // Macros to allow removal of messages from release builds
175 //! Same as flog_print() but only defined if DEBUG is set
177 //! Use this macro to allow removal of messages from release builds
178 //! @see flog_print()
180 #define flog_dprint(p, type, subsystem, text) flog_print (p, type, subsystem, text)
182 #define flog_dprint(p, type, subsystem, text)
185 //! Same as flog_printf() but only defined if DEBUG is set
187 //! Use this macro to allow removal of messages from release builds
188 //! @see flog_printf()
190 #define flog_dprintf(p, type, subsystem, ...) flog_printf (p, type, subsystem, __VA_ARGS__)
192 #define flog_dprintf(p, type, subsystem, ...)
195 #ifdef FLOG_TIMESTAMP
196 typedef int FLOG_TIMESTAMP_T
;
199 //! Message structure - Holds all data related to a single message
201 #ifdef FLOG_TIMESTAMP
202 FLOG_TIMESTAMP_T time
; //!< timestamp
205 char *src_file
; //!< source file emitting message
206 int src_line
; //!< source line number emitting message
207 char *src_func
; //!< source function emitting message
209 FLOG_MSG_TYPE_T type
; //!< type of message
210 char *subsystem
; //!< subsystem which is outputting the msg
211 char *text
; //!< message contents
214 //! Main log structure - typedefined as @ref FLOG_T
216 //! These can be appended to each other in a tree structure (by using flog_append_sublog())
217 //! to form good flow and structure in software.
218 //! Sublogs are created for 3 main purposes: namespacing, multiple outputs and filtering
219 typedef struct flog_t
{
220 char *name
; //!< name of log
221 FLOG_MSG_TYPE_T accepted_msg_type
; //!< bitmask of which messages to accept
222 int (*output_func
)(struct flog_t
*,const FLOG_MSG_T
*); //!< function to output messages to
223 void *output_func_data
; //!< data passed to output func
224 int output_error
; //!< errors occurred on output
225 int output_stop_on_error
; //!< stop outputting messages on error
226 struct flog_t
*error_log
; //!< error log for flog errors
227 FLOG_MSG_T
**msg
; //!< array of messages
228 int msg_amount
; //!< amount of messages in array
229 int msg_max
; //!< maximum amount of buffered messages
230 struct flog_t
**sublog
; //!< array of sublogs
231 int sublog_amount
; //!< amount of sublogs in array
234 void init_flog_msg_t(FLOG_MSG_T
*p
);
236 FLOG_MSG_T
* create_flog_msg_t(const char *src_file
,int src_line
,const char *src_func
,FLOG_MSG_TYPE_T msg_type
,const char *subsystem
,const char *text
);
238 FLOG_MSG_T
* create_flog_msg_t(FLOG_MSG_TYPE_T msg_type
,const char *subsystem
,const char *text
);
240 void destroy_flog_msg_t(FLOG_MSG_T
*p
);
242 void init_flog_t(FLOG_T
*p
);
243 FLOG_T
* create_flog_t(const char *name
, FLOG_MSG_TYPE_T accepted_msg_type
);
244 void destroy_flog_t(FLOG_T
*p
);
246 int flog_add_msg(FLOG_T
*p
,FLOG_MSG_T
*msg
);
247 void flog_clear_msg_buffer(FLOG_T
*p
);
248 int flog_append_sublog(FLOG_T
*p
,FLOG_T
*sublog
);
251 int _flog_print(FLOG_T
*p
,const char *src_file
,int src_line
,const char *src_func
,FLOG_MSG_TYPE_T type
,const char *subsystem
,const char *text
);
252 int _flog_printf(FLOG_T
*p
,const char *src_file
,int src_line
,const char *src_func
,FLOG_MSG_TYPE_T type
,const char *subsystem
,const char *textf
, ...);
254 int _flog_print(FLOG_T
*p
,FLOG_MSG_TYPE_T type
,const char *subsystem
,const char *text
);
255 int _flog_printf(FLOG_T
*p
,FLOG_MSG_TYPE_T type
,const char *subsystem
,const char *textf
, ...);
258 char * flog_msg_t_to_str(const FLOG_MSG_T
*p
);
259 char * flog_get_msg_type_str(FLOG_MSG_TYPE_T type
);
260 void flog_test(FLOG_T
*p
);
262 #ifdef FLOG_TIMESTAMP
263 const char * get_timestamp(void);