Loading...
Searching...
No Matches
LogSink.h
Go to the documentation of this file.
//# LogSink.h: Distribute LogMessages to their destination(s)
//# Copyright (C) 1996,2000,2001,2003,2016
//# Associated Universities, Inc. Washington DC, USA.
//#
//# This library is free software; you can redistribute it and/or modify it
//# under the terms of the GNU Library General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or (at your
//# option) any later version.
//#
//# This library 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 Library General Public
//# License for more details.
//#
//# You should have received a copy of the GNU Library General Public License
//# along with this library; if not, write to the Free Software Foundation,
//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
//#
//# Correspondence concerning AIPS++ should be addressed as follows:
//# Internet email: casa-feedback@nrao.edu.
//# Postal address: AIPS++ Project Office
//# National Radio Astronomy Observatory
//# 520 Edgemont Road
//# Charlottesville, VA 22903-2475 USA
#ifndef CASA_LOGSINK_H
#define CASA_LOGSINK_H
#include <casacore/casa/aips.h>
#include <casacore/casa/Logging/LogSinkInterface.h>
#include <casacore/casa/Exceptions/Error.h>
#include <casacore/casa/iosfwd.h>
#include <memory>
#include <mutex>
namespace casacore { //# NAMESPACE CASACORE - BEGIN
// <summary>
// Distribute LogMessages to their destination(s)
// </summary>
// <use visibility=export>
// <reviewed reviewer="wbrouw" date="1996/08/21" tests="tLogging.cc" demos="dLogging.cc">
// </reviewed>
// <prerequisite>
// <li> <linkto class="LogMessage">LogMessage</linkto>
// <li> <linkto class="LogSinkInterface">LogSinkInterface</linkto>, if you are
// interested in extending the set of destinations a <src>LogMessage</src> can
// be sent.
// </prerequisite>
//
// <etymology>
// Log as in "Log Book." Sink from its common usage ("source/sink") as a thing
// which can accept some substance or energy.
// </etymology>
//
// <synopsis>
// The LogSink class supplies the destination for
// <linkto class="LogMessage">LogMessage</linkto>s. There are two destinations
// available through the <src>LogSink</src>
// <ol>
// <li> A <i>global</i> destination, which is shared by all LogSinks. The global
// destination will typically be a GUI window or standard output.
// <li> A <i>local</i> destination which is intended to log changes to
// particular dataset(s). The local destination will typically be a
// Casacore <linkto class="Table">Table</linkto>, but there is also
// a local sink for temporary storage in memory.
// </ol>
// Normally the <src>post()</src> member function will be called which
// sends the message to both the global and local destinations, however one or
// the other may be chosen via <src>LogSink::postGlobally()</src> and
// <src>postLocally()</src> member functions.
//
// The global sink will normally be set by system library code (it defaults to
// using <src>cerr</src>. The type of local sink is defined at
// construction time. Presently you can choose one of:
// <ol>
// <li> a <linkto class="NullLogSink">NullLogSink</linkto> which merely
// discards the logging messages.
// <li> a <linkto class="StreamLogSink">StreamLogSink</linkto> which sends
// the log messages to an <src>ostream</src> (typically <src>cerr</src>)
// <li> a <linkto class="TableLogSink">TableLogSink</linkto> which sends
// the messages to a Casacore <linkto class=Table>Table</linkto>.
// </ol>
//
// Every <src>LogSink</src> has an attached
// <linkto class=LogFilterInterface>LogFilterInterface</linkto>
// which is used to reject or pass messages.
// The local and global sinks have their own filters, so they can
// pass different message priorities (e.g., global <src>DEBUGGING</src> and
// local <src>NORMAL</src>). Generally applications code shouldn't change the
// global filter.
//
// </synopsis>
//
// <example>
// <srcblock>
// LogMessage logMessage(...);
// LogSink logger(LogMessage::NORMAL, "logtable"); // log locally to a 'logtable'
// logMessage.message("this is a message").line(__LINE__);
// logger.post(logMessage); // local and global
// </srcblock>
// More complete examples are in <linkto file=Logging.h>Logging.h</linkto>.
// </example>
//
// <h3>Advanced topics</h3>
// All possible sinks are derived from an abstract base class:
// <linkto class=LogSinkInterface>LogSinkInterface</linkto>. If you want to
// allow for logging to a different type of sink (i.e. different from
// a stream or Table) , you first need to derive a new class from
// <src>LogSinkInterface</src>, and then add a new constructor to
// <src>LogSink</src>.
//
// <src>LogSink</src> itself contains a reference to the actual object that
// disposes of the messages. Several <src>LogSink</src>'s can share the same
// actual sink via the copy constructor or assignment operator.
// <srcblock>
// LogSink logger1(LogMessage::NORMAL, "logtable");
// LogSink logger2(logger1); // logger2 references logger1
// logger2.post(message); // ends up in "logtable"
// </srcblock>
// You can even have different <src>LogFilterInterface</src>'s
// attached to the different <src>LogSink</src>s.
//
// <motivation>
// Logging changes to data and informing users what the software is doing in
// detail.
// </motivation>
//
// <todo asof="1996/07/24">
// <li> More sink types - in particular to Glish.
// <li> A "tee" Sink type might be useful.
// </todo>
class LogSink : public LogSinkInterface
{
public:
//#If you add more sink types, modify the <ol> in the synopsis as well.
// Create a null local sink that throws all messages away or create
// a memory local sink that holds the messages in memory.
// If a filter isn't defined, default to <src>NORMAL</src>.
// <group>
explicit LogSink (LogMessage::Priority filter = LogMessage::NORMAL,
Bool nullSink = True);
explicit LogSink (const LogFilterInterface &filter, Bool nullSink = True);
// </group>
// Log to an ostream. It is the responsiblity of the caller to ensure that
// <src>os</src> will last as long as the <src>LogSink</src>s that use it.
// Normally you would use <src>&cerr</src> as the argument.
// <group>
LogSink (LogMessage::Priority filter, ostream *os,
Bool useGlobalSink = True);
LogSink (const LogFilterInterface &filter, ostream *os,
Bool useGlobalSink = True);
// </group>
// Log to the given sink.
// It is primarily intended to log to a
// <linkto class=TableLogSink>TableLogSink</linkto>.
LogSink (const LogFilterInterface &filter,
const std::shared_ptr<LogSinkInterface>&);
// Make a referencing copy of <src>other</src>. That is, if you post a
// message to the new object, it behaves as if you had posted it to the
// old one (so long as their filters are the same).
// <group>
LogSink (const LogSink &other);
LogSink &operator= (const LogSink &other);
// </group>
// Temporary to avoid problem that the bool constructor is taken
// if a char* is passed.
// They are not implemented, so compiler should give warning.
// The 3rd argument is added to make it different from current
// version which is still in the system library.
LogSink (const LogFilterInterface &filter, const String &fileName, Int n=0);
LogSink (const LogFilterInterface &filter, const Char* fileName, Int n=0);
LogSink (LogMessage::Priority, const String &fileName, Int n=0);
LogSink (LogMessage::Priority, const Char* fileName, Int n=0);
~LogSink();
// Send <src>message</src> to both the local and global sink. Return
// <src>True</src> if it passes either of them.
Bool post (const LogMessage &message);
// Send <src>message</src> to the global sink only. Returns <src>True</src>
// if it passes the filter.
static Bool postGlobally (const LogMessage &message);
// Send <src>message</src> to the local sink only. Returns <src>True</src>
// if it passes the filter.
virtual Bool postLocally (const LogMessage &message);
// Post <src>message</src> and then throw an <src>AipsError</src> exception
// containing <src>message.toString()</src>. It is always posted as a
// <src>SEVERE</src> priority message, no matter what
// <src>message.priority()</src> says.
// <group>
template<typename EXC> void postThenThrow (const LogMessage &message,
const EXC& exc)
{ preparePostThenThrow(message, exc); throw exc; }
static void postGloballyThenThrow (const LogMessage &message);
// </group>
// Get number of messages in local sink.
virtual uInt nelements() const;
// Get given part of the i-th message from the local sink.
// <group>
virtual Double getTime (uInt i) const;
virtual String getPriority (uInt i) const;
virtual String getMessage (uInt i) const;
virtual String getLocation (uInt i) const;
virtual String getObjectID (uInt i) const;
// </group>
// Write a message (usually from another logsink) into the local one.
// The default implementation does nothing.
virtual void writeLocally (Double time, const String& message,
const String& priority, const String& location,
const String& objectID);
// Clear the local sink (i.e. remove all messages from it).
virtual void clearLocally();
//# Bring out of LogSinkInterface only for documentation purposes
// Get or set the filter of this particular <src>LogSink</src>.
// <group>
virtual const LogFilterInterface &filter() const;
virtual LogSinkInterface &filter (const LogFilterInterface &filter);
// </group>
// Change the sink that this <src>LogSink</src> actually uses.
// <group>
const LogSinkInterface &localSink() const;
LogSinkInterface &localSink();
LogSink &localSink (LogSinkInterface *&fromNew);
// </group>
// Get/set the global sink or check if the global sink is null. The global
// sink defaults to using <src>cerr</src>. Generally applications code
// shouldn't change the global sink. More so, calling globalSink(fromNew)
// while using the global sink is not thread-safe. And fromNew is set to 0.
// <group>
static LogSinkInterface &globalSink();
static void globalSink (LogSinkInterface *&fromNew);
static Bool nullGlobalSink();
// </group>
// Write any pending output (by default also the global sink).
virtual void flush (Bool global=True);
// Returns the id for this class...
static String localId( );
// Returns the id of the LogSink in use...
String id( ) const;
private:
// LsiIntermediate is a helper class to allow LogSinkInterface to implement
// semantics that allow causing all classes accessing the log sink to be
// aimed at a different sink object. This used to be done by using an
// odd "replace" method in std::shared_ptr; however, this is functionality is
// being removed to std::shared_ptr as it is modernized so this class was
// created to serve this narrow purpose.
class LsiIntermediate {
public:
LsiIntermediate () : logSinkInterface_p (0) {}
LsiIntermediate (LogSinkInterface * lsi) : logSinkInterface_p (lsi) {}
~LsiIntermediate () { delete logSinkInterface_p;}
LogSinkInterface & operator* () { return * logSinkInterface_p;}
LogSinkInterface * operator-> () { return logSinkInterface_p;}
Bool operator! () const { return ! logSinkInterface_p;}
void replace (LogSinkInterface * newLsi) { delete logSinkInterface_p; logSinkInterface_p = newLsi;}
private:
// Copy ctor and op= are private and not defined to prevent double-delete.
LsiIntermediate (const LsiIntermediate &);
LsiIntermediate & operator= (const LsiIntermediate &);
LogSinkInterface * logSinkInterface_p;
};
// Prepare for postThenThrow function.
void preparePostThenThrow(const LogMessage &message, const AipsError& x) ;
// Create the global sink (attached to cerr). Always called using theirCallOnce.
static void createGlobalSink();
//# Data members.
std::shared_ptr<LogSinkInterface> local_sink_p;
static std::shared_ptr<LsiIntermediate> global_sink_p;
static std::once_flag theirCallOnceFlag;
// The following is a reference to the global sink. It is created to
// ensure that the global sink is not destroyed before the last
// reference to it is destroyed. This can happen if you have a static
// LogSink (or LogIO).
std::shared_ptr<LsiIntermediate> local_ref_to_global_p;
Bool useGlobalSink_p;
};
} //# NAMESPACE CASACORE - END
#endif
casacore::AipsError
Definition Error.h:133
casacore::LogFilterInterface
Definition LogFilterInterface.h:82
casacore::LogMessage
Definition LogMessage.h:98
casacore::LogMessage::Priority
Priority
An "importance" which is assigned to each LogMessage.
Definition LogMessage.h:102
casacore::LogMessage::NORMAL
@ NORMAL
Definition LogMessage.h:116
casacore::LogSinkInterface::LogSinkInterface
LogSinkInterface()
Create with a NORMAL filter.
casacore::LogSink::LsiIntermediate::operator=
LsiIntermediate & operator=(const LsiIntermediate &)
casacore::LogSink::LsiIntermediate::operator*
LogSinkInterface & operator*()
Definition LogSink.h:279
casacore::LogSink::LsiIntermediate::LsiIntermediate
LsiIntermediate(const LsiIntermediate &)
Copy ctor and op= are private and not defined to prevent double-delete.
casacore::LogSink::LsiIntermediate::LsiIntermediate
LsiIntermediate()
Definition LogSink.h:275
casacore::LogSink::LsiIntermediate::LsiIntermediate
LsiIntermediate(LogSinkInterface *lsi)
Definition LogSink.h:276
casacore::LogSink::LsiIntermediate::operator->
LogSinkInterface * operator->()
Definition LogSink.h:280
casacore::LogSink::LsiIntermediate::~LsiIntermediate
~LsiIntermediate()
Definition LogSink.h:277
casacore::LogSink::LsiIntermediate::replace
void replace(LogSinkInterface *newLsi)
Definition LogSink.h:283
casacore::LogSink::LsiIntermediate::operator!
Bool operator!() const
Definition LogSink.h:281
casacore::LogSink::LsiIntermediate::logSinkInterface_p
LogSinkInterface * logSinkInterface_p
Definition LogSink.h:292
casacore::LogSink::id
String id() const
Returns the id of the LogSink in use...
casacore::LogSink::LogSink
LogSink(const LogFilterInterface &filter, ostream *os, Bool useGlobalSink=True)
casacore::LogSink::localSink
LogSink & localSink(LogSinkInterface *&fromNew)
casacore::LogSink::writeLocally
virtual void writeLocally(Double time, const String &message, const String &priority, const String &location, const String &objectID)
Write a message (usually from another logsink) into the local one.
casacore::LogSink::getLocation
virtual String getLocation(uInt i) const
casacore::LogSink::LogSink
LogSink(const LogFilterInterface &filter, const String &fileName, Int n=0)
Temporary to avoid problem that the bool constructor is taken if a char* is passed.
casacore::LogSink::LogSink
LogSink(LogMessage::Priority, const Char *fileName, Int n=0)
casacore::LogSink::global_sink_p
static std::shared_ptr< LsiIntermediate > global_sink_p
Definition LogSink.h:304
casacore::LogSink::LogSink
LogSink(const LogFilterInterface &filter, const Char *fileName, Int n=0)
casacore::LogSink::getMessage
virtual String getMessage(uInt i) const
casacore::LogSink::local_sink_p
std::shared_ptr< LogSinkInterface > local_sink_p
Definition LogSink.h:303
casacore::LogSink::operator=
LogSink & operator=(const LogSink &other)
casacore::LogSink::postLocally
virtual Bool postLocally(const LogMessage &message)
Send message to the local sink only.
casacore::LogSink::LogSink
LogSink(LogMessage::Priority filter, ostream *os, Bool useGlobalSink=True)
Log to an ostream.
casacore::LogSink::filter
virtual const LogFilterInterface & filter() const
Get or set the filter of this particular LogSink.
casacore::LogSink::clearLocally
virtual void clearLocally()
Clear the local sink (i.e.
casacore::LogSink::local_ref_to_global_p
std::shared_ptr< LsiIntermediate > local_ref_to_global_p
The following is a reference to the global sink.
Definition LogSink.h:311
casacore::LogSink::filter
virtual LogSinkInterface & filter(const LogFilterInterface &filter)
casacore::LogSink::getTime
virtual Double getTime(uInt i) const
Get given part of the i-th message from the local sink.
casacore::LogSink::LogSink
LogSink(const LogSink &other)
Make a referencing copy of other.
casacore::LogSink::postThenThrow
void postThenThrow(const LogMessage &message, const EXC &exc)
Post message and then throw an AipsError exception containing message.toString().
Definition LogSink.h:202
casacore::LogSink::LogSink
LogSink(const LogFilterInterface &filter, Bool nullSink=True)
casacore::LogSink::localSink
const LogSinkInterface & localSink() const
Change the sink that this LogSink actually uses.
casacore::LogSink::LogSink
LogSink(LogMessage::Priority, const String &fileName, Int n=0)
casacore::LogSink::postGlobally
static Bool postGlobally(const LogMessage &message)
Send message to the global sink only.
casacore::LogSink::useGlobalSink_p
Bool useGlobalSink_p
Definition LogSink.h:312
casacore::LogSink::globalSink
static LogSinkInterface & globalSink()
Get/set the global sink or check if the global sink is null.
casacore::LogSink::localSink
LogSinkInterface & localSink()
casacore::LogSink::nelements
virtual uInt nelements() const
Get number of messages in local sink.
casacore::LogSink::LogSink
LogSink(LogMessage::Priority filter=LogMessage::NORMAL, Bool nullSink=True)
Create a null local sink that throws all messages away or create a memory local sink that holds the m...
casacore::LogSink::nullGlobalSink
static Bool nullGlobalSink()
casacore::LogSink::postGloballyThenThrow
static void postGloballyThenThrow(const LogMessage &message)
casacore::LogSink::post
Bool post(const LogMessage &message)
Send message to both the local and global sink.
casacore::LogSink::LogSink
LogSink(const LogFilterInterface &filter, const std::shared_ptr< LogSinkInterface > &)
Log to the given sink.
casacore::LogSink::getObjectID
virtual String getObjectID(uInt i) const
casacore::LogSink::createGlobalSink
static void createGlobalSink()
Create the global sink (attached to cerr).
casacore::LogSink::getPriority
virtual String getPriority(uInt i) const
casacore::LogSink::~LogSink
~LogSink()
casacore::LogSink::localId
static String localId()
Returns the id for this class...
casacore::LogSink::flush
virtual void flush(Bool global=True)
Write any pending output (by default also the global sink).
casacore::LogSink::theirCallOnceFlag
static std::once_flag theirCallOnceFlag
Definition LogSink.h:305
casacore::LogSink::globalSink
static void globalSink(LogSinkInterface *&fromNew)
casacore::LogSink::preparePostThenThrow
void preparePostThenThrow(const LogMessage &message, const AipsError &x)
Prepare for postThenThrow function.
casacore::String
String: the storage and methods of handling collections of characters.
Definition String.h:223
casacore
this file contains all the compiler specific defines
Definition mainpage.dox:28
casacore::time
TableExprNode time(const TableExprNode &node)
Definition ExprNode.h:1584
casacore::uInt
unsigned int uInt
Definition aipstype.h:49
casacore::Int
int Int
Definition aipstype.h:48
casacore::Bool
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
casacore::True
const Bool True
Definition aipstype.h:41
casacore::Double
double Double
Definition aipstype.h:53
casacore::Char
char Char
Definition aipstype.h:44