12 // Yes, it's a bit ugly.
13 #define SYSLOG_FAKE_FILE (static_cast<FILE *>(NULL))
15 bool logging_started = false;
16 std::vector<FILE *> log_destinations;
18 void add_log_destination_file(const std::string &filename)
20 FILE *fp = fopen(filename.c_str(), "a");
22 perror(filename.c_str());
26 log_destinations.push_back(fp);
29 void add_log_destination_console()
31 log_destinations.push_back(stderr);
34 void add_log_destination_syslog()
36 openlog("cubemap", LOG_PID, LOG_DAEMON);
37 log_destinations.push_back(SYSLOG_FAKE_FILE);
42 logging_started = true;
45 void shut_down_logging()
47 for (size_t i = 0; i < log_destinations.size(); ++i) {
48 if (log_destinations[i] == SYSLOG_FAKE_FILE) {
50 } else if (log_destinations[i] != stderr) {
51 if (fclose(log_destinations[i]) != 0) {
56 log_destinations.clear();
57 logging_started = false;
60 void log(LogLevel log_level, const char *fmt, ...)
62 char formatted_msg[4096];
65 vsnprintf(formatted_msg, sizeof(formatted_msg), fmt, ap);
68 const char *log_level_str;
74 syslog_level = LOG_INFO;
77 log_level_str = "INFO: ";
78 syslog_level = LOG_INFO;
81 log_level_str = "WARNING: ";
82 syslog_level = LOG_WARNING;
85 log_level_str = "ERROR: ";
86 syslog_level = LOG_ERR;
92 // Log to stderr if logging hasn't been set up yet. Note that this means
93 // that such messages will come even if there are no “error_log” lines.
94 if (!logging_started) {
95 fprintf(stderr, "%s%s\n", log_level_str, formatted_msg);
99 for (size_t i = 0; i < log_destinations.size(); ++i) {
100 if (log_destinations[i] == SYSLOG_FAKE_FILE) {
101 syslog(syslog_level, "%s", formatted_msg);
103 int err = fprintf(log_destinations[i], "%s%s\n", log_level_str, formatted_msg);
107 if (log_destinations[i] != stderr) {
108 fflush(log_destinations[i]);