casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LogSink.h
Go to the documentation of this file.
1 //# LogSink.h: Distribute LogMessages to their destination(s)
2 //# Copyright (C) 1996,2000,2001,2003,2016
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //#
27 //# $Id$
28 
29 #ifndef CASA_LOGSINK_H
30 #define CASA_LOGSINK_H
31 
32 #include <casacore/casa/aips.h>
34 
37 #include <casacore/casa/OS/Mutex.h>
38 #include <casacore/casa/iosfwd.h>
39 
40 namespace casacore { //# NAMESPACE CASACORE - BEGIN
41 
42 // <summary>
43 // Distribute LogMessages to their destination(s)
44 // </summary>
45 
46 // <use visibility=export>
47 
48 // <reviewed reviewer="wbrouw" date="1996/08/21" tests="tLogging.cc" demos="dLogging.cc">
49 // </reviewed>
50 
51 // <prerequisite>
52 // <li> <linkto class="LogMessage">LogMessage</linkto>
53 // <li> <linkto class="LogSinkInterface">LogSinkInterface</linkto>, if you are
54 // interested in extending the set of destinations a <src>LogMessage</src> can
55 // be sent.
56 // </prerequisite>
57 //
58 // <etymology>
59 // Log as in "Log Book." Sink from its common usage ("source/sink") as a thing
60 // which can accept some substance or energy.
61 // </etymology>
62 //
63 // <synopsis>
64 // The LogSink class supplies the destination for
65 // <linkto class="LogMessage">LogMessage</linkto>s. There are two destinations
66 // available through the <src>LogSink</src>
67 // <ol>
68 // <li> A <i>global</i> destination, which is shared by all LogSinks. The global
69 // destination will typically be a GUI window or standard output.
70 // <li> A <i>local</i> destination which is intended to log changes to
71 // particular dataset(s). The local destination will typically be a
72 // Casacore <linkto class="Table">Table</linkto>, but there is also
73 // a local sink for temporary storage in memory.
74 // </ol>
75 // Normally the <src>post()</src> member function will be called which
76 // sends the message to both the global and local destinations, however one or
77 // the other may be chosen via <src>LogSink::postGlobally()</src> and
78 // <src>postLocally()</src> member functions.
79 //
80 // The global sink will normally be set by system library code (it defaults to
81 // using <src>cerr</src>. The type of local sink is defined at
82 // construction time. Presently you can choose one of:
83 // <ol>
84 // <li> a <linkto class="NullLogSink">NullLogSink</linkto> which merely
85 // discards the logging messages.
86 // <li> a <linkto class="StreamLogSink">StreamLogSink</linkto> which sends
87 // the log messages to an <src>ostream</src> (typically <src>cerr</src>)
88 // <li> a <linkto class="TableLogSink">TableLogSink</linkto> which sends
89 // the messages to a Casacore <linkto class=Table>Table</linkto>.
90 // </ol>
91 //
92 // Every <src>LogSink</src> has an attached
93 // <linkto class=LogFilterInterface>LogFilterInterface</linkto>
94 // which is used to reject or pass messages.
95 // The local and global sinks have their own filters, so they can
96 // pass different message priorities (e.g., global <src>DEBUGGING</src> and
97 // local <src>NORMAL</src>). Generally applications code shouldn't change the
98 // global filter.
99 //
100 // </synopsis>
101 //
102 // <example>
103 // <srcblock>
104 // LogMessage logMessage(...);
105 // LogSink logger(LogMessage::NORMAL, "logtable"); // log locally to a 'logtable'
106 // logMessage.message("this is a message").line(__LINE__);
107 // logger.post(logMessage); // local and global
108 // </srcblock>
109 // More complete examples are in <linkto file=Logging.h>Logging.h</linkto>.
110 // </example>
111 //
112 // <h3>Advanced topics</h3>
113 // All possible sinks are derived from an abstract base class:
114 // <linkto class=LogSinkInterface>LogSinkInterface</linkto>. If you want to
115 // allow for logging to a different type of sink (i.e. different from
116 // a stream or Table) , you first need to derive a new class from
117 // <src>LogSinkInterface</src>, and then add a new constructor to
118 // <src>LogSink</src>.
119 //
120 // <src>LogSink</src> itself contains a reference to the actual object that
121 // disposes of the messages. Several <src>LogSink</src>'s can share the same
122 // actual sink via the copy constructor or assignment operator.
123 // <srcblock>
124 // LogSink logger1(LogMessage::NORMAL, "logtable");
125 // LogSink logger2(logger1); // logger2 references logger1
126 // logger2.post(message); // ends up in "logtable"
127 // </srcblock>
128 // You can even have different <src>LogFilterInterface</src>'s
129 // attached to the different <src>LogSink</src>s.
130 //
131 // <motivation>
132 // Logging changes to data and informing users what the software is doing in
133 // detail.
134 // </motivation>
135 //
136 // <todo asof="1996/07/24">
137 // <li> More sink types - in particular to Glish.
138 // <li> A "tee" Sink type might be useful.
139 // </todo>
140 
141 class LogSink : public LogSinkInterface
142 {
143 public:
144  //#If you add more sink types, modify the <ol> in the synopsis as well.
145  // Create a null local sink that throws all messages away or create
146  // a memory local sink that holds the messages in memory.
147  // If a filter isn't defined, default to <src>NORMAL</src>.
148  // <group>
150  Bool nullSink = True);
151  explicit LogSink (const LogFilterInterface &filter, Bool nullSink = True);
152  // </group>
153 
154  // Log to an ostream. It is the responsiblity of the caller to ensure that
155  // <src>os</src> will last as long as the <src>LogSink</src>s that use it.
156  // Normally you would use <src>&cerr</src> as the argument.
157  // <group>
158  LogSink (LogMessage::Priority filter, ostream *os,
159  Bool useGlobalSink = True);
160  LogSink (const LogFilterInterface &filter, ostream *os,
161  Bool useGlobalSink = True);
162  // </group>
163 
164  // Log to the given sink.
165  // It is primarily intended to log to a
166  // <linkto class=TableLogSink>TableLogSink</linkto>.
167  LogSink (const LogFilterInterface &filter,
169 
170  // Make a referencing copy of <src>other</src>. That is, if you post a
171  // message to the new object, it behaves as if you had posted it to the
172  // old one (so long as their filters are the same).
173  // <group>
174  LogSink (const LogSink &other);
175  LogSink &operator= (const LogSink &other);
176  // </group>
177 
178  // Temporary to avoid problem that the bool constructor is taken
179  // if a char* is passed.
180  // They are not implemented, so compiler should give warning.
181  // The 3rd argument is added to make it different from current
182  // version which is still in the system library.
183  LogSink (const LogFilterInterface &filter, const String &fileName, Int n=0);
184  LogSink (const LogFilterInterface &filter, const Char* fileName, Int n=0);
185  LogSink (LogMessage::Priority, const String &fileName, Int n=0);
186  LogSink (LogMessage::Priority, const Char* fileName, Int n=0);
187 
188  ~LogSink();
189 
190  // Send <src>message</src> to both the local and global sink. Return
191  // <src>True</src> if it passes either of them.
192  Bool post (const LogMessage &message);
193 
194  // Send <src>message</src> to the global sink only. Returns <src>True</src>
195  // if it passes the filter.
196  static Bool postGlobally (const LogMessage &message);
197  // Send <src>message</src> to the local sink only. Returns <src>True</src>
198  // if it passes the filter.
199  virtual Bool postLocally (const LogMessage &message);
200 
201  // Post <src>message</src> and then throw an <src>AipsError</src> exception
202  // containing <src>message.toString()</src>. It is always posted as a
203  // <src>SEVERE</src> priority message, no matter what
204  // <src>message.priority()</src> says.
205  // <group>
206  template<typename EXC> void postThenThrow (const LogMessage &message,
207  const EXC& exc)
208  { preparePostThenThrow(message, exc); throw exc; }
209  static void postGloballyThenThrow (const LogMessage &message);
210  // </group>
211 
212  // Get number of messages in local sink.
213  virtual uInt nelements() const;
214 
215  // Get given part of the i-th message from the local sink.
216  // <group>
217  virtual Double getTime (uInt i) const;
218  virtual String getPriority (uInt i) const;
219  virtual String getMessage (uInt i) const;
220  virtual String getLocation (uInt i) const;
221  virtual String getObjectID (uInt i) const;
222  // </group>
223 
224  // Write a message (usually from another logsink) into the local one.
225  // The default implementation does nothing.
226  virtual void writeLocally (Double time, const String& message,
227  const String& priority, const String& location,
228  const String& objectID);
229 
230  // Clear the local sink (i.e. remove all messages from it).
231  virtual void clearLocally();
232 
233  //# Bring out of LogSinkInterface only for documentation purposes
234  // Get or set the filter of this particular <src>LogSink</src>.
235  // <group>
236  virtual const LogFilterInterface &filter() const;
237  virtual LogSinkInterface &filter (const LogFilterInterface &filter);
238  // </group>
239 
240  // Change the sink that this <src>LogSink</src> actually uses.
241  // <group>
242  const LogSinkInterface &localSink() const;
244  LogSink &localSink (LogSinkInterface *&fromNew);
245  // </group>
246 
247  // Get/set the global sink or check if the global sink is null. The global
248  // sink defaults to using <src>cerr</src>. Generally applications code
249  // shouldn't change the global sink. More so, calling globalSink(fromNew)
250  // while using the global sink is not thread-safe. And fromNew is set to 0.
251  // <group>
252  static LogSinkInterface &globalSink();
253  static void globalSink (LogSinkInterface *&fromNew);
254  static Bool nullGlobalSink();
255  // </group>
256 
257  // Write any pending output (by default also the global sink).
258  virtual void flush (Bool global=True);
259 
260  // Returns the id for this class...
261  static String localId( );
262  // Returns the id of the LogSink in use...
263  String id( ) const;
264 
265 private:
266 
267  // LsiIntermediate is a helper class to allow LogSinkInterface to implement
268  // semantics that allow causing all classes accessing the log sink to be
269  // aimed at a different sink object. This used to be done by using an
270  // odd "replace" method in CountedPtr; however, this is functionality is
271  // being removed to CountedPtr as it is modernized so this class was
272  // created to serve this narrow purpose.
273 
275 
276  public:
277 
278 
282 
285  Bool operator! () const { return ! logSinkInterface_p;}
286 
287  void replace (LogSinkInterface * newLsi) { delete logSinkInterface_p; logSinkInterface_p = newLsi;}
288 
289  private:
290 
291  // Copy ctor and op= are private and not defined to prevent double-delete.
292 
295 
297 
298  };
299 
300  // Prepare for postThenThrow function.
301  void preparePostThenThrow(const LogMessage &message, const AipsError& x) ;
302 
303  // Create the global sink (attached to cerr). Always called using theirCallOnce.
304  static void createGlobalSink();
305 
306  //# Data members.
310 
311  // The following is a reference to the global sink. It is created to
312  // ensure that the global sink is not destroyed before the last local
313  // reference to it is destroyed. This can happen if you have a static
314  // LogSink (or LogIO).
317 };
318 
319 
320 
321 } //# NAMESPACE CASACORE - END
322 
323 #endif
Wrapper around std::call_once.
Definition: Mutex.h:214
int Int
Definition: aipstype.h:50
LsiIntermediate & operator=(const LsiIntermediate &)
static void createGlobalSink()
Create the global sink (attached to cerr).
Abstract base class for filtering LogMessages.
LogSinkInterface * operator->()
Definition: LogSink.h:284
TableExprNode time(const TableExprNode &node)
Definition: ExprNode.h:1537
static String localId()
Returns the id for this class...
virtual const LogFilterInterface & filter() const
Get or set the filter of this particular LogSink.
static CallOnce0 theirCallOnce
Definition: LogSink.h:309
String id() const
Returns the id of the LogSink in use...
virtual Bool postLocally(const LogMessage &message)
Send message to the local sink only.
char Char
Definition: aipstype.h:46
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...
virtual String getPriority(uInt i) const
LsiIntermediate is a helper class to allow LogSinkInterface to implement semantics that allow causing...
Definition: LogSink.h:274
void replace(LogSinkInterface *newLsi)
Definition: LogSink.h:287
static LogSinkInterface & globalSink()
Get/set the global sink or check if the global sink is null.
void postThenThrow(const LogMessage &message, const EXC &exc)
Post message and then throw an AipsError exception containing message.toString(). ...
Definition: LogSink.h:206
LsiIntermediate(LogSinkInterface *lsi)
Definition: LogSink.h:280
Accepts LogMessages and posts them to some destination.
CountedPtr< LsiIntermediate > local_ref_to_global_p
The following is a reference to the global sink.
Definition: LogSink.h:315
Referenced counted pointer for constant data.
Definition: VisModelData.h:42
Bool post(const LogMessage &message)
Send message to both the local and global sink.
virtual void flush(Bool global=True)
Write any pending output (by default also the global sink).
double Double
Definition: aipstype.h:55
static Bool postGlobally(const LogMessage &message)
Send message to the global sink only.
static void postGloballyThenThrow(const LogMessage &message)
void preparePostThenThrow(const LogMessage &message, const AipsError &x)
Prepare for postThenThrow function.
virtual uInt nelements() const
Get number of messages in local sink.
virtual String getObjectID(uInt i) const
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
LogSinkInterface * logSinkInterface_p
Definition: LogSink.h:296
CountedPtr< LogSinkInterface > local_sink_p
Definition: LogSink.h:307
virtual String getMessage(uInt i) const
Priority
An &quot;importance&quot; which is assigned to each LogMessage.
Definition: LogMessage.h:105
Base class for all Casacore library errors.
Definition: Error.h:134
Distribute LogMessages to their destination(s)
Definition: LogSink.h:141
Bool useGlobalSink_p
Definition: LogSink.h:316
const LogSinkInterface & localSink() const
Change the sink that this LogSink actually uses.
String: the storage and methods of handling collections of characters.
Definition: String.h:223
static CountedPtr< LsiIntermediate > * global_sink_p
Definition: LogSink.h:308
virtual void clearLocally()
Clear the local sink (i.e.
LogSinkInterface & operator*()
Definition: LogSink.h:283
const Bool True
Definition: aipstype.h:43
Informational log messages with with time, priority, and origin.
Definition: LogMessage.h:101
virtual String getLocation(uInt i) const
virtual Double getTime(uInt i) const
Get given part of the i-th message from the local sink.
static Bool nullGlobalSink()
LogSink & operator=(const LogSink &other)
unsigned int uInt
Definition: aipstype.h:51
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.
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42