00001 #include <string>
00002 #include <errno.h>
00003 #include <tools/conf.h>
00004 #include "log.h"
00005
00006 Log __libldsw_thread_log;
00007
00008 Log::Log() : Mutex(RECURSIVE_MUTEX)
00009 {
00010 inited = false;
00011 }
00012
00013 Log::~Log()
00014 {
00015 std::map<std::string, LineLogger*>::iterator log_obj;
00016 for(log_obj = inited_loggers.begin(); log_obj != inited_loggers.end(); ++log_obj)
00017 {
00018 if(log_obj->second)
00019 delete log_obj->second;
00020 }
00021 }
00022
00023 void Log::Init()
00024 {
00025 if(!inited)
00026 {
00027 int log_no = LogLast;
00028 while(log_no--)
00029 loggers.push_back(NULL);
00030
00031 LoadLogObj(std::string("log_debug"), LogDebug);
00032 LoadLogObj(std::string("log_panic"), LogPanic);
00033 LoadLogObj(std::string("log_error"), LogError);
00034 LoadLogObj(std::string("log_warning"), LogWarning);
00035 LoadLogObj(std::string("log_info"), LogInfo);
00036 inited = true;
00037 }
00038 }
00039
00040 void Log::Reload()
00041 {
00042 Lock();
00043 inited = false;
00044 Init();
00045 Unlock();
00046 }
00047
00048 void Log::LoadLogObj(std::string logger_name, enum LogLevel logger_no)
00049 {
00050 Config conf;
00051 std::string logger = "";
00052 if(conf.Get(logger_name, logger))
00053 {
00054
00055 std::map<std::string, LineLogger*>::iterator log_obj;
00056 log_obj = inited_loggers.find(logger);
00057 if(log_obj != inited_loggers.end())
00058 loggers[logger_no] = log_obj->second;
00059 else
00060 {
00061 LineLogger* initialized_logger = NULL;
00062 if(logger == "stdout")
00063 initialized_logger = new StdoutLogger;
00064 else
00065 if(logger == "stderr")
00066 initialized_logger = new StderrLogger;
00067 else
00068 if(logger == "none")
00069 initialized_logger = NULL;
00070 else
00071 if(logger.substr(0, 5) == "file:")
00072 initialized_logger = new FileLogger(logger.substr(5, std::string::npos));
00073 else
00074 if(logger.substr(0, 4) == "net:")
00075 initialized_logger = new NetLogger(logger.substr(4, std::string::npos));
00076 else
00077 fprintf(stderr, "Unknown log target : %s -> %s\n", logger_name.c_str(), logger.c_str());
00078 if(initialized_logger)
00079 inited_loggers[logger] = initialized_logger;
00080 loggers[logger_no] = initialized_logger;
00081 }
00082 }
00083 }
00084
00085 LineLogger* Log::GetLogger(enum LogLevel log_level)
00086 {
00087 Lock();
00088 if(!inited)
00089 {
00090 Unlock();
00091 return NULL;
00092 }
00093 if((unsigned int)log_level < loggers.size())
00094 {
00095 Unlock();
00096 return loggers[log_level];
00097 }
00098 Unlock();
00099 return NULL;
00100 }
00101
00102 void LineLogger::Write(enum LogLevel log_level, const char* debug_info, const char* msg)
00103 {
00104 Lock();
00105 std::string line = "";
00106 if(log_level < LogWarning)
00107 line += std::string(debug_info);
00108
00109 if(log_level == LogPanic) line += "PANIC ";
00110 if(log_level == LogError) line += "ERROR ";
00111 if(log_level == LogWarning) line += "WARNING ";
00112
00113 line += std::string(msg);
00114 WriteToLog(line.c_str());
00115 Unlock();
00116 }
00117
00118 void StdoutLogger::WriteToLog(const char* msg)
00119 {
00120 printf("%s\n", msg);
00121 }
00122
00123 void StderrLogger::WriteToLog(const char* msg)
00124 {
00125 fprintf(stderr, "%s\n", msg);
00126 }
00127
00128 FileLogger::FileLogger(std::string filename)
00129 {
00130 f = fopen(filename.c_str(), "a+");
00131 if(!f)
00132 {
00133 fprintf(stderr, "Unable to open log file \"%s\" : %s\n", filename.c_str(), strerror(errno));
00134 exit(EXIT_FAILURE);
00135 }
00136 }
00137
00138 FileLogger::~FileLogger()
00139 {
00140 fclose(f);
00141 }
00142
00143 void FileLogger::WriteToLog(const char* msg)
00144 {
00145 fprintf(f, "%s\n", msg);
00146 fflush(f);
00147 }
00148
00149 NetLogger::NetLogger(std::string hostport)
00150 {
00151 host_is_valid = false;
00152
00153 size_t split = hostport.find(':');
00154
00155 if(split == std::string::npos)
00156 return;
00157 std::string host = hostport.substr(0, split);
00158 std::string port = hostport.substr(split + 1);
00159
00160 Connect(host, atoi(port.c_str()));
00161 }
00162
00163 NetLogger::~NetLogger()
00164 {
00165 Disconnect();
00166 }
00167
00168 void NetLogger::WriteToLog(const char* msg)
00169 {
00170 Send(msg + std::string("\n"));
00171 }