Flexible Logging¶
Background¶
Logging is often an afterthought. Trace, info, warnings, and errors, all sent to stdout or stderr. The C-Craft library provides a flexible logging system that can be quickly changed to target a file, or syslog, or disabled completely or partially with just one or two lines of code.
File Logs¶
#include <c-craft/app.h>
void main(int argc, char **argv)
{
MEM_SCOPE mem = sm_create(0);
LOG log = log_file_create(mem, "myapp-log.txt");
const char *app = get_program_name();
const char *host = get_host_name();
log_printf(log, L_INFO, "'%s' starting up on %s", app, host);
. . .
log_printf(log, L_INFO, "'%s' on %s. Processing complete.", app, host);
log_close(log);
sm_free(mem);
}
This example writes two lines to the log file ‘myapp-log.txt’ with severity and timestamp.
If, at a later time you decide to write to the syslog instead, you change one line of code.
LOG log = log_sys_create(mem, 0, LOG_USER);
Other Logs¶
There are other options too.
/* Log to FILE stream. */
LOG log = log_fp_create(mem, stdout);
/* Log to standard output/error. Writes L_FATAL, L_ERROR, and L_WARN
* to stderr, and L_INFO, L_TRACE to stdout.
*/
LOG log = log_std_create(mem);
Note that it is good practise to close a log. The log_fp is created with an open FILE, so closing a log_fp does not close the open FILE.
Custom Logs¶
If you need your own custom logging.
/* Log to a custom log. */
void my_log_write(LOG_CTRL log, LOG_LEVEL level, const char* message);
void my_log_close(LOG_CTRL log);
LOG_CTRL ctrl = my_log;
LOG log = log_gen_create(mem, my_log, my_log_write, my_log_close);
/* Here my_log is a pointer to your own struct that carries data about
* your log, and is passed to the my_log_write and my_log_close functions.
* It might be a database reference, for example, depending on your log.
*/
Now when you write using log_printf(log, …) the logging system will call your custom write function. The close function can be NULL, if it is meaningless for your logger.
