Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvlogfile.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * A "Log Receiver" that logs messages to a file
00006  */
00007 
00008 #include <time.h>
00009 #include "wvlogfile.h"
00010 #include "wvtimeutils.h"
00011 #include "wvdiriter.h"
00012 #include "strutils.h"
00013 
00014 #define MAX_LOGFILE_SZ  1024*1024*100   // 100 Megs
00015 
00016 
00017 //----------------------------------- WvLogFileBase ------------------
00018 
00019 void WvLogFileBase::_mid_line(const char *str, size_t len)
00020 {
00021     WvFile::write(str, len);
00022 }
00023 
00024 void WvLogFileBase::_make_prefix()
00025 {
00026     time_t timenow = wvtime().tv_sec;
00027     struct tm* tmstamp = localtime(&timenow);
00028     char timestr[30];
00029     strftime(&timestr[0], 30, "%b %d %T %Z", tmstamp);
00030 
00031     prefix = WvString("%s: %s<%s>: ", timestr, appname(last_source),
00032         loglevels[last_level]);
00033     prelen = prefix.len();
00034 }
00035 
00036 //----------------------------------- WvLogFile ----------------------
00037 
00038 WvLogFile::WvLogFile(WvStringParm _filename, WvLog::LogLevel _max_level,
00039      int _keep_for) : WvLogFileBase(_max_level), keep_for(_keep_for),
00040      filename(_filename)
00041 {
00042     start_log();
00043 }
00044 
00045 void WvLogFile::_make_prefix()
00046 {
00047     time_t timenow = wvtime().tv_sec;
00048     struct tm *tmstamp = localtime(&timenow);
00049     struct stat statbuf;
00050 
00051     // Get the filesize
00052     if (fstat(getfd(), &statbuf) == -1)
00053         statbuf.st_size = 0;
00054 
00055     // Make sure we are calculating last_day in the current time zone.
00056     if (last_day < ((timenow + tmstamp->tm_gmtoff)/86400) 
00057         || statbuf.st_size > MAX_LOGFILE_SZ)
00058         start_log();
00059 
00060     WvLogFileBase::_make_prefix();
00061 }
00062 
00063 
00064 void WvLogFile::start_log()
00065 {
00066     WvFile::close();
00067 
00068     int num = 0;
00069     struct stat statbuf;
00070     time_t timenow = wvtime().tv_sec;
00071     struct tm* tmstamp = localtime(&timenow);
00072     last_day = (timenow + tmstamp->tm_gmtoff) / 86400;
00073     char buf[20];
00074     WvString fullname;
00075     strftime(buf, 20, "%Y-%m-%d", tmstamp);
00076 
00077     // Get the next filename
00078     do
00079         fullname = WvString("%s.%s.%s", filename, buf, num++);
00080     while (stat(fullname, &statbuf) != -1 && statbuf.st_size >= MAX_LOGFILE_SZ);
00081 
00082     WvString curname("%s.current", filename);
00083     WvString base = getfilename(filename);
00084 
00085     WvFile::open(fullname, O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644);
00086 
00087     // Don't delete the file, unless it's a symlink!
00088     int sym = readlink(curname, buf, 20);
00089     if (sym > 0 || errno == ENOENT)
00090     {
00091         unlink(curname);
00092         symlink(getfilename(fullname), curname);
00093     }
00094 
00095     // Look for old logs and purge them
00096     WvDirIter i(getdirname(filename), false);
00097     i.rewind();
00098     while (i.next() && keep_for)
00099     {
00100         // if it begins with the base name
00101         if (!strncmp(i.ptr()->name, base, strlen(base)))
00102             // and it's older than 'keep_for' days
00103             if (i.ptr()->st_mtime <
00104                     wvtime().tv_sec - keep_for*86400)
00105             {
00106                 //delete it
00107                 unlink(i.ptr()->fullname);
00108             }
00109     }
00110 }

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1