Tuesday, June 2, 2015

Easylogging++: how to get one log file per day

I introduced EasyLogging++ before. This article will build on that to show how to rotate the logs daily.

In a nutshell, assuming your log filename already has date specifiers in it, all you have to do is run these two lines, at midnight each day:

auto L = el::Loggers::getLogger("default");

If you have multiple loggers, repeat that for all of them.

I recommend using a config file to configure EasyLogging++; but if you are configuring it completely in your code, and your FILENAME entry does not include date specifiers, you can instead change the filename at any time with this:


But, going back to the first approach, here is a complete program to show creating a new log file every 20 seconds (!). First create a logging.conf file with these contents:

-- default
    FORMAT = "%datetime{%Y-%M-%d %H:%m:%s.%g},%level,%thread,%msg"
    Milliseconds_Width = 4
    TO_FILE = true
    FILENAME = "info.%datetime{%Y%M%d_%H%m%s}.log"

(The FORMAT, and Milliseconds_Width lines are optional, but useful for checking it worked.)

Here is the full code:

#include "easylogging++.h"

namespace sc = std::chrono;

int main(int,char**){
LOG(INFO)<<"The program has started!";

std::thread logRotatorThread([](){
const sc::seconds wakeUpDelta = sc::seconds(20);
auto nextWakeUp = sc::system_clock::now() + wakeUpDelta;

    nextWakeUp += wakeUpDelta;
    LOG(INFO) << "About to rotate log file!";
    auto L = el::Loggers::getLogger("default");
    if(L == nullptr)LOG(ERROR)<<"Oops, it is not called default!";
    else L->reconfigure();



//Main thread
for(int n=0; n < 1000; ++n){
    LOG(TRACE) << n;

LOG(INFO) << "Shutting down.";
return 0;

I compiled it with this command:

g++ -std=c++11 -Wall -Werror logtest.cpp -lpthread -o logtest

and then ran it with this command:


It should be easy to follow. I set up a dedicated thread to call reconfigure() every 20 seconds, and then the main thread logs a counter about 10 times/second.

You’ll end up with about 5 log files, and you can examine them to see that no log commands were lost.

If I was coding for a mission-critical application, where missing even a single log line would be considered Very Bad, I might set up a mutex and a lock to make sure the main thread is not active when the call to reconfigure() happens. I don’t know for sure if that is needed, or if it is guaranteed to be safe. If you know for sure one way or the other, please leave a comment!

But, for a once/day log rotation, in most applications this is a small enough risk that I would not want the overhead of the extra mutex, and I would go with the code shown above.

1 comment:

route66 said...

Thank you, this is an interesting post.

I have a bit more complicated and challenging task though: I have to roll 5 log files of the fixed size.
I've made some attempts but I was really upset with the unexpected results. It seemed to work but it worked weirdly.

I've published my results and the full task description in the Easylogging++ official repository here:

Any advice, hint or help will be strongly appreciated!!!
Have a nice day!