00001
00002
00003
00004
00005
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
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(×tr[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
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
00052 if (fstat(getfd(), &statbuf) == -1)
00053 statbuf.st_size = 0;
00054
00055
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
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
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
00096 WvDirIter i(getdirname(filename), false);
00097 i.rewind();
00098 while (i.next() && keep_for)
00099 {
00100
00101 if (!strncmp(i.ptr()->name, base, strlen(base)))
00102
00103 if (i.ptr()->st_mtime <
00104 wvtime().tv_sec - keep_for*86400)
00105 {
00106
00107 unlink(i.ptr()->fullname);
00108 }
00109 }
00110 }