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 }