libassa
3.5.0
|
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 }