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