FileLogger.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              FileLogger.cpp
00004 //------------------------------------------------------------------------------
00005 // $Id: FileLogger.cpp,v 1.9 2005/08/19 03:18:24 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     if (logfname_ == NULL || maxsize_ <= 0) {
00036         errno = EINVAL;
00037         return -1;
00038     }
00039 
00040     if (m_state == opened) {
00041         errno = EEXIST;
00042         return -1;
00043     }
00044 
00045     m_logfname = logfname_;
00046     m_groups   = groups_;
00047     m_maxsize  = maxsize_;
00048 
00049     m_sink.open (m_logfname.c_str (), std::ios::out | std::ios::app);
00050 
00051     if (!m_sink) {
00052         return -1;
00053     }
00054     m_state = opened;
00055     return 0;
00056 }
00057 
00058 int  
00059 FileLogger::
00060 log_close (void)
00061 {
00062     if (m_state != closed) {
00063         m_sink << std::flush;
00064         m_sink.close ();
00065         m_state = closed;
00066 
00067         if (m_groups == 0) {
00068             ::unlink (m_logfname.c_str ());
00069         }
00070         m_logfname.empty ();
00071         m_maxsize = 0;
00072         m_bytecount = 0;
00073     }
00074     return 0;
00075 }
00076 
00105 int
00106 FileLogger::
00107 log_msg (Group                    g_,
00108          size_t        indent_level_, 
00109          const string&    func_name_,
00110          size_t         expected_sz_,
00111          const char*            fmt_,
00112          va_list           msg_list_)
00113 {
00114     if (m_state == closed) {
00115         errno = EPERM;
00116         return -1;
00117     }
00118 
00119     if (! group_enabled (g_)) {
00120         return 0;
00121     }
00122 
00123     m_bytecount += add_timestamp (m_sink);
00124     m_bytecount += indent_func_name (m_sink, func_name_,indent_level_,FUNC_MSG);
00125 
00126     bool release = false;
00127     char* msgbuf_ptr = format_msg (expected_sz_, fmt_, msg_list_, release);
00128     if (msgbuf_ptr == NULL) {
00129         return -1;              // failed to format
00130     }
00131     m_sink << msgbuf_ptr << std::flush;
00132     m_bytecount += strlen (msgbuf_ptr);
00133 
00134     if (release) {
00135         delete [] msgbuf_ptr;
00136     }
00137 
00138     return handle_rollover ();
00139 }
00140 
00141 int
00142 FileLogger::
00143 log_func (Group g_, size_t indent_level_, const string&  func_name_,
00144           marker_t type_)
00145 {
00146     if (m_state == closed) {
00147         errno = EPERM;
00148         return -1;
00149     }
00150     if (! group_enabled (g_)) {
00151         return 0;
00152     }
00153     m_bytecount += add_timestamp (m_sink);
00154     m_bytecount += indent_func_name (m_sink, func_name_, indent_level_, type_);
00155     m_sink << ((type_ == FUNC_ENTRY) ? "---v---\n" : "---^---\n") << std::flush;
00156     m_bytecount += ::strlen ("---v---\n");
00157     return handle_rollover ();
00158 }
00159 
00160 int
00161 FileLogger::
00162 log_raw_msg (const string&  msg_)
00163 {
00164     if (m_state == closed) {
00165         errno = EPERM;
00166         return -1;
00167     }
00168     m_sink << msg_ << std::flush;
00169     m_bytecount += msg_.length ();
00170     return handle_rollover ();
00171 }
00172 
00173 int
00174 FileLogger::
00175 handle_rollover ()
00176 {
00177     if (m_bytecount >= m_maxsize) {
00178         struct stat fst;
00179         if (::stat (m_logfname.c_str(), &fst) == 0) {
00180             if (S_ISREG (fst.st_mode)) {
00181                 m_sink << "\nReached maximum allowable size\n"
00182                        << "m_bytecount = " << m_bytecount
00183                        << ", m_maxsize = " << m_maxsize << std::endl;
00184                 m_sink.close ();
00185                 m_state = closed;
00186                 m_bytecount = 0;
00187 
00188                 string newname = m_logfname + ".0";
00189                 unlink (newname.c_str ());
00190                 rename (m_logfname.c_str (), newname.c_str ());
00191                 m_sink.open (m_logfname.c_str (), 
00192                              std::ios::app | std::ios::out);
00193                 if (!m_sink) {
00194                     return -1;
00195                 }
00196                 m_state = opened;
00197             }
00198             else if (S_ISCHR (fst.st_mode)) { // It is /dev/null
00199                 m_bytecount = 0;
00200             }
00201             else {
00202                 Assure_exit (1);
00203             }
00204         }
00205     }
00206     return 0;
00207 }
00208 
00209 void
00210 FileLogger::
00211 dump (void)
00212 {
00213 #ifdef BUG_HUNTING
00214     if (m_state == opened) {
00215         m_sink << "m_logfname    = \"" << m_logfname      << "\"\n"
00216                << "m_groups      = 0x";
00217         char oldfill = m_sink.fill ('0');
00218         m_sink << std::setw(8) << std::hex << m_groups << '\n' << std::dec;
00219         m_sink.fill (oldfill);
00220         m_sink << "m_indent_step = "   << m_indent_step   << '\n'
00221                << "m_tmflg       = "   << m_tmflg         << '\n'
00222                << "m_maxsize     = "   << m_maxsize       << '\n'
00223                << "m_state       = opened\n"
00224                << "m_bytecount   = "   << m_bytecount     << std::endl;
00225     }
00226 #endif
00227 }

Generated on Sat Dec 31 19:52:09 2005 for libassa by  doxygen 1.4.5