00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "log.hh"
00025
00026 #include <iostream>
00027
00028 using namespace VOS;
00029
00030
00031
00032
00033
00034 map<const char*, Log*, Log::StrCmp> Log::channels;
00035 std::ostream* Log::defaultostream = &std::clog;
00036 int Log::defaultloglevel = 2;
00037 bool Log::didReadEnv = false;
00038 boost::mutex Log::log_io_mutex;
00039
00040 #ifdef DEFAULT_MASTER_LOGLEVEL
00041 int Log::masterLogLevel = DEFAULT_MASTER_LOGLEVEL;
00042 #else
00043 int Log::masterLogLevel = 10;
00044 #endif
00045
00046 Log::Log(const string& channel, std::ostream* outputstream)
00047 : channelname(channel), output(outputstream), loglevel(defaultloglevel)
00048 { }
00049
00050 Log::Log(const string& channel)
00051 : channelname(channel), output(defaultostream), loglevel(defaultloglevel)
00052 { }
00053
00054 void Log::log(int level, const string& message)
00055 {
00056 if(level <= loglevel) {
00057 time_t t;
00058 time(&t);
00059 char* c=ctime(&t);
00060 c[strlen(c)-1]=0;
00061 boost::mutex::scoped_lock lock(log_io_mutex);
00062 *output << "[" << c << " (" << level << ") " << channelname << "] " << message.substr(0, 1024) << '\n';
00063 output->flush();
00064 }
00065 }
00066
00067 void Log::setLevel(int l)
00068 {
00069 loglevel=l;
00070 }
00071
00072 int Log::getLevel()
00073 {
00074 return loglevel;
00075 }
00076
00077 void Log::log(const string& channel, int level, const string& message)
00078 {
00079 log(channel.c_str(), level, message);
00080 }
00081
00082 void Log::log(const char* channel, int level, const string& message)
00083 {
00084 if(channels.find(channel) == channels.end()) {
00085 (channels[channel] = new Log(channel, defaultostream))->setLevel(defaultloglevel);
00086 }
00087 channels[channel]->log(level, message);
00088 }
00089
00090 void Log::addChannel(Log* l) { channels[l->channelname.c_str()] = l; }
00091 void Log::setDefaultOutputStream(std::ostream* o) { defaultostream=o; }
00092 void Log::setDefaultLevel(int l) { defaultloglevel=l; }
00093 int Log::getDefaultLevel() { return defaultloglevel; }
00094 void Log::setMasterLevel(int l) { masterLogLevel = l; }
00095 int Log::getMasterLevel() { return masterLogLevel; }
00096
00097 Log* Log::getLog(const string& channel) {
00098 return getLog(channel.c_str());
00099 }
00100
00101 Log* Log::getLog(const char* channel) {
00102 if(! didReadEnv) readEnvironment();
00103 map<const char*, Log*, StrCmp>::const_iterator it = channels.find(channel);
00104 if(it != channels.end()) return (*it).second;
00105 else return 0;
00106 }
00107
00108 void Log::readEnvironment()
00109 {
00110 didReadEnv=true;
00111
00112 char* env = getenv("VOS_MASTER_LOGLEVEL");
00113 if(env) {
00114 setMasterLevel(atoi(env));
00115 }
00116
00117 env = getenv("VOS_DEFAULT_LOGLEVEL");
00118 if(env) {
00119 setDefaultLevel(atoi(env));
00120 }
00121
00122 env = getenv("VOS_LOG");
00123 if(env) {
00124 char* e = strdup(env);
00125 env=e;
00126 for(;;) {
00127 char* col = strchr(env, '=');
00128 if(!col) return;
00129 *col=0;
00130 char* com = strchr(col+1, ',');
00131 if(com) *com=0;
00132
00133 Log* l = getLog(env);
00134 if(! l) {
00135 l = new Log(env);
00136 addChannel(l);
00137 }
00138 time_t t;
00139 time(&t);
00140 char* c=ctime(&t);
00141 c[strlen(c)-1]=0;
00142 *defaultostream << "[" << c << " (" << 0 << ") " << "log" << "] "
00143 << "Setting channel " << l->channelname << " to level " << (col+1) << '\n';
00144 defaultostream->flush();
00145
00146 l->setLevel(atoi(col+1));
00147
00148 if(com) env=com+1;
00149 else break;
00150 }
00151 free(e);
00152 }
00153 }
00154
00155 void Log::closeAllChannels() {
00156 for(map<const char*, Log*, StrCmp>::iterator i = channels.begin(); i != channels.end(); i++) {
00157 if( i->second )
00158 delete i->second;
00159 channels.erase(i);
00160 }
00161 }
00162