#ifndef __SYS_LOGGER_H__
#define __SYS_LOGGER_H__
/******************************************************************************/
/* */
/* X r d S y s L o g g e r . h h */
/* */
/*(c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
/*Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Deprtment of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#ifndef WIN32
#include
#include
#include
#else
#include
#include
#include "XrdSys/XrdWin32.hh"
#endif
#include "XrdSys/XrdSysPthread.hh"
//-----------------------------------------------------------------------------
//! XrdSysLogger is the object that is used to route messages to wherever they
//! need to go and also handles log file rotation and trimming.
//-----------------------------------------------------------------------------
class XrdOucTListFIFO;
class XrdSysLogger
{
public:
//-----------------------------------------------------------------------------
//! Constructor
//!
//! @param ErrFD is the filedescriptor of where error messages normally
//! go if this class is not used. Default is stderr.
//! @param xrotate when not zero performs internal log rotatation. Otherwise,
//! log rotation is suppressed. See also setRotate().
//-----------------------------------------------------------------------------
XrdSysLogger(int ErrFD=STDERR_FILENO, int xrotate=1);
//-----------------------------------------------------------------------------
//! Destructor
//-----------------------------------------------------------------------------
~XrdSysLogger()
{
RmLogRotateLock();
if (ePath)
free(ePath);
}
//-----------------------------------------------------------------------------
//! Add a message to be printed at midnight.
//!
//! @param msg The message to be printed. A copy of the message is saved.
//-----------------------------------------------------------------------------
void AddMsg(const char *msg);
//-----------------------------------------------------------------------------
//! Add a task to be run at midnight. Tasks are run sequentially lifo.
//!
//! @param mnTask Pointer to an instance of the task object below.
//-----------------------------------------------------------------------------
class Task
{
public:
friend class XrdSysLogger;
virtual void Ring() = 0; //!< This method gets called at midnight
inline Task *Next() {return next;}
Task() : next(0) {}
virtual ~Task() {}
private:
Task *next;
};
void AtMidnight(Task *mnTask);
//-----------------------------------------------------------------------------
//! Bind allows you to bind the file descriptor passed at construction time to
//! a file with an optional periodic closing and opening of the file.
//!
//! @param path The log file path. The file is created, if need be.
//! If path is null, messages are routed to stderr and the
//! lfh argument is ignored.
//! @param lfh Log file handling:
//! >0 file is to be closed and opened at midnight.
//! This implies automatic log rotation.
//! =0 file is to be left open all the time.
//! This implies no log rotation.
//! <0 file is to be closed and opened only on signal abs(lfh)
//! unless the value equals onFifo. In this case a fifo is
//! used to control log file rotation. The name of the fifo
//! is path with the filename component prefixed by dot.
//! This implies manual log rotation. Warning! Using
//! signals requires that Bind() be called before starting
//! any threads so that the signal is properly blocked.
//!
//! @return 0 Processing successful.
//! @return <0 Unable to bind, returned value is -errno of the reason.
//-----------------------------------------------------------------------------
static const int onFifo = (int)0x80000000;
int Bind(const char *path, int lfh=0);
//-----------------------------------------------------------------------------
//! Capture allows you to capture all messages (they are not routed). This is
//! a global setting so use with caution!
//!
//! @param tFIFO Pointer to the XrdOucTListFIFO where messages are saved.
//! If the pointer is nil, capturing is turned off.
//-----------------------------------------------------------------------------
void Capture(XrdOucTListFIFO *tFIFO);
//-----------------------------------------------------------------------------
//! Flush any pending output
//-----------------------------------------------------------------------------
void Flush() {fsync(eFD);}
//-----------------------------------------------------------------------------
//! Get the file descriptor passed at construction time.
//!
//! @return the file descriptor passed to the constructor.
//-----------------------------------------------------------------------------
int originalFD() {return baseFD;}
//-----------------------------------------------------------------------------
//! Parse the keep option argument.
//!
//! @param arg Pointer to the argument. The argument syntax is:
//! \ | \ | fifo | \
//!
//! @return !0 Parsing succeeded. The return value is the argument that
//! must be passed as the lfh parameter to Bind().
//! @return =0 Invalid keep argument.
//-----------------------------------------------------------------------------
int ParseKeep(const char *arg);
//-----------------------------------------------------------------------------
//! Output data and optionally prefix with date/time
//!
//! @param iovcnt The number of elements in iov vector.
//! @param iov The vector describing what to print. If iov[0].iov_base
//! is zero, the message is prefixed by date and time.
//-----------------------------------------------------------------------------
void Put(int iovcnt, struct iovec *iov);
//-----------------------------------------------------------------------------
//! Set call-out to logging plug-in on or off.
//-----------------------------------------------------------------------------
static
void setForwarding(bool onoff) {doForward = onoff;}
//-----------------------------------------------------------------------------
//! Set log file timstamp to high resolution (hh:mm:ss.uuuu).
//-----------------------------------------------------------------------------
void setHiRes() {hiRes = true;}
//-----------------------------------------------------------------------------
//! Set log file keep value.
//!
//! @param knum The keep value. If knum < 0 then abs(knum) files are kept.
//! Otherwise, only knum bytes of log files are kept.
//-----------------------------------------------------------------------------
void setKeep(long long knum) {eKeep = knum;}
//-----------------------------------------------------------------------------
//! Set log file rotation on/off.
//!
//! @param onoff When !0 turns on log file rotations. Otherwise, rotation
//! is turned off.
//-----------------------------------------------------------------------------
void setRotate(int onoff) {doLFR = onoff;}
//-----------------------------------------------------------------------------
//! Start trace message serialization. This method must be followed by a call
//! to traceEnd().
//!
//! @return pointer to the time buffer to be used as the msg timestamp.
//-----------------------------------------------------------------------------
char *traceBeg() {Logger_Mutex.Lock(); Time(TBuff); return TBuff;}
//-----------------------------------------------------------------------------
//! Stop trace message serialization. This method must be preceeded by a call
//! to traceBeg().
//!
//! @return pointer to a new line character to terminate the message.
//-----------------------------------------------------------------------------
char traceEnd() {Logger_Mutex.UnLock(); return '\n';}
//-----------------------------------------------------------------------------
//! Get the log file routing.
//!
//! @return the filename of the log file or "stderr".
//-----------------------------------------------------------------------------
const char *xlogFN() {return (ePath ? ePath : "stderr");}
//-----------------------------------------------------------------------------
//! Internal method to handle the logfile. This is public because it needs to
//! be called by an external thread.
//-----------------------------------------------------------------------------
void zHandler();
private:
int FifoMake();
void FifoWait();
int Time(char *tbuff);
static int TimeStamp(struct timeval &tVal, unsigned long tID,
char *tbuff, int tbsz, bool hires);
int HandleLogRotateLock( bool dorotate );
void RmLogRotateLock();
struct mmMsg
{mmMsg *next;
int mlen;
char *msg;
};
mmMsg *msgList;
Task *taskQ;
XrdSysMutex Logger_Mutex;
long long eKeep;
char TBuff[32]; // Trace header buffer
int eFD;
int baseFD;
char *ePath;
char Filesfx[8];
int eInt;
int reserved1;
char *fifoFN;
bool hiRes;
bool doLFR;
pthread_t lfhTID;
static bool doForward;
void putEmsg(char *msg, int msz);
int ReBind(int dorename=1);
void Trim();
};
#endif