//*-- Author : Joern Wuestenfeld
//*-- Modified : 15/04/2002 by Joern Wuestenfeld
//*-- Modified : 04/04/2002 by Joern Wuestenfeld
//*-- Modified : 28/03/2002 by Joern Wuestenfeld
//*-- Modified : 27/02/2003 by Joern Wuestenfeld
//*-- Modified : 07/05/2003 by Joern Wuestenfeld
//_HADES_CLASS_DESCRIPTION
/////////////////////////////////////////
//
// HMessageMgr
//
// This class manages three different outputs for all kind of messages.
// Besides the standart output, which is the default, one can also
// write the messages to a file, or via a socket to a remote logging process.
//
// The usage of this class should be done via the four macros that are defined
// in the hmessagemgr.h file.
// DEBUG_msg(level, det, text)
// ERROR_msg(det, text)
// WARNING_msg(level, det, text)
// INFO_msg(level, det, text)
//
// The meaning of the parameters is:
// level - level of this message, never set it to zero because this means
// no message at all will be printed
// det - detector which sends this message, can be one of:
// DET_RICH DET_START DET_MDC DET_TOF DET_TOFINO DET_SHOWER
// DET_TRIGGER
// text - text to print
//
/////////////////////////////////////////////////////
using namespace std;
#include "TSystem.h"
#include "hmessagemgr.h"
#include <iostream>
#include <iomanip>
/// This is the default constructor inherited from TNamed.
/**
Sets default logging to stdout and stderr.
The default levels are: no debugging, but all of error, warning and info.
param name Name of the object
param title Title of the object
*/
HMessageMgr::HMessageMgr(const char *name, const char *title)
: TNamed(name,title)
{
msgFile = NULL;
errorFile = NULL;
msgSocket = NULL;
errorSocket = NULL;
file = NULL;
debugLevel = 0;
warningLevel = LEVELMAX;
infoLevel = LEVELMAX;
detectorMsg = DET_ALL;
line = 0;
screen = kFALSE;
file = new char[80];
}
/// This is the default destructor
/**
*/
HMessageMgr::~HMessageMgr(void)
{
setDefault();
delete [] file;
file = NULL;
}
/// Resets the message logging to ist default.
/**
Closses all loggfiles or open sockets, and loggs further messages to
stdout and stderr.
Also the loglevels are set to the same values as in the constructor.
*/
Bool_t HMessageMgr::setDefault(void)
{
if(msgFile)
{
delete msgFile;
}
if(errorFile)
{
delete errorFile;
}
if(msgSocket)
{
msgSocket->Close();
delete msgSocket;
msgSocket = NULL;
}
if(errorSocket)
{
errorSocket->Close();
delete errorSocket;
errorSocket = NULL;
}
debugLevel = 0;
warningLevel = LEVELMAX;
infoLevel = LEVELMAX;
detectorMsg = DET_ALL;
screen = kFALSE;
return kTRUE;
}
/// Sets the logfile.
/**
Input is the directory to where to log to.
The filename is derived from the name of this object, that is given
when creating it.
Two files are created. One with extension .msg for all messages of
type info, warning and debug.
The other one with extension .err fo the error messages.
param dir Directory where to store the logfiles.
retval setFile Returns kTRUE if file could be opened, otherwise kFALSE.
*/
Bool_t HMessageMgr::setFile(const char *dir)
{
char *fname;
fname = (char *)calloc(1,200);
if(msgFile)
{
delete msgFile;
msgFile = NULL;
}
if(errorFile)
{
delete errorFile;
errorFile = NULL;
}
if(!msgFile)
{
if((UInt_t)strlen(dir) > (UInt_t)(200 - fName.Length() + 5))
{
free(fname);
return kFALSE;
}
else
{
sprintf(fname,"%s%s%s",dir,fName.Data(),".msg");
}
msgFile = new ofstream(fname,ios::out
if(!msgFile)
{
free(fname);
return kFALSE;
}
}
else
{
free(fname);
return kFALSE;
}
if(!errorFile)
{
if((UInt_t )strlen(dir) > (UInt_t)(200 - fName.Length() + 5))
{
free(fname);
return kFALSE;
}
else
{
sprintf(fname,"%s%s%s",dir,fName.Data(),".err");
}
errorFile = new ofstream(fname,ios::out
if(!errorFile)
{
free(fname);
if(msgFile)
{
msgFile->close();
msgFile = NULL;
}
return kFALSE;
}
}
else
{
free(fname);
return kFALSE;
}
return kTRUE;
}
/// Opens two socket connections to a logging server on the specified host.
/**
The passed port is used for the message logging. Errors are send to
the portaddress port + 10.
eventually opened logfiles are closed, if the connection could be opened.
Otherwise the current logging stays active.
param host Name of the host to send the logmessages to.
param port Port to use for communication with remote process.
retval setPort Returns kTRUE if remote process could be contacted, otherwise
kFALSE is returned.
*/
Bool_t HMessageMgr::setPort(const char *host, Int_t port)
{
msgSocket = new TSocket(host,port);
errorSocket = new TSocket(host,port+10);
thisHost = new TString(gSystem->HostName());
if(msgSocket->IsValid() && errorSocket->IsValid())
{
if(msgFile)
{
msgFile->close();
msgFile = NULL;
}
if(errorFile)
{
errorFile->close();
errorFile = NULL;
}
msgSocket->Send(thisHost->Data());
errorSocket->Send(thisHost->Data());
return kTRUE;
}
else
{
delete msgSocket;
delete errorSocket;
msgSocket = NULL;
errorSocket = NULL;
return kFALSE;
}
}
/// Switches of the logging completly by setting the output to /dev/null.
/**
Could probably done also by redirecting stdout and stderr to /dev/null.
Currently opened files or sockets are closed.
retval switchOff Returns kTRUE on succsess, kFALSE otherwise.
*/
Bool_t HMessageMgr::switchOff(void)
{
char *fname;
fname = (char *)calloc(1,200);
setDefault();
if(msgFile)
{
delete msgFile;
msgFile = NULL;
}
if(errorFile)
{
delete errorFile;
errorFile = NULL;
}
if(!msgFile)
{
sprintf(fname,"%s","/dev/null");
}
msgFile = new ofstream(fname,ios::out
if(!msgFile)
{
free(fname);
return kFALSE;
}
else
{
free(fname);
return kFALSE;
}
if(!errorFile)
{
sprintf(fname,"%s","/dev/null");
}
errorFile = new ofstream(fname,ios::out
if(!errorFile)
{
free(fname);
return kFALSE;
}
else
{
free(fname);
return kFALSE;
}
return kTRUE;
}
/// Sets the level of debug messages to level.
/**
param level Level of debugging, max 10 min 0.
*/
void HMessageMgr::setDebugLevel(Char_t level)
{
if(level > 10)
debugLevel = 10;
else
if(level <= 0)
debugLevel = 1;
else
debugLevel = level;
}
/// Sets the level of info messages to level.
/**
param level Level of information, max 10 min 0.
*/
void HMessageMgr::setInfoLevel(Char_t level)
{
if(level > 1)
infoLevel = 10;
else
if(level <= 0)
infoLevel = 1;
else
infoLevel = level;
}
/// Sets the level of warning messages to level.
/**
param level Level of warning, max 10 min 0.
*/
void HMessageMgr::setWarningLevel(Char_t level)
{
if(level > 10)
warningLevel = 10;
else
if(level <= 0)
warningLevel = 1;
else
warningLevel = level;
}
/// Selects for which detector messages should be displayed.
/**
param det An or'd pattern of the DET_* constants.
*/
void HMessageMgr::enableDetectorMsg(Int_t det)
{
detectorMsg = det;
}
/// This function prints a line with character seperator.
/*
The seperator character is repeated num times on this line.
param seperator character to be used as seperator
param num How often the character is to be repeated on the same line.
*/
void HMessageMgr::messageSeperator(Char_t *seperator, Int_t num)
{
int i;
msg1 = (char *)calloc(1,200);
for(i=0;i<num;i++)
{
strcat(msg1,seperator);
}
write(msg1);
free(msg1);
}
/// Message handler for ROOT. Can be installed via gSystem->SetErrorHandler()
/**
Used by all ROOT classes to do message logging.
Gives a common message layout.
param level Level of logging
param abort Wether to abort the execution after the printing of the message
param location Location of the message
param msg Text to be printed.
*/
void HMessageMgr::hydraErrorHandler(int level, Bool_t abort, const char *location, const char *msg)
{
if (level < gErrorIgnoreLevel)
return;
if((level >= kError) | (level >= kSysError) | (level >= kFatal))
{
gHades->getMsg()->error(10,DET_ALL,location,msg);
}
else
if(level >= kWarning)
{
gHades->getMsg()->warning(10,DET_ALL,location,msg);
}
else
if(level >= kInfo)
{
gHades->getMsg()->info(10,DET_ALL,location,msg);
}
}
/// This function should never be called directly, use the DEBUG macro instead.
/**
This function writes a debug message to the output.
It looks like this example:<br>
debug <Hades >:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to 'print.
*/
void HMessageMgr::debug(Char_t level, Int_t det, const char *className, const char *text)
{
if(level <= 0)
level = 1;
if((level <= debugLevel) && (detectorMsg & det))
{
msg1 = (char*)calloc(1,strlen((char *)text)+30);
if(msg1)
{
if(line == 0)
sprintf(msg1,"%7s%s%s%s%s","debug","<",className,">: ",text);
else
sprintf(msg1,"%7s%s%s %s%s%d%s%s","debug","<",className,file,":",line,">:",text);
write(msg1);
free(msg1);
}
}
}
/// This function should never be called directly, use the ERROR macro instead.
/**
This function writes a error message to the output.
It looks like this example:<br>
error <Hades >:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
*/
void HMessageMgr::error(Char_t level, Int_t det, const char *className, const char *text)
{
if(level <= 0)
level = 1;
if(detectorMsg & det)
{
msg1 = (char*)calloc(1,strlen((char *)text)+30);
if(msg1)
{
sprintf(msg1,"%7s%s%s%s%s","error","<",className,">: ",text);
ewrite(msg1);
free(msg1);
}
}
}
/// This function should never be called directly, use the WARNING macro instead.
/**
This function writes a warning message to the output.
It looks like this example:<br>
warning<Hades >:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
*/
void HMessageMgr::warning(Char_t level, Int_t det, const char *className, const char *text)
{
if(level <= 0)
level = 1;
if((level <= warningLevel) && (detectorMsg & det))
{
msg1 = (char*)calloc(1,strlen((char *)text)+strlen(className)+15);
if(msg1)
{
sprintf(msg1,"%7s%s%s%s%s","warning","<",className,">: ",text);
write(msg1);
free(msg1);
}
}
}
/// This function should never be called directly, use the INFO macro instead.
/**
This function writes a info message to the output.
It looks like this example:<br>
info< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
*/
void HMessageMgr::info(Char_t level, Int_t det, const char *className, const char *text)
{
if(level <= 0)
level = 1;
if((level <= infoLevel) && (detectorMsg & det))
{
msg1 = (char*)calloc(1,strlen((char *)text)+30);
if(msg1)
{
sprintf(msg1,"%7s%s%s%s%s","info","<",className,">: ",text);
write(msg1);
free(msg1);
}
}
}
/// This function put out an error message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
debug< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::debug(Int_t level, Int_t det, const char *className, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if((level <= debugLevel) && (detectorMsg & det))
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
if(line == 0)
sprintf(msg1,"%7s%s%s%s","debug","<",className,">:");
else
sprintf(msg1,"%7s%s%s %s%s%d%s","debug","<",className,file,":",line,">: ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an error message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
error< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::error(Int_t level, Int_t det, const char *className, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if(detectorMsg & det)
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s%s%s%s","error","<",className,">: ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
ewrite(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an warning message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
warning< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::warning(Int_t level, Int_t det, const char *className, const char *text, ...)
{
va_list ap;
unsigned int size1,size2;
if(level <= 0)
level = 1;
if((level <= warningLevel) && (detectorMsg & det))
{
size2 = strlen(text)+200;
size1 = strlen(className) + size2 + 15;
msg2 = (char *)calloc(1,size2);
msg1 = (char *)calloc(1,size1);
sprintf(msg1,"%7s%s%s%s","warning","<",className,">: ");
va_start(ap,text);
vsnprintf(msg2,size2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an info message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
info< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::info(Int_t level, Int_t det, const char *className, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if((level <= infoLevel) && (detectorMsg & det))
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s%s%s%s","info","<",className,">: ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an error message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
debug< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param className Name of the class that prints this message.
param file Filename that prints the message.
param line Linenumber from where the message is printed.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::debugB(Char_t level, Int_t det, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if((level <= debugLevel) && (detectorMsg & det))
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s%s%s %s%d%s","debug","<",file,":",line,">: ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an error message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
error< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::errorB(Char_t level, Int_t det, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if(detectorMsg & det)
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s","error :");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
ewrite(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an warning message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
warning< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::warningB(Char_t level, Int_t det, const char *text, ...)
{
va_list ap;
unsigned int size1,size2;
if(level <= 0)
level = 1;
if((level <= warningLevel) && (detectorMsg & det))
{
size2 = strlen(text)+200;
size1 = size2 + 15;
msg2 = (char *)calloc(1,size2);
msg1 = (char *)calloc(1,size1);
sprintf(msg1,"%7s","warning : ");
va_start(ap,text);
vsnprintf(msg2,size2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an info message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
info< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::infoB(Char_t level, Int_t det, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if((level <= infoLevel) && (detectorMsg & det))
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s","info : ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// This function put out an error message including some variable arguments.
/**
The text parameter takes the standart parameters as in printf().
The output looks like:<br>
debug< Hades>:No input specified<p>
param level Level of message logging
param det One of the DET_* constants that defines the detector printing this message.
param file Filename that prints the message.
param line Linenumber from where the message is printed.
param text Text to print.
param ... Variable number of arguments, that will be used to fill the text
*/
void HMessageMgr::debug(Int_t level, Int_t det, const char * className, const char *file, Int_t line, const char *text, ...)
{
va_list ap;
if(level <= 0)
level = 1;
if((level <= debugLevel) && (detectorMsg & det))
{
msg1 = (char *)calloc(1,200);
msg2 = (char *)calloc(1,200);
sprintf(msg1,"%7s%s%s %s%s%d%s","debug","<",className,file,":",line,">: ");
va_start(ap,text);
vsprintf(msg2,text,ap);
va_end(ap);
strcat(msg1,msg2);
write(msg1);
free(msg1);
free(msg2);
}
}
/// Internal function used to write to the correct output.
/**
Used for info, warning and debug messages.
Adds the name of the host the code is running on, if output is send via
socket to a remote logging process.
If screen is set to kTRUE the output is writen to stdout in addition to
the logfile.
param text Text to be writen to specified target.
*/
void HMessageMgr::write(const char *text)
{
Char_t *msg;
if(msgFile)
{
msgFile->write(text,strlen(text));
if(screen)
cout << text << endl;
}
else
{
if(msgSocket)
{
msg =(Char_t *)calloc(1,strlen(text) + 20);
sprintf(msg,"<%10s>%s",thisHost->Data(),text);
msgSocket->Send(msg);
free(msg);
}
else
{
cout << text << endl;
}
}
}
/// Internal function used to write to the correct output.
/**
Used for error messages.
Adds the name of the host the code is running on, if output is send via
socket to a remote logging process.
If screen is set to kTRUE the output is writen to stdout in addition to
the logfile.
param text Text to be writen to specified target.
*/
void HMessageMgr::ewrite(const char *text)
{
Char_t *msg;
if(errorFile)
{
errorFile->write(text,strlen(text));
if(screen)
cout << text << endl;
}
else
{
if(errorSocket)
{
msg =(Char_t *)calloc(1,strlen(text) + 20);
sprintf(msg,"<%10s>%s",thisHost->Data(),text);
errorSocket->Send(msg);
free(msg);
}
else
{
cerr << text << endl;
}
}
}
/// Sets the filename for the debug messages.
/**
The filenames are printed when the debug level is set.
param name Name of the file that wants to print a message soon.
*/
void HMessageMgr::setF(const char *name)
{
if(name && (strlen(name) != 0))
strncpy(file, name,79);
else strcpy(file, "");
}
/// Sets the linenumber for the debug message.
/**
The linenumber is printed when the debug level is set.
param num Linenumber of message.
*/
void HMessageMgr::setL(int num)
{
line = num;
}
ClassImp(HMessageMgr)
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.