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
00036
00037
00038
00039
00040 if (logfname_ == NULL || maxsize_ <= 0) {
00041
00042 errno = EINVAL;
00043 return -1;
00044 }
00045
00046 if (m_state == opened) {
00047
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
00060 return -1;
00061 }
00062
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
00125
00126
00127 if (m_state == closed) {
00128
00129 errno = EPERM;
00130 return -1;
00131 }
00132
00133 if (! group_enabled (g_)) {
00134
00135
00136
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
00147
00148 return -1;
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)) {
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 }