8 #include "wvtimeutils.h" 11 #include "wvdailyevent.h" 14 #include <sys/types.h> 19 #define MAX_LOGFILE_SZ 1024*1024*100 // 100 Megs 22 #define O_LARGEFILE 00000000 // MAC doesn't need Largefile support, so just make it a dummy value when ORd 25 static time_t gmtoffset()
27 time_t nowgmt = time(NULL);
28 struct tm gmt = *gmtime(&nowgmt);
29 struct tm local = *localtime(&nowgmt);
30 time_t nowantilocal = mktime(&gmt);
31 return nowgmt - nowantilocal;
37 WvLogFileBase::WvLogFileBase(
WvStringParm _filename, WvLog::LogLevel _max_level)
39 WvFile(_filename, O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644)
41 fsync_every = fsync_count = 0;
45 WvLogFileBase::WvLogFileBase(WvLog::LogLevel _max_level)
48 fsync_every = fsync_count = 0;
63 if (fsync_count <= 0 || fsync_count > fsync_every)
65 fsync_count = fsync_every;
74 #define TIME_FORMAT "%b %d %H:%M:%S" // timezones in win32 look stupid 76 #define TIME_FORMAT "%b %d %H:%M:%S %Z" 81 struct tm* tmstamp = localtime(&timenow);
83 strftime(×tr[0], 30, TIME_FORMAT, tmstamp);
85 prefix =
WvString(
"%s: %s<%s>: ", timestr, last_source,
86 loglevels[last_level]);
87 prelen = prefix.len();
92 WvLogFile::WvLogFile(
WvStringParm _filename, WvLog::LogLevel _max_level,
93 int _keep_for,
bool _force_new_line,
bool _allow_append)
94 :
WvLogFileBase(_max_level), keep_for(_keep_for), filename(_filename),
95 allow_append(_allow_append)
97 WvLogRcv::force_new_line = _force_new_line;
101 void WvLogFile::_make_prefix(time_t timenow)
110 if (fstat(getfd(), &statbuf) == -1)
114 if (last_day != ((timenow + gmtoffset())/86400)
115 || statbuf.st_size > MAX_LOGFILE_SZ)
124 if (!keep_for)
return;
125 WvDirIter i(getdirname(filename),
false);
126 for (i.rewind(); i.next(); )
129 if (!strncmp(i.ptr()->name, base, strlen(base)))
132 if (i.ptr()->st_mtime < wvtime().tv_sec - keep_for*86400)
133 ::unlink(i.ptr()->fullname);
145 time_t timenow = wvtime().tv_sec;
146 last_day = (timenow + gmtoffset()) / 86400;
147 struct tm* tmstamp = localtime(&timenow);
150 strftime(buf, 20,
"%Y-%m-%d", tmstamp);
154 fullname =
WvString(
"%s.%s.%s", filename, buf, num++);
155 while (stat(fullname, &statbuf) != -1
156 && (statbuf.st_size >= MAX_LOGFILE_SZ || !allow_append));
158 WvString curname(
"%s.current", filename);
161 WvFile::open(fullname, O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE, 0644);
163 #ifndef _WIN32 // no symlinks in win32 165 int sym = readlink(curname, buf, 20);
166 if (sym > 0 || errno == ENOENT)
183 trim_old_logs(filename, base, keep_for);
190 while ((rv = waitpid(forky, NULL, 0)) != forky)
191 if (rv == -1 && errno != EINTR)
195 trim_old_logs(filename, base, keep_for);
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Basic WvLogRcv that logs to a file.
WvLogRcv adds some intelligence to WvLogRcvBase, to keep track of line-prefix-printing and other form...
Provides support for forking processes.
WvFile implements a stream connected to a file or Unix device.
virtual size_t write(const void *buf, size_t count)
Write data to the stream.
virtual bool flush(time_t msec_timeout)
flush the output buffer, if we can do it without delaying more than msec_timeout milliseconds at a ti...
virtual void _mid_line(const char *str, size_t len)
add text to the current log line.
virtual bool isok() const
return true if the stream is actually usable right now
virtual void close()
Closes the file descriptors.
virtual void _make_prefix(time_t now_sec)
Set the Prefix and Prefix Length (size_t prelen)
virtual void _end_line()
End this (Guaranteed NonEmpty) log line.
WvString getfilename(WvStringParm fullname)
Take a full path/file name and splits it up into respective pathname and filename.
pid_t wvfork(int dontclose1=-1, int dontclose2=-1)
wvfork() just runs fork(), but it closes all file descriptors that are flagged close-on-exec, since we don't necessarily always run exec() after we fork()...
WvString is an implementation of a simple and efficient printable-string class.