00001 #include "config.h" 00002 00003 #ifdef HAVE_UNISTD_H 00004 #include <unistd.h> 00005 #endif 00006 00007 #include <iostream> 00008 #include <string> 00009 #include <fstream> 00010 00011 #include "asserts.h" 00012 #include "error.h" 00013 #include "timer.h" 00014 #include "rconfig.h" 00015 #include "estring.h" 00016 00017 #include "logger.h" 00018 00019 //----------------------------------------------------------------------------- 00020 00021 /** C'tor */ 00022 log_manager::log_manager() 00023 { 00024 if (this != &logger) 00025 throw( 00026 INTERNAL_ERROR(0,"Attempt to allocate multiple log managers") 00027 ); 00028 clear(); 00029 } 00030 00031 /** Clear the log manager */ 00032 void log_manager::clear(void) 00033 { 00034 m_new_line = true; 00035 if (m_out.is_open()) 00036 m_out.close(); 00037 m_use_error_logging_level = false; 00038 m_initialized = false; 00039 } 00040 00041 /** Initialize the log manager */ 00042 void log_manager::init(void) 00043 { 00044 std::string es; 00045 std::string filename; 00046 bool done = false; 00047 int count = 0; 00048 estring str; 00049 00050 00051 done = false; 00052 while (!done) { 00053 TRY_nomem(filename = config.log_dir()); 00054 TRY_nomem(filename += "/"); 00055 TRY_nomem(filename += config.timestamp().str()); 00056 if (config.action() == configuration_manager::action_archive) { 00057 TRY_nomem(filename += ".log"); 00058 } 00059 else if (config.action() == configuration_manager::action_relink) { 00060 TRY_nomem(filename += ".relink"); 00061 } 00062 if (count != 0) { 00063 TRY_nomem(filename += "."); 00064 TRY_nomem(filename += estring(count)); 00065 } 00066 if (exists(filename)) 00067 ++count; 00068 else 00069 done = true; 00070 } 00071 m_out.open(filename.c_str()); 00072 if (!m_out.is_open()) { 00073 TRY_nomem(es = "Could not open log file: \""); 00074 TRY_nomem(es += filename); 00075 TRY_nomem(es += "\""); 00076 throw(ERROR(errno,es)); 00077 } 00078 00079 m_use_error_logging_level = false; 00080 00081 m_initialized = true; 00082 00083 str = "Rsync Vault Manager - "; 00084 str += VERSION; 00085 str += '\n'; 00086 logger.write(str); 00087 } 00088 00089 /** The initialized state of the log manager */ 00090 const bool log_manager::initialized(void) const 00091 { 00092 return(m_initialized); 00093 } 00094 00095 /** Write a string to the log file */ 00096 void log_manager::write( 00097 const std::string& a_str, 00098 const uint16 a_indention, 00099 const configuration_manager::logging_type a_logging_level, 00100 const pid_t a_pid 00101 ) 00102 { 00103 std::string::const_iterator csi; 00104 00105 if (!initialized()) 00106 throw(INTERNAL_ERROR(0,"Log manager is not initialized")); 00107 00108 if (m_use_error_logging_level) { 00109 if (a_logging_level > config.error_logging_level()) 00110 return; 00111 } 00112 else { 00113 if (a_logging_level > config.logging_level()) 00114 return; 00115 } 00116 00117 for (csi = a_str.begin(); csi != a_str.end(); ++csi) { 00118 if (m_new_line) { 00119 m_out << stamp(a_pid, a_indention); 00120 m_new_line = false; 00121 } 00122 m_out << *csi; 00123 if (*csi == '\n') 00124 m_new_line = true; 00125 } 00126 m_out.flush(); 00127 } 00128 00129 /** Use error-logging-level instead of logging-level */ 00130 void log_manager::set_error_logging(bool a_b) 00131 { 00132 m_use_error_logging_level = a_b; 00133 } 00134 00135 //----------------------------------------------------------------------------- 00136 00137 /** The global log manager */ 00138 log_manager logger; 00139 00140 //----------------------------------------------------------------------------- 00141