Reputation: 90452
I have a logger system which basically is a fancy way of writing my data to std::clog in a thread safe way.
I also, redirect std::clog
to a file like this:
int main() {
std::ofstream logfile(config::logname, std::ios::app);
std::streambuf *const old_buffer = std::clog.rdbuf(logfile.rdbuf());
// .. the guts of the application
std::clog.rdbuf(old_buffer);
}
This works great... however, my application also produces a very large amount of logs. I was wondering what would be a good way to properly rotate my log files. Is there a safe way to switch out the file via a cron task? I would guess no.
The only thing I can think of that would definitely work is if I had the application itself open a new file, and redirect the rdbuf of clog to that while holding the logging mutex. But that feels like a cheap solution, and I would need to check so see if it is time to rotate logs fairly often for it to be effective. There has got to be a better way.
Upvotes: 4
Views: 11997
Reputation: 36402
You can use something similar to the following, and move the log file away whichever way (logrotate, cron script, etc.) (providing Cish sample, should be easily convertible)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void logworker()
{
ino_t inode = 0;
FILE *logfile;
logfile = fopen(logfilename, "a+");
while(running)
{
struct stat mystat;
if (stat(logfilename, &mystat)!=0 || mystat.st_ino != inode)
{
logfile = freopen(logfilename, "a+", logfile);
inode = mystat.st_ino;
}
while (stuff_in_buffer)
{
fwrite(); /* etc */
}
fflush(logfile);
/* sleep until something interesting happens */
}
}
It is safe to write to a file after it has been moved, so there's no need for extra caution
Upvotes: 1
Reputation: 2210
Or just use syslog instead of your custom logging scheme and the logs get rotated by logrotate anyway. -- depending on how it's configured but on most desktop/server systems it's already set to rotate them.
Upvotes: 7
Reputation: 182782
You can use the built-in log rotation method configured in /etc/logrotate.conf and/or /etc/logrotate.d/ - it's common to have logrotate send your app a SIGUSR1 as a signal to close and re-open all your log files.
Upvotes: 14