16 // Yes, it's a bit ugly.
17 #define SYSLOG_FAKE_FILE (static_cast<FILE *>(NULL))
19 bool logging_started = false;
20 std::vector<FILE *> log_destinations;
22 void add_log_destination_file(const std::string &filename)
24 FILE *fp = fopen(filename.c_str(), "a");
26 perror(filename.c_str());
30 log_destinations.push_back(fp);
33 void add_log_destination_console()
35 log_destinations.push_back(stderr);
38 void add_log_destination_syslog()
40 openlog("cubemap", LOG_PID, LOG_DAEMON);
41 log_destinations.push_back(SYSLOG_FAKE_FILE);
46 logging_started = true;
49 void shut_down_logging()
51 for (size_t i = 0; i < log_destinations.size(); ++i) {
52 if (log_destinations[i] == SYSLOG_FAKE_FILE) {
54 } else if (log_destinations[i] != stderr) {
55 if (fclose(log_destinations[i]) != 0) {
60 log_destinations.clear();
61 logging_started = false;
64 void log(LogLevel log_level, const char *fmt, ...)
66 char formatted_msg[4096];
69 vsnprintf(formatted_msg, sizeof(formatted_msg), fmt, ap);
72 time_t now = time(NULL);
74 struct tm *ltime = localtime_r(&now, <);
77 strcpy(timestamp, "???");
79 strftime(timestamp, sizeof(timestamp), "%a, %d %b %Y %T %z", ltime);
82 const char *log_level_str;
87 log_level_str = "INFO: ";
88 syslog_level = LOG_INFO;
91 log_level_str = "WARNING: ";
92 syslog_level = LOG_WARNING;
95 log_level_str = "ERROR: ";
96 syslog_level = LOG_ERR;
102 // Log to stderr if logging hasn't been set up yet. Note that this means
103 // that such messages will come even if there are no “error_log” lines.
104 if (!logging_started) {
105 fprintf(stderr, "[%s] %s%s\n", timestamp, log_level_str, formatted_msg);
109 for (size_t i = 0; i < log_destinations.size(); ++i) {
110 if (log_destinations[i] == SYSLOG_FAKE_FILE) {
111 syslog(syslog_level, "%s", formatted_msg);
113 int err = fprintf(log_destinations[i], "[%s] %s%s\n", timestamp, log_level_str, formatted_msg);
117 if (log_destinations[i] != stderr) {
118 fflush(log_destinations[i]);
124 void log_perror(const char *msg)
127 log(ERROR, "%s: %s", msg, strerror_r(errno, errbuf, sizeof(errbuf)));