casacore
Loading...
Searching...
No Matches
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: casa-feedback@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#ifndef CASA_LOGSINK_H
27#define CASA_LOGSINK_H
28
29#include <casacore/casa/aips.h>
30#include <casacore/casa/Logging/LogSinkInterface.h>
31#include <casacore/casa/Exceptions/Error.h>
32#include <casacore/casa/iosfwd.h>
33#include <memory>
34#include <mutex>
35
36namespace casacore { // # NAMESPACE CASACORE - BEGIN
37
38// <summary>
39// Distribute LogMessages to their destination(s)
40// </summary>
41
42// <use visibility=export>
43
44// <reviewed reviewer="wbrouw" date="1996/08/21" tests="tLogging.cc" demos="dLogging.cc">
45// </reviewed>
46
47// <prerequisite>
48// <li> <linkto class="LogMessage">LogMessage</linkto>
49// <li> <linkto class="LogSinkInterface">LogSinkInterface</linkto>, if you are
50// interested in extending the set of destinations a <src>LogMessage</src> can
51// be sent.
52// </prerequisite>
53//
54// <etymology>
55// Log as in "Log Book." Sink from its common usage ("source/sink") as a thing
56// which can accept some substance or energy.
57// </etymology>
58//
59// <synopsis>
60// The LogSink class supplies the destination for
61// <linkto class="LogMessage">LogMessage</linkto>s. There are two destinations
62// available through the <src>LogSink</src>
63// <ol>
64// <li> A <i>global</i> destination, which is shared by all LogSinks. The global
65// destination will typically be a GUI window or standard output.
66// <li> A <i>local</i> destination which is intended to log changes to
67// particular dataset(s). The local destination will typically be a
68// Casacore <linkto class="Table">Table</linkto>, but there is also
69// a local sink for temporary storage in memory.
70// </ol>
71// Normally the <src>post()</src> member function will be called which
72// sends the message to both the global and local destinations, however one or
73// the other may be chosen via <src>LogSink::postGlobally()</src> and
74// <src>postLocally()</src> member functions.
75//
76// The global sink will normally be set by system library code (it defaults to
77// using <src>cerr</src>. The type of local sink is defined at
78// construction time. Presently you can choose one of:
79// <ol>
80// <li> a <linkto class="NullLogSink">NullLogSink</linkto> which merely
81// discards the logging messages.
82// <li> a <linkto class="StreamLogSink">StreamLogSink</linkto> which sends
83// the log messages to an <src>ostream</src> (typically <src>cerr</src>)
84// <li> a <linkto class="TableLogSink">TableLogSink</linkto> which sends
85// the messages to a Casacore <linkto class=Table>Table</linkto>.
86// </ol>
87//
88// Every <src>LogSink</src> has an attached
89// <linkto class=LogFilterInterface>LogFilterInterface</linkto>
90// which is used to reject or pass messages.
91// The local and global sinks have their own filters, so they can
92// pass different message priorities (e.g., global <src>DEBUGGING</src> and
93// local <src>NORMAL</src>). Generally applications code shouldn't change the
94// global filter.
95//
96// </synopsis>
97//
98// <example>
99// <srcblock>
100// LogMessage logMessage(...);
101// LogSink logger(LogMessage::NORMAL, "logtable"); // log locally to a 'logtable'
102// logMessage.message("this is a message").line(__LINE__);
103// logger.post(logMessage); // local and global
104// </srcblock>
105// More complete examples are in <linkto file=Logging.h>Logging.h</linkto>.
106// </example>
107//
108// <h3>Advanced topics</h3>
109// All possible sinks are derived from an abstract base class:
110// <linkto class=LogSinkInterface>LogSinkInterface</linkto>. If you want to
111// allow for logging to a different type of sink (i.e. different from
112// a stream or Table) , you first need to derive a new class from
113// <src>LogSinkInterface</src>, and then add a new constructor to
114// <src>LogSink</src>.
115//
116// <src>LogSink</src> itself contains a reference to the actual object that
117// disposes of the messages. Several <src>LogSink</src>'s can share the same
118// actual sink via the copy constructor or assignment operator.
119// <srcblock>
120// LogSink logger1(LogMessage::NORMAL, "logtable");
121// LogSink logger2(logger1); // logger2 references logger1
122// logger2.post(message); // ends up in "logtable"
123// </srcblock>
124// You can even have different <src>LogFilterInterface</src>'s
125// attached to the different <src>LogSink</src>s.
126//
127// <motivation>
128// Logging changes to data and informing users what the software is doing in
129// detail.
130// </motivation>
131//
132// <todo asof="1996/07/24">
133// <li> More sink types - in particular to Glish.
134// <li> A "tee" Sink type might be useful.
135// </todo>
136
137class LogSink : public LogSinkInterface {
138 public:
139 // #If you add more sink types, modify the <ol> in the synopsis as well.
140 // Create a null local sink that throws all messages away or create
141 // a memory local sink that holds the messages in memory.
142 // If a filter isn't defined, default to <src>NORMAL</src>.
143 // <group>
145 explicit LogSink(const LogFilterInterface &filter, Bool nullSink = True);
146 // </group>
147
148 // Log to an ostream. It is the responsiblity of the caller to ensure that
149 // <src>os</src> will last as long as the <src>LogSink</src>s that use it.
150 // Normally you would use <src>&cerr</src> as the argument.
151 // <group>
152 LogSink(LogMessage::Priority filter, ostream *os, Bool useGlobalSink = True);
153 LogSink(const LogFilterInterface &filter, ostream *os, Bool useGlobalSink = True);
154 // </group>
155
156 // Log to the given sink.
157 // It is primarily intended to log to a
158 // <linkto class=TableLogSink>TableLogSink</linkto>.
159 LogSink(const LogFilterInterface &filter, const std::shared_ptr<LogSinkInterface> &);
160
161 // Make a referencing copy of <src>other</src>. That is, if you post a
162 // message to the new object, it behaves as if you had posted it to the
163 // old one (so long as their filters are the same).
164 // <group>
165 LogSink(const LogSink &other);
166 LogSink &operator=(const LogSink &other);
167 // </group>
168
169 // Temporary to avoid problem that the bool constructor is taken
170 // if a char* is passed.
171 // They are not implemented, so compiler should give warning.
172 // The 3rd argument is added to make it different from current
173 // version which is still in the system library.
174 LogSink(const LogFilterInterface &filter, const String &fileName, Int n = 0);
175 LogSink(const LogFilterInterface &filter, const Char *fileName, Int n = 0);
176 LogSink(LogMessage::Priority, const String &fileName, Int n = 0);
177 LogSink(LogMessage::Priority, const Char *fileName, Int n = 0);
178
180
181 // Send <src>message</src> to both the local and global sink. Return
182 // <src>True</src> if it passes either of them.
183 Bool post(const LogMessage &message);
184
185 // Send <src>message</src> to the global sink only. Returns <src>True</src>
186 // if it passes the filter.
187 static Bool postGlobally(const LogMessage &message);
188 // Send <src>message</src> to the local sink only. Returns <src>True</src>
189 // if it passes the filter.
190 virtual Bool postLocally(const LogMessage &message);
191
192 // Post <src>message</src> and then throw an <src>AipsError</src> exception
193 // containing <src>message.toString()</src>. It is always posted as a
194 // <src>SEVERE</src> priority message, no matter what
195 // <src>message.priority()</src> says.
196 // <group>
197 template <typename EXC>
198 void postThenThrow(const LogMessage &message, const EXC &exc) {
199 preparePostThenThrow(message, exc);
200 throw exc;
201 }
202 static void postGloballyThenThrow(const LogMessage &message);
203 // </group>
204
205 // Get number of messages in local sink.
206 virtual uInt nelements() const;
207
208 // Get given part of the i-th message from the local sink.
209 // <group>
210 virtual Double getTime(uInt i) const;
211 virtual String getPriority(uInt i) const;
212 virtual String getMessage(uInt i) const;
213 virtual String getLocation(uInt i) const;
214 virtual String getObjectID(uInt i) const;
215 // </group>
216
217 // Write a message (usually from another logsink) into the local one.
218 // The default implementation does nothing.
219 virtual void writeLocally(Double time, const String &message, const String &priority,
220 const String &location, const String &objectID);
221
222 // Clear the local sink (i.e. remove all messages from it).
223 virtual void clearLocally();
224
225 // # Bring out of LogSinkInterface only for documentation purposes
226 // Get or set the filter of this particular <src>LogSink</src>.
227 // <group>
228 virtual const LogFilterInterface &filter() const;
230 // </group>
231
232 // Change the sink that this <src>LogSink</src> actually uses.
233 // <group>
237 // </group>
238
239 // Get/set the global sink or check if the global sink is null. The global
240 // sink defaults to using <src>cerr</src>. Generally applications code
241 // shouldn't change the global sink. More so, calling globalSink(fromNew)
242 // while using the global sink is not thread-safe. And fromNew is set to 0.
243 // <group>
245 static void globalSink(LogSinkInterface *&fromNew);
247 // </group>
248
249 // Write any pending output (by default also the global sink).
250 virtual void flush(Bool global = True);
251
252 // Returns the id for this class...
253 static String localId();
254 // Returns the id of the LogSink in use...
255 String id() const;
256
257 private:
258 // LsiIntermediate is a helper class to allow LogSinkInterface to implement
259 // semantics that allow causing all classes accessing the log sink to be
260 // aimed at a different sink object. This used to be done by using an
261 // odd "replace" method in std::shared_ptr; however, this is functionality is
262 // being removed to std::shared_ptr as it is modernized so this class was
263 // created to serve this narrow purpose.
264
266 public:
270
273 Bool operator!() const { return !logSinkInterface_p; }
274
275 void replace(LogSinkInterface *newLsi) {
276 delete logSinkInterface_p;
277 logSinkInterface_p = newLsi;
278 }
279
280 private:
281 // Copy ctor and op= are private and not defined to prevent double-delete.
282
285
287 };
288
289 // Prepare for postThenThrow function.
290 void preparePostThenThrow(const LogMessage &message, const AipsError &x);
291
292 // Create the global sink (attached to cerr). Always called using theirCallOnce.
293 static void createGlobalSink();
294
295 // # Data members.
296 std::shared_ptr<LogSinkInterface> local_sink_p;
297 static std::shared_ptr<LsiIntermediate> global_sink_p;
298 static std::once_flag theirCallOnceFlag;
299
300 // The following is a reference to the global sink. It is created to
301 // ensure that the global sink is not destroyed before the last
302 // reference to it is destroyed. This can happen if you have a static
303 // LogSink (or LogIO).
304 std::shared_ptr<LsiIntermediate> local_ref_to_global_p;
306};
307
308} // namespace casacore
309
310#endif
Priority
An "importance" which is assigned to each LogMessage.
Definition LogMessage.h:102
LogSinkInterface()
Create with a NORMAL filter.
LsiIntermediate & operator=(const LsiIntermediate &)
LogSinkInterface & operator*()
Definition LogSink.h:271
LsiIntermediate(const LsiIntermediate &)
Copy ctor and op= are private and not defined to prevent double-delete.
LsiIntermediate(LogSinkInterface *lsi)
Definition LogSink.h:268
LogSinkInterface * operator->()
Definition LogSink.h:272
void replace(LogSinkInterface *newLsi)
Definition LogSink.h:275
LogSinkInterface * logSinkInterface_p
Definition LogSink.h:286
String id() const
Returns the id of the LogSink in use...
LogSink(const LogFilterInterface &filter, ostream *os, Bool useGlobalSink=True)
LogSink & localSink(LogSinkInterface *&fromNew)
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.
virtual String getLocation(uInt i) const
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.
LogSink(LogMessage::Priority, const Char *fileName, Int n=0)
static std::shared_ptr< LsiIntermediate > global_sink_p
Definition LogSink.h:297
LogSink(const LogFilterInterface &filter, const Char *fileName, Int n=0)
virtual String getMessage(uInt i) const
std::shared_ptr< LogSinkInterface > local_sink_p
Definition LogSink.h:296
LogSink & operator=(const LogSink &other)
virtual Bool postLocally(const LogMessage &message)
Send message to the local sink only.
LogSink(LogMessage::Priority filter, ostream *os, Bool useGlobalSink=True)
Log to an ostream.
virtual const LogFilterInterface & filter() const
Get or set the filter of this particular LogSink.
virtual void clearLocally()
Clear the local sink (i.e.
std::shared_ptr< LsiIntermediate > local_ref_to_global_p
The following is a reference to the global sink.
Definition LogSink.h:304
virtual LogSinkInterface & filter(const LogFilterInterface &filter)
virtual Double getTime(uInt i) const
Get given part of the i-th message from the local sink.
LogSink(const LogSink &other)
Make a referencing copy of other.
void postThenThrow(const LogMessage &message, const EXC &exc)
Post message and then throw an AipsError exception containing message.toString().
Definition LogSink.h:198
LogSink(const LogFilterInterface &filter, Bool nullSink=True)
const LogSinkInterface & localSink() const
Change the sink that this LogSink actually uses.
LogSink(LogMessage::Priority, const String &fileName, Int n=0)
static Bool postGlobally(const LogMessage &message)
Send message to the global sink only.
static LogSinkInterface & globalSink()
Get/set the global sink or check if the global sink is null.
LogSinkInterface & localSink()
virtual uInt nelements() const
Get number of messages in local sink.
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...
static Bool nullGlobalSink()
static void postGloballyThenThrow(const LogMessage &message)
Bool post(const LogMessage &message)
Send message to both the local and global sink.
LogSink(const LogFilterInterface &filter, const std::shared_ptr< LogSinkInterface > &)
Log to the given sink.
virtual String getObjectID(uInt i) const
static void createGlobalSink()
Create the global sink (attached to cerr).
virtual String getPriority(uInt i) const
static String localId()
Returns the id for this class...
virtual void flush(Bool global=True)
Write any pending output (by default also the global sink).
static std::once_flag theirCallOnceFlag
Definition LogSink.h:298
static void globalSink(LogSinkInterface *&fromNew)
void preparePostThenThrow(const LogMessage &message, const AipsError &x)
Prepare for postThenThrow function.
String: the storage and methods of handling collections of characters.
Definition String.h:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
TableExprNode time(const TableExprNode &node)
Definition ExprNode.h:1368
unsigned int uInt
Definition aipstype.h:49
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
const Bool True
Definition aipstype.h:41
double Double
Definition aipstype.h:53
char Char
Definition aipstype.h:44