/home/vlg/develop/libASSA/libassa/assa/FileLogger.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              FileLogger.cpp
00004 //------------------------------------------------------------------------------
00005 // $Id: FileLogger.cpp,v 1.10 2006/07/20 02:30:53 vlg Exp $
00006 //------------------------------------------------------------------------------
00007 //  Copyright (C) 1997-2002,2005  Vladislav Grinchenko
00008 //
00009 //  This library is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU Library General Public
00011 //  License as published by the Free Software Foundation; either
00012 //  version 2 of the License, or (at your option) any later version.
00013 //------------------------------------------------------------------------------
00014 
00015 #include <stdio.h>
00016 #include <stdarg.h>             // vsprintf(3)
00017 
00018 #include <sys/types.h>          // stat(2)
00019 #include <sys/stat.h>           // stat(2)
00020 #include <unistd.h>             // stat(2)
00021 
00022 #include <string>
00023 #include <iomanip>
00024 
00025 #include <assa/TimeVal.h>
00026 #include <assa/FileLogger.h>
00027 #include <assa/Assure.h>
00028 
00029 using namespace ASSA;
00030 
00031 int 
00032 FileLogger::
00033 log_open (const char* logfname_, u_long groups_, u_long maxsize_)
00034 {
00035 //  std::cout << "Enter: FileLogger::log_open(fname=\""
00036 //            << logfname_ << "\"" 
00037 //            << " groups=0x" << std::setw(8) << std::hex << groups_
00038 //            << " maxsize=" << std::dec << maxsize_ << ")\n";
00039 
00040     if (logfname_ == NULL || maxsize_ <= 0) {
00041 //      std::cout << "FileLogger::log_open() failed 1\n";
00042         errno = EINVAL;
00043         return -1;
00044     }
00045 
00046     if (m_state == opened) {
00047 //      std::cout << "FileLogger::log_open() already open\n";
00048         errno = EEXIST;
00049         return -1;
00050     }
00051 
00052     m_logfname = logfname_;
00053     m_groups   = groups_;
00054     m_maxsize  = maxsize_;
00055 
00056     m_sink.open (m_logfname.c_str (), std::ios::out | std::ios::app);
00057 
00058     if (!m_sink) {
00059 //      std::cout << "FileLogger::log_open() failed to open()!\n";
00060         return -1;
00061     }
00062 //  std::cout << "Success on FileLogger::log_open()\n";
00063 
00064     m_state = opened;
00065     return 0;
00066 }
00067 
00068 int  
00069 FileLogger::
00070 log_close (void)
00071 {
00072     if (m_state != closed) {
00073         m_sink << std::flush;
00074         m_sink.close ();
00075         m_state = closed;
00076 
00077         if (m_groups == 0) {
00078             ::unlink (m_logfname.c_str ());
00079         }
00080         m_logfname.empty ();
00081         m_maxsize = 0;
00082         m_bytecount = 0;
00083     }
00084     return 0;
00085 }
00086 
00115 int
00116 FileLogger::
00117 log_msg (Group         g_,
00118          size_t        indent_level_, 
00119          const string& func_name_,
00120          size_t        expected_sz_,
00121          const char*   fmt_,
00122          va_list       msg_list_)
00123 {
00124 //  std::cout << "FileLogger::log_msg() enter\n"
00125 //            << "group__=0x" << std::setw(8) << std::hex << (u_long)g_ << "\n";
00126 
00127     if (m_state == closed) {
00128 //      std::cout << "FileLogger::log_msg() sink closed!\n";
00129         errno = EPERM;
00130         return -1;
00131     }
00132 
00133     if (! group_enabled (g_)) {
00134 //      std::cout << "FileLogger::log_msg() group is not enabled!\n"
00135 //                << "m_groups=0x" 
00136 //                << std::setw(8) << std::hex << m_groups << "\n";
00137         return 0;
00138     }
00139 
00140     m_bytecount += add_timestamp (m_sink);
00141     m_bytecount += indent_func_name (m_sink, func_name_,indent_level_,FUNC_MSG);
00142 
00143     bool release = false;
00144     char* msgbuf_ptr = format_msg (expected_sz_, fmt_, msg_list_, release);
00145     if (msgbuf_ptr == NULL) {
00146 //      std::cout << "FileLogger::log_msg() call to format_msg() failed!"
00147 //                << " fmt_= \"" << fmt_ << "\"\n" << std::flush;
00148         return -1;              // failed to format
00149     }
00150     m_sink << msgbuf_ptr << std::flush;
00151     m_bytecount += strlen (msgbuf_ptr);
00152 
00153     if (release) {
00154         delete [] msgbuf_ptr;
00155     }
00156 
00157     return handle_rollover ();
00158 }
00159 
00160 int
00161 FileLogger::
00162 log_func (Group g_, size_t indent_level_, const string&  func_name_,
00163           marker_t type_)
00164 {
00165     if (m_state == closed) {
00166         errno = EPERM;
00167         return -1;
00168     }
00169 
00170     if (! group_enabled (g_)) {
00171         return 0;
00172     }
00173 
00174     m_bytecount += add_timestamp (m_sink);
00175     m_bytecount += indent_func_name (m_sink, func_name_, indent_level_, type_);
00176     m_sink << ((type_ == FUNC_ENTRY) ? "---v---\n" : "---^---\n") << std::flush;
00177     m_bytecount += ::strlen ("---v---\n");
00178 
00179     return handle_rollover ();
00180 }
00181 
00182 int
00183 FileLogger::
00184 log_raw_msg (const string&  msg_)
00185 {
00186     if (m_state == closed) {
00187         errno = EPERM;
00188         return -1;
00189     }
00190 
00191     m_sink << msg_ << std::flush;
00192     m_bytecount += msg_.length ();
00193 
00194     return handle_rollover ();
00195 }
00196 
00197 int
00198 FileLogger::
00199 handle_rollover ()
00200 {
00201     if (m_bytecount >= m_maxsize) {
00202         struct stat fst;
00203         if (::stat (m_logfname.c_str(), &fst) == 0) {
00204             if (S_ISREG (fst.st_mode)) {
00205                 m_sink << "\nReached maximum allowable size\n"
00206                        << "m_bytecount = " << m_bytecount
00207                        << ", m_maxsize = " << m_maxsize << std::endl;
00208                 m_sink.close ();
00209                 m_state = closed;
00210                 m_bytecount = 0;
00211 
00212                 string newname = m_logfname + ".0";
00213                 unlink (newname.c_str ());
00214                 rename (m_logfname.c_str (), newname.c_str ());
00215                 m_sink.open (m_logfname.c_str (), 
00216                              std::ios::app | std::ios::out);
00217                 if (!m_sink) {
00218                     return -1;
00219                 }
00220                 m_state = opened;
00221             }
00222             else if (S_ISCHR (fst.st_mode)) { // It is /dev/null
00223                 m_bytecount = 0;
00224             }
00225             else {
00226                 Assure_exit (1);
00227             }
00228         }
00229     }
00230     return 0;
00231 }
00232 
00233 void
00234 FileLogger::
00235 dump (void)
00236 {
00237 #ifdef BUG_HUNTING
00238     if (m_state == opened) {
00239         m_sink << "m_logfname    = \"" << m_logfname      << "\"\n"
00240                << "m_groups      = 0x";
00241         char oldfill = m_sink.fill ('0');
00242         m_sink << std::setw(8) << std::hex << m_groups << '\n' << std::dec;
00243         m_sink.fill (oldfill);
00244         m_sink << "m_indent_step = "   << m_indent_step   << '\n'
00245                << "m_tmflg       = "   << m_tmflg         << '\n'
00246                << "m_maxsize     = "   << m_maxsize       << '\n'
00247                << "m_state       = opened\n"
00248                << "m_bytecount   = "   << m_bytecount     << std::endl;
00249     }
00250 #endif
00251 }

Generated on Sun Aug 13 15:08:00 2006 for libassa by  doxygen 1.4.6