8#include "wvtimeutils.h"
11#include "wvdailyevent.h"
19#define MAX_LOGFILE_SZ 1024*1024*100
22#define O_LARGEFILE 00000000
25static 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;
37WvLogFileBase::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;
45WvLogFileBase::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"
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();
92WvLogFile::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;
101void 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);
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);
virtual bool flush(time_t msec_timeout)=0
flush the output buffer, if we can do it without delaying more than msec_timeout milliseconds at a ti...
virtual bool isok() const =0
By default, returns true if geterr() == 0.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
int getfd() const
Returns the Unix file descriptor for reading and writing.
int getwfd() const
Returns the Unix file descriptor for writing to this stream.
virtual void close()
Closes the file descriptors.
WvFile implements a stream connected to a file or Unix device.
Basic WvLogRcv that logs to a file.
virtual void _make_prefix(time_t now_sec)
Set the Prefix and Prefix Length (size_t prelen)
virtual void _mid_line(const char *str, size_t len)
add text to the current log line.
virtual void _end_line()
End this (Guaranteed NonEmpty) log line.
WvLogRcv adds some intelligence to WvLogRcvBase, to keep track of line-prefix-printing and other form...
virtual size_t write(const void *buf, size_t count)
Write data to the stream.
WvString is an implementation of a simple and efficient printable-string class.
Provides support for forking processes.
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,...
WvString getfilename(WvStringParm fullname)
Take a full path/file name and splits it up into respective pathname and filename.