00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <stdarg.h>
00017
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <unistd.h>
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;
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)) {
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 }