casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableLogSink.h
Go to the documentation of this file.
00001 //# TableLogSink.h: Save log messages in an AIPS++ Table
00002 //# Copyright (C) 1996,1997,1998,2000,2001,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: TableLogSink.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00028 
00029 #ifndef TABLES_TABLELOGSINK_H
00030 #define TABLES_TABLELOGSINK_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Logging/LogSink.h>
00035 #include <casa/Logging/LogFilter.h>
00036 #include <tables/Tables/Table.h>
00037 #include <tables/Tables/ScalarColumn.h>
00038 #include <tables/Tables/ArrayColumn.h>
00039 #include <casa/Utilities/Assert.h>
00040 #include <casa/Exceptions/Error.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 //# Forward Declarations
00045 class TableDesc;
00046 class SetupNewTable;
00047 
00048 // <summary>
00049 // Save log messages in an AIPS++ Table
00050 // </summary>
00051 
00052 // <use visibility=export>
00053 
00054 // <reviewed reviewer="wbrouw" date="1996/08/21" tests="tLogging.cc" demos="dLogging.cc">
00055 // </reviewed>
00056 
00057 // <prerequisite>
00058 //   <li> <linkto class=LogSinkInterface>LogSinkInterface</linkto>
00059 //   <li> <linkto module=Tables>Tables</linkto>
00060 // </prerequisite>
00061 //
00062 // <etymology>
00063 // Log to an AIPS++ Table.
00064 // </etymology>
00065 //
00066 // <synopsis>
00067 // Unlike the other classes derived from 
00068 // <linkto class=LogSinkInterface>LogSinkInterface</linkto>, there are utility
00069 // functions in this class which might be of some modest interest. In
00070 // particular, the member functions which define the structure of the table
00071 // and define the column names might be of interest.
00072 //
00073 // This class posts messages which pass the filter to an AIPS++
00074 // <linkto class=Table>Table</linkto>. It puts every field of the
00075 // <linkto class=LogMessage>LogMessage</linkto> into its own column.
00076 // </synopsis>
00077 //
00078 // <example>
00079 // See <linkto file="Logging.h">Logging.h</linkto>.
00080 // </example>
00081 //
00082 // <motivation>
00083 // "Persistent" log messages must be stored in a Table.
00084 // </motivation>
00085 //
00086 // <todo asof="2001/06/12">
00087 //   <li> Allow a subset of the columns to be written? e.g., only time, 
00088 //        message, and priority.
00089 //   <li> Allow time sorting in concatenate?
00090 // </todo>
00091 
00092 class TableLogSink : public LogSinkInterface
00093 {
00094 public:
00095   // If <src>fileName</src> exists, attach and append to it, otherwise create
00096   // a table with that name. If the table exists, it must have all the
00097   // required columns defined by <src>logTableDescription()</src>.
00098   // <group>
00099   TableLogSink (LogMessage::Priority filter, const String& fileName);
00100   TableLogSink (const LogFilterInterface& filter, const String& fileName);
00101   // </group>
00102 
00103   // Open the log table for readonly.
00104   // If needed, reopenRW can be used later to define a filter and
00105   // to open the logtable for writing.
00106   explicit TableLogSink (const String& fileName);
00107 
00108   // After copying, both sinks will write to the same <src>Table</src>.
00109   // <group>
00110   TableLogSink (const TableLogSink& other);
00111   TableLogSink& operator= (const TableLogSink& other);
00112   // </group>
00113 
00114   ~TableLogSink();
00115 
00116   // Reopen the logtable for read/write (if needed).
00117   // When it actually reopens, the given filter will be used.
00118   void reopenRW (const LogFilterInterface& filter);
00119 
00120   // If the message passes the filter, write it to the log table.
00121   virtual Bool postLocally (const LogMessage& message);
00122 
00123   // Get number of messages in sink.
00124   virtual uInt nelements() const;
00125 
00126   // Get given part of the i-th message from the sink.
00127   // <group>
00128   virtual Double getTime (uInt i) const;
00129   virtual String getPriority (uInt i) const;
00130   virtual String getMessage (uInt i) const;
00131   virtual String getLocation (uInt i) const;
00132   virtual String getObjectID (uInt i) const;
00133   // </group>
00134 
00135   // Access to the actual log table and its columns.
00136   // <note role=caution>
00137   // Functions <src>time, priority, message, location, objectID</src>
00138   // return a null <src>ScalarColumn</src> object when the logtable is
00139   // not writable. Using it may result in using a null pointer
00140   // causing a core dump. In debug mode it is checked if the object
00141   // is not null.
00142   // </note>
00143   // <group>
00144   const Table& table() const;
00145   Table& table();
00146   const ROScalarColumn<Double>& roTime() const;
00147   ScalarColumn<Double>& time();
00148   const ROScalarColumn<String>& roPriority() const;
00149   ScalarColumn<String>& priority();
00150   const ROScalarColumn<String>& roMessage() const;
00151   ScalarColumn<String>& message();
00152   const ROScalarColumn<String>& roLocation() const;
00153   ScalarColumn<String>& location();
00154   const ROScalarColumn<String>& roObjectID() const;
00155   ScalarColumn<String>& objectID();
00156   // </group>
00157   
00158   // Defines the minimal set of columns in the table (more may exist, but
00159   // are ignored.
00160   enum Columns { 
00161     // MJD in seconds, UT. (Double.)
00162     TIME, 
00163     // Message importance. (String).
00164     PRIORITY,
00165     // Informational message. (String).
00166     MESSAGE, 
00167     // Source code origin of the log message. Usually a combination of
00168     // class name, method name, file name and line number, but any String
00169     // is legal.
00170     LOCATION, 
00171     // ObjectID of distributed object that created the message (String).
00172     // If empty, no OBJECT_ID was set.
00173     OBJECT_ID
00174   };
00175 
00176   // Turn the <src>Columns</src> enum into a String which is the actual
00177   // column name in the <src>Table</src>.
00178   static String columnName(Columns which);
00179 
00180   // Description of the log table. You can use this if, e.g., you do not
00181   // want to use the storage managers that this class creates by default
00182   // (currently Miriad).
00183   static TableDesc logTableDescription();
00184 
00185   // Write out any pending output to the table.
00186   virtual void flush (Bool global=True);
00187 
00188   // Write a message (usually from another logsink) into the local one.
00189   virtual void writeLocally (Double time, const String& message,
00190                              const String& priority, const String& location,
00191                              const String& objectID);
00192 
00193   // Clear the local sink (i.e. remove all messages from it).
00194   virtual void clearLocally();
00195 
00196   // Returns the id for this class...
00197   static String localId( );
00198   // Returns the id of the LogSink in use...
00199   String id( ) const;
00200 
00201   // Make a LogSink for a TableLogSink with a new table.
00202   // Default filter is <src>NORMAL</src>.
00203   // <group>
00204   static LogSink makeSink (const String& fileName);
00205   static LogSink makeSink (LogMessage::Priority filter,
00206                            const String& fileName);
00207   static LogSink makeSink (const LogFilterInterface& filter,
00208                            const String& fileName);
00209   // </group>
00210 
00211 private:
00212   // Undefined and inaccessible
00213   TableLogSink();
00214   // Avoid duplicating code in copy ctor and assignment operator
00215   void copy_other(const TableLogSink& other);
00216   // Make a new log table.
00217   void makeTable (SetupNewTable&);
00218   // Attach the column objects and create unit keywor if needed.
00219   void attachCols();
00220   // Initialize the object.
00221   void init (const String& fileName);
00222 
00223 
00224   Table log_table_p;
00225   // Message
00226   ROScalarColumn<Double>  roTime_p;
00227   ROScalarColumn<String>  roPriority_p;
00228   ROScalarColumn<String>  roMessage_p;
00229   // Origin
00230   ROScalarColumn<String>  roLocation_p;
00231   // ObjectID
00232   ROScalarColumn<String>  roId_p;
00233   ScalarColumn<Double>  time_p;
00234   ScalarColumn<String>  priority_p;
00235   ScalarColumn<String>  message_p;
00236   // Origin
00237   ScalarColumn<String>  location_p;
00238   // ObjectID
00239   ScalarColumn<String>  id_p;
00240 };
00241 
00242 //# Inlines
00243 inline const Table& TableLogSink::table() const {return log_table_p;}
00244 inline Table& TableLogSink::table() {return log_table_p;}
00245 
00246 inline const ROScalarColumn<Double>& TableLogSink::roTime() const
00247   {return roTime_p;}
00248 inline ScalarColumn<Double>& TableLogSink::time()
00249   {DebugAssert(!time_p.isNull(),AipsError); return time_p;}
00250 inline const ROScalarColumn<String>& TableLogSink::roPriority() const 
00251    {return roPriority_p;}
00252 inline ScalarColumn<String>& TableLogSink::priority()
00253   {DebugAssert(!priority_p.isNull(),AipsError); return priority_p;}
00254 inline const ROScalarColumn<String>& TableLogSink::roLocation() const 
00255   {return roLocation_p;}
00256 inline ScalarColumn<String>& TableLogSink::location()
00257   {DebugAssert(!location_p.isNull(),AipsError); return location_p;}
00258 inline const ROScalarColumn<String>& TableLogSink::roObjectID() const 
00259   {return roId_p;}
00260 inline ScalarColumn<String>& TableLogSink::objectID()
00261   {DebugAssert(!id_p.isNull(),AipsError); return id_p;}
00262 inline const ROScalarColumn<String>& TableLogSink::roMessage() const
00263   {return roMessage_p;}
00264 inline ScalarColumn<String>& TableLogSink::message()
00265   {DebugAssert(!message_p.isNull(),AipsError); return message_p;}
00266 
00267 inline LogSink TableLogSink::makeSink (const String& fileName)
00268   { return makeSink (LogFilter(), fileName); }
00269 inline LogSink TableLogSink::makeSink (LogMessage::Priority filter,
00270                                        const String& fileName)
00271   { return makeSink (LogFilter(filter), fileName); }
00272 
00273 
00274 
00275 } //# NAMESPACE CASA - END
00276 
00277 #endif