Boost logo

Boost :

Subject: Re: [boost] [logging] Interest check on logging library.
From: Jason Wagner (jason_at_[hidden])
Date: 2008-12-31 12:30:14


Andrey Semashev wrote:
> Sorry, couldn't resist. I think, my library fits these requirements
> quite well. Why would you start your own implementation from scratch? Is
> there something that doesn't suit you in my implementation?

It started because I thought yours was no longer in development. I have no idea why I thought that, since looking at your cvs logs you have been consistently working on it. It was largely a mistake.

I'm writing a internet spaceship game. There's a client and a cluster of servers with different types. The protocol is simple message passing, with the serialization code shared between client and server. This leads to a very simple example like:

if(message.size > packet.size)
{
   log << severity::warn() << "Packet was larger than the buffer that contains it!"
        << build_target::server() << " Packet source= " << connection << ", account = " << user << "\n"
        << dump_hex(packet);
   // error handling
}

On the client side, we note that the packet was too big and move on. On the server side, we actually log the packet since evil hackers are always trying to steal my space bucks. Since the template generates empty code at compile time, both gcc and msvc are smart enough to remove the " Packet source=" and ", account= " strings from the binary, providing less clue in the client as to what the server is watching for. On the server side, I probably want this record to go into a database, so having the entire thing as a single record is very important. That precludes items of the form:

log << severity::warn() << "...";
if(server) // or #ifdef
  log << "Packet source = "; //...

I also really don't like having the conditional in the logging. Looking at the serialization code, one shouldn't have to wade through the logic of logging.

I think I could add this to your library using features. That's not a light weight thing to add, based upon what I see features need to be instantiated. In my scheme, since the if() test is built into the log record instantiation there's single point to change to affect all appropriate loggers. With your scheme I'd have to change the logger type, the if()s that wrap them or the macros that contain the ifs, and possibly client code as well.

Switching to a different scheme, I could do:

log << severity::warn() << "Packet was larger than the buffer that contains it!"
     << auditing::full() << " Packet source= " << connection << ", account = " << user << "\n"
     << dump_hex(packet);

Now, on the client side I can turn off full auditing at compile time and on the server time I can turn off packet logging at run time and have a condition that turns it on when I suspect a problem. There is a separation of concerns between what audit level and severity of the record.

The whole thing could be rewritten with scope variables for connection and user that would allow them to be first class denizens of the database or fed into an event processing system without having to do entity extraction on the record. In addition, immediately insertable variables prevent the overhead of setting scope variables if not needed:

log << severity::warn() << "Packet was larger than the buffer that contains it!"
     << auditing::full() << << set("User", user) << set("connection",connection)
" Packet source= " << connection << ", account = " << user << "\n"
     << dump_hex(packet);

---
Jason Wagner
jason_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk