diff --git a/castor/Imakefile b/castor/Imakefile index 74435f4346fd8e57033b9ace1776175f837fb108..a6a554ca4d2ed4017a6ea3928fd32fc13904ed4c 100644 --- a/castor/Imakefile +++ b/castor/Imakefile @@ -17,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -# @(#)$RCSfile: Imakefile,v $ $Revision: 1.10 $ $Release$ $Date: 2004/05/28 08:56:54 $ $Author: sponcec3 $ +# @(#)$RCSfile: Imakefile,v $ $Revision: 1.11 $ $Release$ $Date: 2004/05/28 09:40:26 $ $Author: sponcec3 $ # # Make Castor libraries and executables # @@ -92,6 +92,7 @@ STGLIB_SRCS = IAddressCInt.cpp \ Services.cpp \ ServicesCInt.cpp \ logstream.cpp \ + logbuf.cpp \ client/BaseClient.cpp \ io/Socket.cpp \ io/StreamAddress.cpp \ diff --git a/castor/logbuf.cpp b/castor/logbuf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55ecc97fc604859abd01e8672096eac50a8bdcd8 --- /dev/null +++ b/castor/logbuf.cpp @@ -0,0 +1,54 @@ +/****************************************************************************** + * logbuf.cpp + * + * This file is part of the Castor project. + * See http://castor.web.cern.ch/castor + * + * Copyright (C) 2003 CERN + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program 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 General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * @(#)$RCSfile: logbuf.cpp,v $ $Revision: 1.1 $ $Release$ $Date: 2004/05/28 09:40:26 $ $Author: sponcec3 $ + * + * + * + * @author Sebastien Ponce + *****************************************************************************/ + +// Include Files +#include "castor/logbuf.h" +#include <time.h> +#include <sstream> +#include <iomanip> +#include <Cthread_api.h> + +//----------------------------------------------------------------------------- +// getTimeStamp +//----------------------------------------------------------------------------- +std::string castor::logbuf::getTimeStamp() { + struct tm tmstruc, *tm; + time_t current_time; + + (void) time (¤t_time); + (void) localtime_r (¤t_time, &tmstruc); + tm = &tmstruc; + + std::ostringstream buf; + + buf << std::setw(2) << tm->tm_mon+1 + << "/" << tm->tm_mday + << " " << tm->tm_hour + << ":" << tm->tm_min + << ":" << tm->tm_sec + << " " << Cthread_self() << " "; + return buf.str(); +} diff --git a/castor/logbuf.h b/castor/logbuf.h new file mode 100644 index 0000000000000000000000000000000000000000..f3a16e39dca25bd8d55982417212d6a15491ca2a --- /dev/null +++ b/castor/logbuf.h @@ -0,0 +1,86 @@ +/****************************************************************************** + * logbuf.h + * + * This file is part of the Castor project. + * See http://castor.web.cern.ch/castor + * + * Copyright (C) 2003 CERN + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program 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 General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * @(#)$RCSfile: logbuf.h,v $ $Revision: 1.1 $ $Release$ $Date: 2004/05/28 09:40:26 $ $Author: sponcec3 $ + * + * + * + * @author Sebastien Ponce + *****************************************************************************/ + +#ifndef CASTOR_LOGBUF_H +#define CASTOR_LOGBUF_H 1 + +// Include Files +#include <iostream> +#include <fstream> +#include <string> + +namespace castor { + + class logbuf : public std::filebuf { + + public: + + /** + * Constructor + */ + logbuf() : std::filebuf(), m_newline(true) {} + + public: + + /** + * output of n characters in one go + */ + virtual std::streamsize + xsputn(const char* __s, std::streamsize __n) { + if (m_newline) { + std::string prefix = getTimeStamp(); + std::filebuf::xsputn(prefix.c_str(), prefix.size()); + } + m_newline = (__s[__n-1] == '\n'); + std::filebuf::xsputn(__s, __n); + } + + /** + * set m_newline to true + */ + void setNewLine() { m_newline = true; } + + private: + + /** + * Build a prefix for logs containing the date, time + * and thread number + */ + std::string getTimeStamp(); + + private: + + /** + * remember whether we are at a new line + */ + bool m_newline; + + }; + + +} // End of namespace Castor + +#endif // CASTOR_LOGBUF_H diff --git a/castor/logstream.h b/castor/logstream.h index 5bb9f04dea2516eb93b3c908d42844112af5c525..cd700b57c90de54337e080cac84cbb484108dda9 100644 --- a/castor/logstream.h +++ b/castor/logstream.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * @(#)$RCSfile: logstream.h,v $ $Revision: 1.1.1.1 $ $Release$ $Date: 2004/05/12 12:13:34 $ $Author: sponcec3 $ + * @(#)$RCSfile: logstream.h,v $ $Revision: 1.2 $ $Release$ $Date: 2004/05/28 09:40:26 $ $Author: sponcec3 $ * * * @@ -29,8 +29,9 @@ // Include Files #include <string> -#include <fstream> +#include <ostream> #include "osdep.h" +#include "castor/logbuf.h" #define OPERATOR(T) \ logstream& operator<< (T var) { \ @@ -47,7 +48,7 @@ m_isIP = false; \ printIP(var); \ } else { \ - this->std::ofstream::operator<<(var); \ + this->std::ostream::operator<<(var); \ } \ } \ return *this; \ @@ -56,11 +57,11 @@ #define MANIPULATOR(T) castor::logstream& T(castor::logstream& s); namespace castor { - - class logstream : virtual public std::ofstream { - + + class logstream : virtual public std::ostream { + public: - + /** * The different possible level of output */ @@ -77,14 +78,33 @@ namespace castor { } Level; public: - + /** * constructor */ explicit logstream(const char* p, Level l = INFO) : - std::ofstream(p, std::ios::app), m_minLevel(l), - m_curLevel(INFO), m_isIP(false) { - printf("logstream name : %s\n", p); + std::ostream(0), + m_logbuf(), + m_minLevel(l), + m_curLevel(INFO), + m_isIP(false) { + // Deal with the buffer + this->init(&m_logbuf); + if (!m_logbuf.open(p, std::ios::app | std::ios_base::out)) { + this->setstate(ios_base::failbit); + } + } + + /** + * @brief Close the file. + * + * Calls @c std::basic_filebuf::close(). If that function + * fails, @c failbit is set in the stream's error state. + */ + void close() { + if (!m_logbuf.close()) { + this->setstate(ios_base::failbit); + } } public: @@ -120,6 +140,8 @@ namespace castor { * castor::logstream */ logstream& operator<< (std::ostream& (&f)(std::ostream&)) { + if (&f == (std::ostream& (&)(std::ostream&))std::endl) + m_logbuf.setNewLine(); f(*this); return *this; } @@ -149,6 +171,12 @@ namespace castor { private: + /** + * The log buffer used on top of the file buffer for + * prefixing the logs with timestamps + */ + castor::logbuf m_logbuf; + /** * The current minimum level of output for the stream * everything under it will not be output