+
+/**
+ * The log function for para_server and para_audiod.
+ *
+ * \param ll The log level.
+ * \param fmt The format string describing the log message.
+ */
+__printf_2_3 void daemon_log(int ll, const char* fmt,...)
+{
+ va_list argp;
+ FILE *fp;
+ struct tm *tm;
+ char *color;
+ bool log_time = daemon_test_flag(DF_LOG_TIME), log_timing =
+ daemon_test_flag(DF_LOG_TIMING);
+
+ ll = PARA_MIN(ll, NUM_LOGLEVELS - 1);
+ ll = PARA_MAX(ll, LL_DEBUG);
+ if (ll < me->loglevel)
+ return;
+
+ fp = me->logfile? me->logfile : stderr;
+ color = daemon_test_flag(DF_COLOR_LOG)? me->log_colors[ll] : NULL;
+ if (color)
+ fprintf(fp, "%s", color);
+ if (log_time || log_timing) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ if (daemon_test_flag(DF_LOG_TIME)) { /* print date and time */
+ time_t t1 = tv.tv_sec;
+ char str[100];
+ tm = localtime(&t1);
+ strftime(str, sizeof(str), "%b %d %H:%M:%S", tm);
+ fprintf(fp, "%s%s", str, log_timing? ":" : " ");
+ }
+ if (log_timing) /* print milliseconds */
+ fprintf(fp, "%04lu ", (long unsigned)tv.tv_usec / 1000);
+ }
+ if (daemon_test_flag(DF_LOG_HOSTNAME)) {
+ if (!me->hostname)
+ me->hostname = para_hostname();
+ fprintf(fp, "%s ", me->hostname);
+ }
+ if (daemon_test_flag(DF_LOG_LL)) /* log loglevel */
+ fprintf(fp, "(%d) ", ll);
+ if (daemon_test_flag(DF_LOG_PID)) { /* log pid */
+ pid_t mypid = getpid();
+ fprintf(fp, "(%d) ", (int)mypid);
+ }
+ va_start(argp, fmt);
+ vfprintf(fp, fmt, argp);
+ va_end(argp);
+ if (color)
+ fprintf(fp, "%s", COLOR_RESET);
+}