248 lines
7.2 KiB
C++
248 lines
7.2 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
//paragraph [23] table3columns: [\begin{quote}\begin{tabular}{lll}] [\end{tabular}\end{quote}]
|
|
//[--------] [\hline]
|
|
//characters [1] verbatim: [\verb|] [|]
|
|
//[ae] [\"a]
|
|
//[oe] [\"o]
|
|
//[ue] [\"u]
|
|
//[ss] [{\ss}]
|
|
//[<=] [$\leq$]
|
|
//[#] [\neq]
|
|
//[tilde] [\verb|~|]
|
|
|
|
1 Header File LogMsg.h
|
|
|
|
December 2003 M. Spiekermann
|
|
|
|
August 2004 M. Spiekermann. Implemented class ~CMsg~
|
|
|
|
Nov 2004 M. Spiekermann. Tabstops were replaced by spaces since different
|
|
setting of tabstops in editors will mess the code formatting.
|
|
|
|
Dec 2004, M. Spiekermann. New function ~setFlag~ implemented.
|
|
|
|
Jan 2005, M. Spiekermann. Some "stringstream << ends"[1] have been removed. The
|
|
~ends~ function adds a byte of value 0 to the ~stringstreams~ and also into
|
|
their resulting strings. This caused a hard to find bug (Value = is a
|
|
whitespace) in nested list text atoms since value 0 is the only one which is
|
|
used internally in text records to distinguish between empty and non empty
|
|
space.
|
|
|
|
May 2005, M. Spiekermann. Function CMsg::info overloaded.
|
|
|
|
August 2005, M. Spiekermann. Redirection of output corrected. Moreover, strings
|
|
containing only white spaces will be ignored. Errors will be printed in color,
|
|
if the appropriate flag is set.
|
|
|
|
April 2007, M. Spiekermann. Implementation parts moved to .cpp files.
|
|
|
|
1.1 Overview
|
|
|
|
This file should collect all methods or techniques used in SECONDO for managing
|
|
errors and trace messages. This is still work in progress!
|
|
|
|
This file declares a class ~RTFlag~ (Runtime Flag) and a preprocessor Macro
|
|
~LOGMSG~. It can be used to identify a bool value with a std::string constant.
|
|
The value for a given flag name is true, when it appears in the file
|
|
"SecondoConfig.ini"[1] in the list of the values for the key RTFlag. It can be
|
|
used for trace messages or runtime configuration. This is good for testing or
|
|
comparing different implementations without recompilation. The alternative of
|
|
defining and reading in new keys in "SecondoConfig.ini" is much more
|
|
complicated. The macro or the class are used as presented below.
|
|
|
|
----LOGMSG("MyFlagName", cerr << "variable x:" << x << std::endl;)
|
|
|
|
if ( RTFlag::isActive("MyFlagName") ) {
|
|
|
|
... code which should only be executed in this case
|
|
|
|
}
|
|
----
|
|
|
|
All flags should be documented in the configuration file. However, the
|
|
mechanism is quite simple, take care to use the same std::string constants
|
|
in your code and in the configuration file otherwise you will get in trouble.
|
|
|
|
Sending information to ~cout~ or ~cerr~ is not a good idea, since in a client
|
|
server setup these information will not transfered to the client. Hence a
|
|
global message object ~cmsg~ of class ~CMsg~ will be used as transmitter for
|
|
messages. There are four methods which return the reference to an std::ostream
|
|
object. Additonally, you can easily send data to a file. Currently, the
|
|
messages are not send to a client via the socket communication but this can
|
|
easily be integrated later.
|
|
|
|
Here are some examples how to use the interface:
|
|
|
|
---- cmsg.info() << "Non critical information send to cout" << std::endl;
|
|
cmsg.send();
|
|
cmsg.warning() << "More critical information send to cout" << std::endl;
|
|
cmsg.send();
|
|
cmsg.error() << "Error information send to cerr" << std::endl;
|
|
cmsg.send();
|
|
cmsg.file() << "Information send to the file secondo.log" << std::endl;
|
|
cmsg.send();
|
|
cmsg.file("my-logfile.log") << "Information send to my-logfile.log"
|
|
<< std::endl;
|
|
----
|
|
|
|
Before changing the output channel it is important to clear the messsage buffer
|
|
with the ~send~ method.
|
|
|
|
*/
|
|
|
|
|
|
#ifndef CLASS_LOGMSG_H
|
|
#define CLASS_LOGMSG_H
|
|
|
|
#ifndef LOGMSG_OFF
|
|
#define LOGMSG(a, b) if ( RTFlag::isActive(a) ) { b }
|
|
#endif
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
|
|
extern std::ostream* traceOS;
|
|
|
|
class RTFlag {
|
|
|
|
public:
|
|
|
|
static void initByString( const std::string& keyList );
|
|
|
|
static void showActiveFlags(std::ostream& os);
|
|
|
|
static bool isActive( const std::string& key );
|
|
|
|
static void setFlag( const std::string& key, const bool value );
|
|
|
|
static bool empty() {
|
|
return flagMap.empty();
|
|
}
|
|
|
|
private:
|
|
|
|
RTFlag(){}
|
|
~RTFlag(){}
|
|
static std::map<std::string,bool> flagMap;
|
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
|
4 Class ErrorReporter
|
|
|
|
This class contains only static member functions. These functions
|
|
permit reporting an error message (~ReportError~) and
|
|
retrieving it (~GetErrorMessage~). Once an error message has been
|
|
retrieved, it is removed. If there is no error message, the function
|
|
~RemoveErrorMessage~ sets its argument to ~""~.
|
|
|
|
It should be used only for reporting ~type error~ messages.
|
|
An example of the usage of function ~ReportError~ is given in the
|
|
type mapping function of operator ~feed~ in the relational algebra.
|
|
|
|
*/
|
|
|
|
class ErrorReporter
|
|
{
|
|
private:
|
|
static bool receivedMessage;
|
|
static std::string message;
|
|
|
|
public:
|
|
static bool FreezeMessage;
|
|
static bool TypeMapError;
|
|
static void Reset() { TypeMapError=false; message=""; }
|
|
static void ReportError(const std::string msg);
|
|
static void ReportError(const char* msg);
|
|
static void GetErrorMessage(std::string& msg);
|
|
};
|
|
|
|
|
|
class CMsg {
|
|
|
|
public:
|
|
|
|
CMsg();
|
|
~CMsg();
|
|
|
|
std::ostream& file();
|
|
std::ostream& file(const std::string& fileName);
|
|
|
|
// condintinal output of messages
|
|
std::ostream& info(const std::string& key);
|
|
|
|
inline std::ostream& info() { stdOutput = 1; return buffer; }
|
|
inline std::ostream& warning() { stdOutput = 1; return buffer; }
|
|
inline std::ostream& error() { stdOutput = 2; return buffer; }
|
|
|
|
// More specific error channels
|
|
void typeError(const std::string& msg) { ErrorReporter::ReportError(msg);}
|
|
void inFunError(const std::string& msg) { error() << "InFun: " << msg
|
|
<< std::endl; }
|
|
void otherError(const std::string& msg) { error() << "Other: " << msg
|
|
<< std::endl; }
|
|
|
|
/*
|
|
|
|
The send method will flush the stored messages to the underlying stream. In
|
|
the future it may also send the message to clients using socket communication.
|
|
|
|
*/
|
|
void send();
|
|
|
|
/*
|
|
Retrieving and cleaning stored errors.
|
|
|
|
*/
|
|
std::string getErrorMsg();
|
|
|
|
void resetErrors();
|
|
|
|
private:
|
|
|
|
void init();
|
|
int stdOutput;
|
|
std::ofstream* fp;
|
|
std::stringstream buffer;
|
|
std::stringstream allErrors;
|
|
std::stringstream devnull;
|
|
std::string logFileStr;
|
|
std::string prefix;
|
|
std::map<std::string,std::ofstream*> files;
|
|
|
|
};
|
|
|
|
// defined in cmsg.cpp
|
|
extern CMsg cmsg;
|
|
|
|
|
|
|
|
#endif
|