casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LogIO.h
Go to the documentation of this file.
1 //# LogIO.h: ostream-like interface to creating log messages.
2 //# Copyright (C) 1997,1999,2000,2001,2003
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_LOGIO_H
30 #define CASA_LOGIO_H
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
38 
39 namespace casacore { //# NAMESPACE CASACORE - BEGIN
40 
41 //# Forward Declarations
42 class LogSink;
43 class LogOrigin;
44 
45 // <summary>
46 // ostream-like interface to creating log messages.
47 // </summary>
48 
49 // <use visibility=export>
50 
51 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tLogIO.cc" demos="dLogging.cc">
52 // </reviewed>
53 
54 // <prerequisite>
55 // <li> <linkto class=LogSink>LogSink</linkto> class
56 // <li> <linkto class=LogMessage>LogMessage</linkto> class
57 // <li> <linkto class=LogMessage>LogOrigin</linkto> class
58 // </prerequisite>
59 //
60 // <etymology>
61 // <src>Log</src> message, <src>I</src>nput/<src>O</src>utput.
62 // </etymology>
63 //
64 // <synopsis>
65 // LogIO is intended to be used in a way similar to the ostream class.
66 // However, rather than sending it's output to a file or stdout, it bundles
67 // its output up into <linkto class=LogMessage>LogMessage</linkto> objects
68 // and posts them to a <linkto class=LogSink>LogSink</linkto>.
69 //
70 // When you use the "<<" operator on a LogIO, you are building up a log message
71 // inside the LogIO object. The message is posted when:
72 // <ol>
73 // <li> <src>LogIO::POST()</src> is called
74 // <li> You send the <src>LogIO::POST</src> or <src>LogIO::EXCEPTION</src>
75 // commands to the LogIO with the shift (<src> << </src>) command.
76 // <li> The LogIO object is destructed.
77 // </ol>
78 // Note that log messages may span multiple lines, so sending the LogIO a
79 // newline (via "\n" or endl) does not force the message to be emitted.
80 // </synopsis>
81 //
82 // <example>
83 // A LogIO may be created in the following ways:
84 // <srcblock>
85 // LogIO os;
86 // </srcblock>
87 // Here, <src>os</src> is attached to the global log sink, and no origin
88 // information is set.
89 //
90 // <srcblock>
91 // TableLogSink tab(...);
92 // LogIO os(tab);
93 // </srcblock>
94 // Here, <src>os</src> is attached to <src>tab</src> (and also to the global
95 // log sink since every sink's <src>post</src> also calls the global sink's
96 // <src>post</src>).
97 //
98 //
99 // <srcblock>
100 // LogIO os(LogOrigin("class", "func(args)", WHERE));
101 // </srcblock>
102 // Here, <src>os</src> is attached to the global sink and the origin
103 // information is set to <src>class::func(args)</src> and the line number and
104 // source file information is set (with <src>WHERE</src>).
105 //
106 // <srcblock>
107 // TableLogSink tab(...);
108 // LogIO os(LogOrigin("class", "func(args)", WHERE), tab);
109 // </srcblock>
110 // Here all the above information is set.
111 //
112 // Once you have a <src>LogIO</src>, using it is pretty simple:
113 // <srcblock>
114 // os << "Every good boy deserves" << 5 << " pieces of fudge!";
115 // </srcblock>
116 //
117 // This accumulates the message but does not send it. If you want to force it
118 // to be sent you can do so with either of the following methods:
119 // <srcblock>
120 // os << LogIO::POST; // From the Commands enum
121 // os.post(); // Member function
122 // </srcblock>
123 // Note that after a post the priority is reset to NORMAL.
124 //
125 // If you want to change the level of the message you can also do so with the
126 // shift operator:
127 // <srcblock>
128 // os << LogIO::DEBUGGING << "Boring message" <<
129 // LogIO::SEVERE << "Error!" << LogIO::POST;
130 // </srcblock>
131 // Note that changing the priority changes the priority of the entire
132 // message. The message does not get posted until the POST is done.
133 // So in the above example the DEBUGGING priority does not do anything
134 // because the priority is overwritten by the SEVERE one.
135 //
136 // You can also change the origin information with the << operator:
137 // <srcblock>
138 // os << LogOrigin("class", "func(args)");
139 // os << WHERE;
140 // </srcblock>
141 //
142 // A class which has an operator<< to std::ostream but not LogIO can be handled
143 // as follows:
144 // <srcblock>
145 // os << LogIO::SEVERE << " at ";
146 // os.output() << MEpoch::Convert(time_p, MEpoch::Ref(MEpoch::UTC))();
147 // os << LogIO::POST;
148 // </srcblock>
149 // </example>
150 //
151 // <motivation>
152 // The earlier method of creating log messages solely through LogSink and
153 // LogMessage required the programmer to type in more lines of code than
154 // this solution. Also, this interface makes it easy to drop log messages
155 // into existing code that uses ostreams.
156 // </motivation>
157 //
158 // <todo asof="1997/01/29">
159 // <li> Add << operators for all classes that have ostream<< defined.
160 // (We could probably do it with a template, but might result
161 // in ambiguity).
162 // <li> Have a function for changing the LogSink only? (You can get
163 // much the same effect with operator=).
164 // them?
165 // </todo>
166 
167 class LogIO
168 {
169 public:
170  // Special commands to the LogIO object
171  enum Command {
172  // Post the accumulated message. Equivalent to calling LogIO::post().
174  // Post the accumulated message then throw an exception.
175  // Always posts the message at SEVERE priority. Equivalent to calling
176  // LogIO::postThenThrow().
178  // Change the message priority to SEVERE.
180  // Change the message priority to WARN.
182  // Change the message priority to NORMAL.
189  // Change the message priority to DEBUGGING.
193 
194  // Attach this LogIO object to the global sink with no origin information.
195  LogIO();
196  // Attach this LogIO object to the supplied sink. A referencing copy of
197  // the sink is made inside the LogIO object, so you do not need to worry
198  // about memory management.
199  LogIO(LogSink &sink);
200  // Attach this LogIO object to the supplied origin and global sink.
201  LogIO(const LogOrigin &OR);
202  // Attach this LogIO object to the supplied origin and sink.
203  LogIO(const LogOrigin &OR, LogSink &sink);
204 
205  // Copying uses reference semantics, i.e. the same sink will be shared
206  // by both copies.
207  // <group>
208  LogIO(const LogIO &other);
209  LogIO &operator=(const LogIO &other);
210  // </group>
211 
212  // The destructor will post any accumulated message that has not already
213  // been posted.
214  ~LogIO();
215 
216  // Post the accumulated message. If you wish, you can post the messages
217  // only locally to the sink.
218  // After the post the priority is reset to NORMAL.
219  void post();
220  void post(LogMessage &amess);
221 
222  // Post the accumulated message locally.
223  // After the post the priority is reset to NORMAL.
224  void postLocally();
225 
226  // Post the accumulated message at SEVERE priority and then throw an
227  // exception.
228  // After the post the priority is reset to NORMAL.
229  template<typename EXC> void postThenThrow (const EXC& exc)
231 
232  // Change the priority of the message. It does NOT post the accumulated
233  // message at the old priority first.
234  void priority(LogMessage::Priority which);
236  // Change the location in the origin. Almost always this is called with the
237  // macro WHERE as its argument.
238  void sourceLocation(const SourceLocation *where);
239  // Change the origin of the accumulated message.
240  void origin(const LogOrigin &origin);
241 
242  // Acumulate output in this ostream.
243  ostream& output();
244 
245  // Occasionally it is useful to interrogate the local log sink.
247  const LogSinkInterface &localSink() const;
248 
249 private:
250  // Prepare message stream for postThenThrow function.
251  void preparePostThenThrow (const AipsError& x);
252 
255  ostringstream *text_p;
256 
257 };
258 
259 // <summary>
260 // Functions to send commands to a LogIO object.
261 // </summary>
262 // The following commands don't change the accumulated message, rather they
263 // send commands to the LogIO object, either to:
264 // <ol>
265 // <li>post the current message: <src>os << "message" << LogIO::POST;</src>
266 // <li>post the current message and then throw an exception:
267 // <src>os << "error" << LogIO::EXCEPTION;</src>
268 // <li> Change the priority of the current message:
269 // <src>os << LogIO::DEBUGGING;</src>
270 // <li> Change the origin of the message:
271 // <srcblock>
272 // os << LogOrigin(...);
273 // os << WHERE; // Changes only source file/line number
274 // </srcblock>
275 // </ol>
276 // <group name=command>
278 LogIO &operator<<(LogIO &os, const SourceLocation *item);
279 LogIO &operator<<(LogIO &os, const LogOrigin &OR);
280 // </group>
281 
282 // <summary>
283 // Functions to accumulate text in the output message.
284 // </summary>
285 // Accumulate text in the output message. The last entry is for things like
286 // <src>endl</src>.
287 // <group name=output>
288 LogIO &operator<<(LogIO &os, const String &item);
289 LogIO &operator<<(LogIO &os, const char *item);
290 LogIO &operator<<(LogIO &os, Double item);
291 LogIO &operator<<(LogIO &os, Complex item);
292 LogIO &operator<<(LogIO &os, DComplex item);
293 LogIO &operator<<(LogIO &os, Int item);
294 LogIO &operator<<(LogIO &os, uInt item);
295 LogIO &operator<<(LogIO &os, Int64 item);
296 LogIO &operator<<(LogIO &os, uInt64 item);
297 LogIO &operator<<(LogIO &os, uLong item);
298 LogIO &operator<<(LogIO &os, Long item);
299 LogIO &operator<<(LogIO &os, Bool item);
300 LogIO &operator<<(LogIO &os, ostream &(*item)(ostream &));
301 // </group>
302 
304 {
305  return sink_p.localSink();
306 }
307 
308 inline const LogSinkInterface &LogIO::localSink() const
309 {
310  return sink_p.localSink();
311 }
312 
313 
314 } //# NAMESPACE CASACORE - END
315 
316 #endif
void postThenThrow(const EXC &exc)
Post the accumulated message at SEVERE priority and then throw an exception.
Definition: LogIO.h:229
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size)
Definition: aipsxtype.h:38
LogIO & operator=(const LogIO &other)
int Int
Definition: aipstype.h:50
unsigned long long uInt64
Definition: aipsxtype.h:39
void sourceLocation(const SourceLocation *where)
Change the location in the origin.
~LogIO()
The destructor will post any accumulated message that has not already been posted.
void origin(const LogOrigin &origin)
Change the origin of the accumulated message.
Post the accumulated message then throw an exception.
Definition: LogIO.h:177
Command
Special commands to the LogIO object.
Definition: LogIO.h:171
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
ostream-like interface to creating log messages.
Definition: LogIO.h:167
LogSinkInterface & localSink()
Occasionally it is useful to interrogate the local log sink.
Definition: LogIO.h:303
Change the message priority to WARN.
Definition: LogIO.h:181
LogMessage::Priority priority()
void postThenThrow(const LogMessage &message, const EXC &exc)
Post message and then throw an AipsError exception containing message.toString(). ...
Definition: LogSink.h:207
LogMessage msg_p
Definition: LogIO.h:254
Accepts LogMessages and posts them to some destination.
long Long
Definition: aipstype.h:52
void preparePostThenThrow(const AipsError &x)
Prepare message stream for postThenThrow function.
Change the message priority to SEVERE.
Definition: LogIO.h:179
ostream & output()
Acumulate output in this ostream.
double Double
Definition: aipstype.h:55
Change the message priority to NORMAL.
Definition: LogIO.h:183
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
void postLocally()
Post the accumulated message locally.
unsigned long uLong
Definition: aipstype.h:53
Post the accumulated message.
Definition: LogIO.h:173
LogOrigin: The source code location of the originator of a LogMessage.
Definition: LogOrigin.h:94
ostringstream * text_p
Definition: LogIO.h:255
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:142
const LogSinkInterface & localSink() const
Change the sink that this LogSink actually uses.
void post()
Post the accumulated message.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
LogSink sink_p
Definition: LogIO.h:253
LogIO()
Attach this LogIO object to the global sink with no origin information.
Informational log messages with with time, priority, and origin.
Definition: LogMessage.h:101
Change the message priority to DEBUGGING.
Definition: LogIO.h:190
unsigned int uInt
Definition: aipstype.h:51