Here's an excerpt from a past project that I found to work well for me. Some initialization steps are of course missing. The key here is the vfprintf
function which will handle the details of printing the various arguments.
void _proxy_log(log_level_t level, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
#define proxy_log(level, fmt, ...) _proxy_log(level, fmt"\n", ##__VA_ARGS__)
void _proxy_log(log_level_t level, const char *fmt, ...) {
va_list arg;
FILE *log_file = (level == LOG_ERROR) ? err_log : info_log;
/* Check if the message should be logged */
if (level > log_level)
return;
/* Write the error message */
va_start(arg, fmt);
vfprintf(log_file, fmt, arg);
va_end(arg);
#ifdef DEBUG
fflush(log_file);
fsync(fileno(log_file));
#endif
}