DRAMA C++ Intro   Class Hierarchy   Alphabetical List of types   List of Classes   File List   Class Member Index   File Members Index   Related Pages  

gitlogger.h

Go to the documentation of this file.
00001 /*
00002  * Name: filter.m4
00003  *
00004  * Description:
00005  *     DOXYGEN Input file filter for DRAMA source files.
00006  *
00007  *     This file must be complatible with both Solaris and GNU m4.  All
00008  *     unused macros are deleted and this comment must end up as a C/C++
00009  *     compatible comment which is not picked up by DOXYGEN.
00010  * 
00011  * Synopsis:
00012  *    DCF(func)  => Produces a link to a DRAMA C source file func.html 
00013  *                   in ../routines.
00014  *     DDL(link,text) => Produce a link to ../link.html, specified link text.
00015  *
00016  * Language: m4 macro. 
00017  *
00018  * Author: Tony Farrell, AAO.
00019  *
00020  * "@(#) $Id: ACMM:DramaHtml/filter.m4,v 3.24 03-Nov-2009 09:07:29+11 tjf $"
00021  *
00022  * History:
00023  *     10-Nov-2004 - TJF - Original Version.
00024  */
00025 
00026 
00027 
00028 #ifndef GITLOGGER_INC
00029 #define GITLOGGER_INC
00030 /*+
00031  *          G I T L O G G E R . H
00032  *
00033  *  Function:
00034  *      Header file for a class which implements Logging.
00035  *
00036  *      This file now uses DOXYGEN comments to generate the C++ web pages.
00037  *      m4 macros of the form @htmlonly <a href="../routines/function.html">function()</a>@endhtmlonly are used in the comments
00038  *      to refer to DRAMA C function documention (see DramaHtml/Makefile,
00039  *      DramaHtml/doxygen.config and DramaHtml/filter.m4 for detials)
00040  *
00041  *  Description:
00042  *      
00043  *
00044  *  Author(s): Tony Farrell, AAO (TJF)
00045  *
00046  *-
00047  *  History:
00048  *     30-May-2001 - TJF - Original version
00049  *     13-Jun-2001 - TJF - Support log directory specification to constructor.
00050  *     01-Aug-2003 - TJF - Revamp to support all the DRAMA COMMS logs.
00051  *     14-Aug-2003 - TJF - Support a posix background thread.  Add status
00052  *                         arguments to sync and semaphore ops.  Add
00053  *                         ARGS logging level.
00054  *     09-Jan-2003 - TJF - Add support for DOXYGEN comments.
00055  *     16-Sep-2004 - TJF - In the VxWorks implementation of GitLogger___Time(),
00056  *                         the various variables are now static - to ensure all
00057  *                         tasks int he one machine use the same values.
00058  *     01-Dec-2004 - TJF - Add support for flushing the log file after every 
00059  *                         write, variable flushAlways.  Add routines 
00060  *                         GitLoggerFlushAlways() and GitLoggerFile().
00061  *     01-Mar-2006 - TJF - Add Log() function which takes a time tag, rather
00062  *                         then using the current time.  This required 
00063  *                         changes in LogMessage() and UpdateTime().  
00064  *                         GetLogger is now a public member static function.
00065  *     29-Aug-2007 - TJF - Add GitLoggerTune function - allowing us to
00066  *                         turn flushing, file syncs and background thread.
00067  *                       Under linux, the fsync mode is turned off by default
00068  *                         due to performance problems.  GitLoggerTune() can
00069  *                         turn it back on.
00070  *                       Posix Thread support now turned back on, but the
00071  *                         thread must be enabled using GitLoggerTune().  This
00072  *                         change resulted in some refactoring to allow the
00073  *                         semaphore to be created all the time, regardless
00074  *                         of if the posix thread is running.
00075  *                       Support a file size limit of 1/2Gb - with the file
00076  *                         re-opened with a different name under these
00077  *                         conditions.  1/2Gb is well within the normal limit
00078  *                         of 2Gb - so we don't worry about catching every
00079  *                         case where it might occur - just the main logging
00080  *                         entry and file open.
00081  *    29-Aug-2008 - TJF - Add class variables "failed", "compress" and 
00082  *                         "fileSize". 
00083  *                        Add new methods OpenIt(), CheckCompressMode(),
00084  *                         CloseLogFile(), NewName() and NameUsed().
00085  *                        Add new argument to GitLogger::GitLogger().
00086  *
00087  *
00088  * @(#) $Id: ACMM:DramaGit/gitlogger.h,v 3.49 17-Sep-2009 14:08:16+10 tjf $
00089  */
00090 /*
00091  * This file now uses DOXYGEN comments - the following is placed into the
00092  * index page.  note that the @file block says to include the typedefs,
00093  * functions etc from this file into the documentation.
00094  */
00095 
00100 #ifndef VxWorks
00101 /*
00102  * MacOsX (__APPLE__), Linux and Solaris all have posix threads  We define
00103  * the GIT_USE_POSIX_THREADS macro for all of these unless GIT_NO_POSIX_THREADS 
00104  * is defined (allowing an override for older versions if needed).  For
00105  * other machines, can also define GIT_USE_POSIX_THREADS at compile time, but
00106  * this must be consistent for all cases where gitlogger.h is used.
00107  *
00108  * CURRENTLY I HAVE DISABLED POSIX THREADS IN THE CONSTRUCTOR DUE TO APPARENT 
00109  * CONFLICT WITH CFITSIO LIBRARY which id don't understand.  TJF 2004. THE
00110  *  TUNING function can re-enabled it.
00111  */ 
00112 #if defined(__APPLE__) || defined(__linux__) || defined(solaris2)
00113 #ifndef GIT_NO_POSIX_THREADS
00114 #define GIT_USE_POSIX_THREADS
00115 #endif
00116 #endif
00117 #endif
00118 
00119 
00120 #include "DitsTypes.h"
00121 #include "Ers.h"
00122 #ifdef VxWorks
00123 #include <semLib.h>
00124 #include <taskLib.h>
00125 #include <errno.h>
00126 #elif defined (GIT_USE_POSIX_THREADS)
00127 #include <signal.h>
00128 #include <semaphore.h>
00129 #include <pthread.h>
00130 #endif
00131 
00132 
00133 
00134 /*
00135  * Usable log levels.  
00136  *
00137  * When a log call is made, if the and of the supplied log level
00138  * and the currently enabled log level is non-zero, then the message
00139  * is logged.
00140  */
00141 #define  LOG_ALL        0xFFFFFFFF  
00142 #define  LOG_STARTUP    0x01        
00143 #define  LOG_ERRORS     0x02        
00144 #define  LOG_ACTENT     0x04        
00145 #define  LOG_ACTEXIT    0x08        
00146 #define  LOG_INST       0x10        
00147 #define  LOG_MSG        0x20        
00148 #define  LOG_DEBUG      0x40        
00149 #define  LOG_COMMS      0x80        
00150 #define  LOG_USER1      0x100       
00151 #define  LOG_USER2      0x200       
00152 #define  LOG_USER3      0x400       
00153 #define  LOG_USER4      0x800       
00154 #define  LOG_ARGS       0x1000      
00157 #define  LOG_ALWAYS     0x40000     
00158 #define  LOG_ALWAYS_S   0x80000     
00162 #ifdef __cplusplus
00163 
00164 #include <stdio.h>
00165 #include <string>
00166 #include <DitsFix.h>
00167 
00168 /*
00169  * Declare these here so they can be made friends of GitLogger.
00170  */ 
00171 extern "C" FILE *GitLoggerFile(StatusType *status);
00172 extern "C" DVOID GitLoggerFlushAlways(int flag, StatusType *status);
00173 extern "C" DVOID GitLoggerTune(unsigned NewSettings, 
00174                                unsigned *OldSettings, 
00175                                StatusType *status);
00176 
00177 
00178 
00179 class GitLogger;
00180 
00181 /*
00182  * This object fetches and formats the time.  The UpdateTime() function
00183  * updates the internal time and TimeToString() returns the formated
00184  * time string.
00185  */
00186 class GitLogger___Time {
00187     
00188  private:
00189     /* 
00190      * We keep about the formated time we last used - to avoid doing it again
00191      * We also need the time itself - for which we use a "long int" to avoid
00192      * having to include time.h for this module.
00193      */
00194     long int LastTime;
00195     int millisec;  /*  milliseconds within the second */
00196     char timeStr[30];
00197     /* Experimental and debugging value - an offset added to all values
00198        returned by time();
00199     */
00200     static long int timeOffset;
00201 #ifdef VxWorks
00202     static bool initialised;
00203     static long int ticksToTime; /* Add this to the number of seconds since
00204                              system boot to get the current Unix time */
00205     static long int clockRate;
00206 #endif
00207  
00208  public:
00209     GitLogger___Time();
00210 
00211     /*
00212      * Readout the current system time and update the internal time string.  If
00213      * altTime is non-zero, it is a pointer to a time to use instead of the
00214      * current system time.
00215      */
00216     void UpdateTime(GitLogger *logger, StatusType *status, 
00217                     const IMP_AbsTime *altTime=0);
00218      
00219     /*
00220      * Return the time string.
00221      */
00222     const char *TimeString() const { return timeStr; };
00223     /*
00224      * Return the milliseconds point within the second.
00225      */
00226     int Millisec() const { return millisec; };
00227     /*
00228      * Set/Get the current time offset.
00229      */
00230     static void SetTimeOffset(long int t) { timeOffset = t; }
00231     static long int GetTimeOffset() { return timeOffset; }
00232 
00233     
00234 };
00235 
00236 
00409 class GitLogger {
00410 
00411     friend DVOID GitLoggerFlushAlways(int flag, StatusType *status);
00412     friend FILE *GitLoggerFile(StatusType *status);
00413     friend DVOID GitLoggerTune(unsigned NewSettings, 
00414                                unsigned *OldSettings, 
00415                                StatusType *status);
00416 
00417  private:
00418     /*
00419      * This internal object is used to fetch and format the time.
00420      */
00421     GitLogger___Time timer;
00422 
00423     static const int SyncThreadRate = 5;  /* How often in seconds the sync thead
00424                                       runs */
00425 
00426     /* Structure used to maintain level names */
00427     typedef struct  { 
00428         int minsig; unsigned level; const char *string; 
00429     } LevelStruct;
00430 
00431     /* 
00432      * We need to define SemType and SemNull for each 
00433      * architecture.  SemType is the type for a semaphore whilst
00434      * SemNull is a value which indictes a semaphore is invalid
00435      * The ControlSem item should be defined here but its definition
00436      * is always the same ( it just needs to be here so that
00437      * TakeSem() and GiveSem() can use it.
00438      *
00439      * We also need to define TakeSem() and GiveSem() for each
00440      * architecture.  
00441      *
00442      * Additionally, any architecture specific bits should be
00443      * put here.
00444      */
00445 #   ifdef VxWorks
00446         /*
00447          * VxWorks background thread and sempahore.
00448          */
00449         typedef SEM_ID SemType;
00450         static const SemType  SemNull;
00451         /*
00452          * A semaphore used to control access to the log file when
00453          * we use a background thread to write it.
00454          */
00455         SemType ControlSem;
00456         /*
00457          * Semaphore control.  Architecture specific.  If the background
00458          * thread is not supported on an architecutre, then these can
00459          * be null routines.
00460          */
00461         void TakeSem(StatusType *status)  {
00462             if (*status != STATUS__OK) return;
00463             if (ControlSem != SemNull)
00464                 semTake(ControlSem, WAIT_FOREVER);
00465         }
00466         void GiveSem(StatusType *status) const {
00467             if (*status != STATUS__OK) ;
00468             if (ControlSem != SemNull)
00469                 semGive(ControlSem);
00470         }
00471         void CreateSem(StatusType *status);
00472         void DeleteSem();
00473         int threadID;      /* The background thread VxWorks task id */ 
00474         int mainTaskID;    /* The main task id */
00475   public: /* so that SyncThreadStatic can access it */
00476         void SyncThread(); /* Implementation method for background thread. */
00477   private:
00478 
00479 #   elif defined(GIT_USE_POSIX_THREADS)
00480 
00481         typedef sem_t SemType;    /* The type of a posix semaphore */
00482         SemType ControlSemX;       /* For sem_init() use  */
00483         SemType *ControlSemAddr;  /* If using sem_init(), then &ControlSem,
00484                                      if using sem_open(), return value from
00485                                      sem_open() */
00486         bool SemOk;             /* Indicates if the semaphore was created ok*/
00487         bool SemIsTaken;        /* Indicates if the semaphore is taken */
00488         bool ThreadOk;          /* Was thread created ok */
00489 
00490         sigset_t origSigMask;  /* Signal mask at point semaphore is taken */
00491 
00492         void TakeSem(StatusType *status) ;
00493         void GiveSem(StatusType *status) ;
00494         void CreateSem(StatusType *status);
00495         void DeleteSem();
00496 
00497         static void UserSignalHandler(int);
00498 
00499 
00500         pthread_t syncThreadId;
00501         pthread_t semThreadId;
00502 
00503         std::string semName;  /* Name if used named semaphore */
00504 
00505       public: /* So that extern "C" linkage statics can access them */
00506         void SyncThread(); /* Implementation method for background thread. */
00507         void SyncThreadCleanup();
00508       private:
00509 
00510 #   else
00511         /* Default values - architectures without a background thread */
00512         typedef int    SemType;
00513         static const SemType  SemNull = 0;
00514         SemType ControlSem;  /* Definition always the same */
00515         void TakeSem(StatusType *)  { };
00516         void GiveSem(StatusType *)  { };
00517         void CreateSem(StatusType *) {};
00518         void DeleteSem() {};
00519 #   endif
00520 
00521 
00522     static const LevelStruct LevelNames[];
00523     static const char *RescheduleReasons[];
00524     static const char *Requests[];
00525     static const char *PathStatus[];
00526     static const char *MessageTypes[];
00527 
00528     /* Maximum length of messages */
00529     static const int MsgLen;
00530     static const char *LogFormat;
00531     static const char *LogFormatTimed;
00532     static const char *LogFormatHeader;
00533 
00534     /* Current Logging levels - which goto the file and which to the screen.*/
00535     unsigned FileLevels;
00536     unsigned ScreenLevels;
00537 
00538     /* If we true,then logging of MsgOut messages is disabled (since we 
00539        are using MsgOut to log to screen)
00540     */
00541     bool DisableMsgOut;
00542 
00543     /* Log file */
00544     FILE *LogFile;
00545     std::string LogFileName;
00546 
00547     /*
00548      * LastDay contain the day number in the year.  We use it to work
00549      * out if the day has changed.
00550      */
00551     int LastDay;
00552 
00553     /*
00554      * Directory and system names supplied to constructor.
00555      */
00556     std::string directory;
00557     std::string system;
00558     /*
00559      * Set true to always flush the log file.
00560      */
00561     bool flushAlways;
00562     /*
00563      * Set true to turn of fsync() operation when flusshing
00564      */
00565     bool noFsync;
00566     /*
00567      * Set true to disable LogFlush()
00568      */
00569     bool noLogFlush;
00570     /*
00571      * Are we trying to run the sync thread.
00572      */
00573     bool syncThreadRun;
00574     /*
00575      * Is the sync thread actually running
00576      */
00577     bool syncThreadIsRunning;
00578     /*
00579      * Set true when the log is flushed, cleared when messages
00580      * are written.
00581      */
00582     bool flushed;
00583 
00584     /*
00585      * Last write to log file failed.
00586      */
00587     bool failed;
00588     /*
00589      * Are we compressing data on the fly (posix only)
00590      */
00591     bool compress;
00592     /*
00593      * This variable records the approimate file size - in particular, the
00594      * amount of data we have written to the file using GitLogger::LogMessage(), the
00595      * core logging routine.  It does not record various bits of header information.
00596      *
00597      * We use this allow us to create a new log file every 512 MB - to avoid file system
00598      * file size problems which occur at about 1 GB on older file systems..  
00599      */
00600     INT32 fileSize;
00601 
00602     /*
00603      * Background sync thread initialisation/shutdown.
00604      */
00605     void SyncThreadStart(StatusType *status);
00606     void SyncThreadStop();
00607 
00608     /*
00609      * Used to actually sync the log file.
00610      */
00611     void SyncFile(const char *from_where, StatusType *);
00612     /*
00613      * We need a static routine to implement the log level action
00614      * which can then call the object routine Action.
00615      */
00616     static void LogLevelAction(StatusType *status);
00617     void Action(StatusType *status);
00618 
00619     /*
00620      * static routines which are passed to DRAMA to implement the
00621      * DRAMA logging system.  See DitsSetLogSys().
00622      */
00623     static DVOID ActionEntryLog(DVOIDP client_data,StatusType *status);
00624     static DVOID ActionReturnLog(
00625         DVOIDP client_data,
00626         int argDelete,
00627         SdsIdType argOut,
00628         DitsReqType request,
00629         int delaySet,
00630         DCONSTV DitsDeltaTimeType * delay,
00631         StatusType exitStatus,
00632         StatusType *status);
00633     static DVOID GetPathLog(
00634         DVOIDP client_data,
00635         DCONSTV  char * name,
00636         DCONSTV  char * node,
00637         int flags,
00638         DCONSTV DVOIDP info,
00639         DitsPathType path,
00640         DitsTransIdType transid,
00641         StatusType *  status);
00642     static  DVOID MsgSendLog(
00643         DVOIDP client_data,
00644         long int flags,
00645         DitsPathType path,
00646         DitsTransIdType transid,
00647         DCONSTV DitsGsokMessageType *  message,
00648         StatusType *status);
00649     static DVOID LoadLog(
00650         DVOIDP client_data,
00651         DCONSTV char * Machine,
00652         DCONSTV char * TaskName,
00653         DCONSTV char * ArgString,
00654         long int Flags,
00655         DCONSTV DitsTaskParamType * TaskParams,
00656         DitsTransIdType transid,
00657         StatusType *status);
00658     static  DVOID NotifyReqLog(
00659         DVOIDP client_data,
00660         int notifyRequested,
00661         DitsPathType path,
00662         DitsTransIdType transid,
00663         StatusType *status);
00664     static DVOID MsgOutLog(
00665         DVOIDP client_data,
00666         DCONSTV char * message,
00667         StatusType *status);
00668     static DVOID LogMsgLog(
00669         DVOIDP client_data,
00670         unsigned    level,
00671         DCONSTV char * prefix,
00672         DCONSTV char * fmt,
00673         va_list ap,
00674         StatusType *status);
00675 
00676     static DVOID LogTrigger(
00677         DVOIDP client_data,
00678         SdsIdType arg,
00679         StatusType *status);    
00680 
00681     static DVOID LogTrigBulk(
00682         DVOIDP client_data,
00683         DCONSTV DVOIDP SharedMemInfo,
00684         int sds,
00685         int NotifyBytes,
00686         DitsTransIdType transid,
00687         StatusType *status);
00688 
00689     static DVOID LogSignal(
00690         DVOIDP client_data,
00691         long int actptr,
00692         DCONSTV DVOIDP ptr,
00693         SdsIdType arg,
00694         StatusType *status);    
00695 
00696     static DVOID LogBulkSend(
00697         DVOIDP client_data,
00698         DCONSTV long int flags,
00699         DCONSTV DitsPathType path,
00700         DCONSTV DVOIDP SharedMemInfo,
00701         int NotifyBytes,
00702         DitsTransIdType transid,
00703         DCONSTV DitsGsokMessageType *  message,
00704         StatusType * status);  
00705 
00706 
00707     static DVOID ErsLog(DVOIDP logArg, DCONSTV ErsMessageType * message,
00708                        StatusType * status);
00709     static DVOID LogShutdown(
00710         DVOIDP client_data,
00711         int taskShutdown,
00712         StatusType *status);
00713         
00714     static DVOID LogFlush(DVOIDP client_data, StatusType *status);
00715     static DVOID LogInfo(DVOIDP client_data, StatusType *status);
00716     
00717         
00718     /*
00719      * The actual routine which logs to the file etc.  If altTime is specified,
00720      * then the log message is taged with that time, otherwise it is taged
00721      * with the current time
00722      */
00723     void LogMessage(bool logToFile, bool logToScreen, const char *prefix,
00724                     const char *message, StatusType *status,
00725                     const IMP_AbsTime *altTime=0);
00726 
00727 
00728     /*
00729      * Function to set the logging levels from a string.
00730      */
00731     void SetLevels(const char *s, StatusType *status);
00732     /* Functions to fetch logging levels. */
00733     void GetLevels(std::string *s, StatusType *status);
00734     void GetLevels(int stringLen, char *s, StatusType *status);
00735     /* Support function for GetLevels */
00736     void LevelCheckAndAdd(const unsigned index, std::string *const s);
00737 
00738     void OpenLogFile(bool day_rollover, bool size, StatusType *status);
00739     void OpenIt(const std::string &BaseLogFileName);
00740     /* Check if the file size has got too large */
00741     void CheckFileSize(StatusType *status);
00742 
00743     /* Check if we should use compress mode */
00744     void CheckCompressMode();
00745     /* Close log file */
00746     void CloseLogFile();
00747 
00748     /* Create a new log file name */
00749     static std::string NewName(const std::string &BaseLogFileName, int counter);
00750 
00751     /* Has a log file named already been used */
00752     static bool NameUsed(const std::string &name);
00753     /*
00754      * Assignemnt operation and Copy constructor  made private
00755      * to avoid misuse.
00756      */
00757     void operator=(const GitLogger&);
00758     GitLogger(const GitLogger&);
00759 
00760     /* Destructor - protected to prevent non-heap objects.  */
00761  protected:
00762     ~GitLogger();
00763 
00764 
00765  public:
00766 
00784     GitLogger(const char *system, StatusType *status, const char *dir=0, bool compress=false);
00785 
00791     void CheckDayChange(int newDay, StatusType *status);
00792 
00793 
00800     static void SetTimeOffset(long int t){GitLogger___Time::SetTimeOffset(t); }
00801     
00815     void Log(unsigned level, bool nofmt, const char *prefix,
00816              StatusType *status, const char *fmt, ...)
00817 #ifdef __GNUC__
00818         //DOES NOT WORK - WHY      __attribute__ ((format (printf, 5, 6)))
00819 #endif
00820        ;
00821 
00847     void Log(const IMP_AbsTime *time,
00848              unsigned level, bool nofmt, const char *prefix,
00849              StatusType *status, const char *fmt, ...)
00850 #ifdef __GNUC__
00851         //DOES NOT WORK - WHY      __attribute__ ((format (printf, 5, 6)))
00852 #endif
00853        ;
00854 
00863     void Set(unsigned newFileLevels, unsigned newScreenLevels, 
00864              StatusType *status);
00865       
00874     void Unset(unsigned newFileLevels, unsigned newScreenLevels, 
00875              StatusType *status);
00876 
00885     static GitLogger *GetLogger(StatusType * const status);
00886 
00887 
00888 };
00889 /* Now C level interfaces */
00890 extern "C" {
00891 #endif
00892 
00898     DPUBLIC DVOID GitLoggerInit(const char *system,StatusType *status);
00906     DPUBLIC FILE *GitLoggerFile(StatusType *status);
00907 
00916     DPUBLIC DVOID GitLoggerFlushAlways(int flag, StatusType *status);
00917 
00918 
00933 #define GIT_LOGGER_M_NO_FSYNC      1  /* If set, don't fsync on flush */
00934 #define GIT_LOGGER_M_FLUSH_ALWAYS  2  /* If set, flush on each event */
00935 #define GIT_LOGGER_M_LOG_FLUSH_OFF 4  /* If set, don't flush on LogFlush() events,
00936                                          normally DitsMsgOut events */
00937 #define GIT_LOGGER_M_SYNC_THRD_RUN 8 /* If set - run the sync thread */
00938 #define GIT_LOGGER_M_SYNC_THRD_IS_RNNNG 16 /* Return only - if set - sync 
00939                                               thread is running */
00940     DPUBLIC DVOID GitLoggerTune(unsigned NewSettings, 
00941                                 unsigned *OldSettings, 
00942                                 StatusType *status);
00943 #ifdef __cplusplus
00944 }
00945 #endif
00946 
00947 #endif
00948 

Click here for the DRAMA home page and here for the AAO home page.

For more information, contact tjf@aaoepp.aao.gov.au 

Generated on Tue Nov 3 09:09:56 2009 for AAO DRAMA C++ Interfaces by doxygen 1.2.18