Evan Teran
Evan Teran

Reputation: 90452

Linux/c++ log rotation scheme

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

Answers (3)

Hasturkun
Hasturkun

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

Steve Lazaridis
Steve Lazaridis

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

Paul Tomblin
Paul Tomblin

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

Related Questions