00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4Log.h"
00015
00016 #include "Riostream.h"
00017 #include "TDataType.h"
00018 #include "TDatime.h"
00019 #include "TMutex.h"
00020 #include "TSystem.h"
00021 #include "snprintf.h"
00022
00023 #include "TGo4LockGuard.h"
00024
00025 const char* TGo4Log::fgcLEFT = "GO4-";
00026
00027 const char* TGo4Log::fgcRIGHT = " ";
00028 const char* TGo4Log::fgcDEBUG = "d";
00029 const char* TGo4Log::fgcINFO = "*";
00030 const char* TGo4Log::fgcWARN = "#";
00031 const char* TGo4Log::fgcERR = "!";
00032 const char* TGo4Log::fgcDEFAULTLOG = "go4logfile.txt";
00033
00034 TString TGo4Log::fgsGO4SYS = "";
00035
00036
00037 char TGo4Log::fgcMessagetext[__MESSAGETEXTLENGTH__];
00038 Int_t TGo4Log::fgiIgnoreLevel = 1;
00039 Bool_t TGo4Log::fgbOutputEnabled = kTRUE;
00040 Bool_t TGo4Log::fgbLogfileEnabled = kFALSE;
00041 Bool_t TGo4Log::fgbAutoMode = kFALSE;
00042 void* TGo4Log::fgxLogfile = 0;
00043 TMutex* TGo4Log::fgxMutex = 0;
00044 TGo4Log* TGo4Log::fgxInstance = 0;
00045
00046 TString TGo4Log::fgxLogName = TGo4Log::fgcDEFAULTLOG;
00047
00048 TNamed* TGo4Log::fgSniffer = 0;
00049
00050
00051
00052 TGo4Log::TGo4Log()
00053 {
00054 if (fgxMutex == 0) fgxMutex = new TMutex(kTRUE);
00055
00056
00057
00058
00059 if (IsLogfileEnabled()) {
00060 OpenLogfile(fgcDEFAULTLOG,"--- This is the default Go4 Message logfile ---");
00061 LogfileEnable(kFALSE);
00062 }
00063 }
00064
00065 TGo4Log::~TGo4Log()
00066 {
00067 CloseLogfile();
00068 }
00069
00070 TGo4Log *TGo4Log::Instance()
00071 {
00072 if(fgxInstance == 0)
00073 fgxInstance = new TGo4Log();
00074
00075 return fgxInstance;
00076 }
00077
00078 const char* TGo4Log::GO4SYS()
00079 {
00080 if (fgsGO4SYS.Length()>0) return fgsGO4SYS.Data();
00081 const char* go4sys = gSystem->Getenv("GO4SYS");
00082 #ifdef COMP_GO4SYS
00083 if ((go4sys==0) || (strlen(go4sys)==0)) go4sys = COMP_GO4SYS;
00084 #endif
00085 if ((go4sys==0) || (strlen(go4sys)==0)) return "";
00086
00087 fgsGO4SYS = go4sys;
00088 if (fgsGO4SYS.Length() > 0) {
00089 #ifdef WIN32
00090 char lastsymbol = '\\';
00091 fgsGO4SYS.ReplaceAll("/","\\");
00092 #else
00093 char lastsymbol = '/';
00094 #endif
00095 if (fgsGO4SYS[fgsGO4SYS.Length() - 1] != lastsymbol) fgsGO4SYS += lastsymbol;
00096 }
00097
00098 return fgsGO4SYS.Length()>0 ? fgsGO4SYS.Data() : "";
00099 }
00100
00101 TString TGo4Log::subGO4SYS(const char* subdir)
00102 {
00103 const char* go4sys = GO4SYS();
00104
00105 if ((subdir==0) || (strlen(subdir)==0)) return TString(go4sys);
00106
00107 TString res = go4sys;
00108
00109 #ifdef WIN32
00110 res += TString(subdir).ReplaceAll("/","\\");
00111 #else
00112 res += subdir;
00113 #endif
00114
00115 return res;
00116 }
00117
00118
00119
00120 const char* TGo4Log::Message(Int_t prio, const char* text,...)
00121 {
00122 Instance();
00123
00124 if(prio>-1 && prio<fgiIgnoreLevel) return 0;
00125 char txtbuf[fguMESLEN];
00126 va_list args;
00127 va_start(args, text);
00128 vsnprintf(txtbuf, fguMESLEN, text, args);
00129 va_end(args);
00130 const char* prefix(fgcINFO);
00131 switch(prio) {
00132
00133 case -1: prefix=fgcINFO; break;
00134 case 0: prefix=fgcDEBUG; break;
00135 case 1: prefix=fgcINFO; break;
00136 case 2: prefix=fgcWARN; break;
00137 case 3: prefix=fgcERR; break;
00138 }
00139
00140 if(fgbLogfileEnabled) {
00141
00142 snprintf(fgcMessagetext,fguMESLEN,"%s %s",prefix,txtbuf);
00143 WriteLogfile(fgcMessagetext);
00144 }
00145
00146
00147 snprintf(fgcMessagetext,fguMESLEN, "%s%s> %s %s",
00148 fgcLEFT, prefix, txtbuf,fgcRIGHT);
00149
00150 if(fgbOutputEnabled) {
00151 std::cout << fgcMessagetext << std::endl;
00152
00153 if (fgSniffer) fgSniffer->SetTitle(fgcMessagetext);
00154 }
00155
00156 return fgcMessagetext;
00157 }
00158
00159 void TGo4Log::Debug(const char* text,...)
00160 {
00161 if(fgiIgnoreLevel>0) return;
00162 Instance();
00163
00164 char txtbuf[fguMESLEN];
00165 va_list args;
00166 va_start(args, text);
00167 vsnprintf(txtbuf, fguMESLEN, text, args);
00168 va_end(args);
00169 Message(0,txtbuf);
00170 }
00171
00172 void TGo4Log::Info(const char* text,...)
00173 {
00174 if(fgiIgnoreLevel>1) return;
00175 Instance();
00176
00177 char txtbuf[fguMESLEN];
00178 va_list args;
00179 va_start(args, text);
00180 vsnprintf(txtbuf, fguMESLEN, text, args);
00181 va_end(args);
00182 Message(1,txtbuf);
00183 }
00184
00185 void TGo4Log::Warn(const char* text,...)
00186 {
00187 if(fgiIgnoreLevel>2) return;
00188 Instance();
00189
00190 char txtbuf[fguMESLEN];
00191 va_list args;
00192 va_start(args, text);
00193 vsnprintf(txtbuf, fguMESLEN, text, args);
00194 va_end(args);
00195 Message(2,txtbuf);
00196 }
00197
00198 void TGo4Log::Error(const char* text,...)
00199 {
00200 Instance();
00201
00202 char txtbuf[fguMESLEN];
00203 va_list args;
00204 va_start(args, text);
00205 vsnprintf(txtbuf, fguMESLEN, text, args);
00206 va_end(args);
00207 Message(3,txtbuf);
00208 }
00209
00210
00211 void TGo4Log::SetIgnoreLevel(Int_t level)
00212 {
00213
00214 fgiIgnoreLevel=level;
00215 }
00216
00217 Int_t TGo4Log::GetIgnoreLevel()
00218 {
00219 return fgiIgnoreLevel;
00220 }
00221
00222 const char* TGo4Log::GetLogname()
00223 {
00224 return fgxLogName.Data();
00225 }
00226
00227 const char* TGo4Log::GetDefaultLogname()
00228 {
00229 return fgcDEFAULTLOG;
00230 }
00231
00232 const char* TGo4Log::GetPrintfArg(Int_t type_id)
00233 {
00234 switch (type_id) {
00235 case kInt_t: return "%d";
00236 case kUInt_t: return "%u";
00237 case kLong_t: return "%ld";
00238 case kULong_t: return "%lu";
00239 case kLong64_t: return sizeof(long long int)==8 ? "%lld" : "%ld";
00240 case kULong64_t: return sizeof(long long unsigned)==8 ? "%llu" : "%lu";
00241 }
00242
00243 return "%d";
00244 }
00245
00246
00247 void TGo4Log::OutputEnable(Bool_t on)
00248 {
00249
00250 fgbOutputEnabled=on;
00251 }
00252
00253 Bool_t TGo4Log::IsOutputEnabled()
00254 {
00255 return fgbOutputEnabled;
00256 }
00257
00258 void TGo4Log::LogfileEnable(Bool_t on)
00259 {
00260
00261 fgbLogfileEnabled=on;
00262 }
00263
00264 Bool_t TGo4Log::IsLogfileEnabled()
00265 {
00266 return fgbLogfileEnabled;
00267 }
00268
00269 void TGo4Log::AutoEnable(Bool_t on)
00270 {
00271
00272 fgbAutoMode=on;
00273 }
00274
00275 Bool_t TGo4Log::IsAutoEnabled()
00276 {
00277 return fgbAutoMode;
00278 }
00279
00280 void TGo4Log::OpenLogfile(const char* name, const char* headercomment, Bool_t appendmode)
00281 {
00282
00283 try
00284 {
00285 CloseLogfile();
00286 char txtbuf[fguMESLEN];
00287 if(name==0)
00288
00289 snprintf(txtbuf,fguMESLEN,"go4log-%d.txt", gSystem->GetPid());
00290 else
00291 snprintf(txtbuf,fguMESLEN,"%s",name);
00292
00293 std::ofstream* lf = new std::ofstream(txtbuf, appendmode ? std::ios::app : std::ios::out);
00294
00295 if(lf->fail()) {
00296 LogfileEnable(kFALSE);
00297 delete lf;
00298 std::cerr <<"TGo4Log::OpenLogfile() - Error opening logfile "<< name << std::endl;
00299 } else {
00300 fgxLogfile = lf;
00301 fgxLogName = txtbuf;
00302 }
00303
00304 if(headercomment) WriteLogfile(headercomment, kFALSE);
00305 }
00306
00307 catch(std::exception& ex)
00308 {
00309 std::cerr <<"standard exception "<<ex.what()<<"in TGo4Log::OpenLogfile" << std::endl;
00310 }
00311 catch(...)
00312 {
00313 std::cerr <<"!!! Unexpected exception in TGo4Log::OpenLogfile !!!" << std::endl;
00314 }
00315 }
00316
00317 void TGo4Log::WriteLogfile(const char* text, Bool_t withtime)
00318 {
00319
00320 if((text==0) || !fgbLogfileEnabled || (fgxLogfile==0)) return;
00321 try {
00322 if(withtime) {
00323 TDatime now;
00324 *((std::ofstream*)fgxLogfile) << now.AsSQLString() << ": ";
00325 }
00326 *((std::ofstream*)fgxLogfile) << text << std::endl;
00327 }
00328 catch(std::exception& ex)
00329 {
00330 std::cerr <<"standard exception "<<ex.what()<<"in TGo4Log::WriteLogfile" << std::endl;
00331 }
00332 catch(...)
00333 {
00334 std::cerr <<"!!! Unexpected exception in TGo4Log::WriteLogfile !!!" << std::endl;
00335 }
00336 }
00337
00338 void TGo4Log::CloseLogfile()
00339 {
00340
00341 if(fgxLogfile!=0)
00342 {
00343 try
00344 {
00345 delete (std::ofstream*)fgxLogfile;
00346 fgxLogfile=0;
00347 }
00348 catch(std::exception& ex)
00349 {
00350 std::cerr <<"standard exception "<<ex.what()<<"in TGo4Log::CloseLogfile" << std::endl;
00351 }
00352 catch(...)
00353 {
00354 std::cerr <<"!!! Unexpected exception in TGo4Log::CloseLogfile !!!" << std::endl;
00355 }
00356 }
00357 }