A logging facility

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

A logging facility

Post by mcostalba »

QUESTION:

How it is possible to toggle at runtime the file logging of all the messages sent to the GUI preserving the usual functionality, in particular keeping sending to stdout, and without changing even a single line of existing code (no replacing of std::cout with my_cout_stuff or similar) and with zero overhead when logging is disabled ?

ANSWER:
https://github.com/mcostalba/Stockfish/ ... c80cf7bf2c
gladius
Posts: 568
Joined: Tue Dec 12, 2006 10:10 am
Full name: Gary Linscott

Re: A logging facility

Post by gladius »

Very cool!

I see you added in the iostream speed-up as well. I had not seen that in quite a few years of dealing with C++.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: A logging facility

Post by bob »

mcostalba wrote:QUESTION:

How it is possible to toggle at runtime the file logging of all the messages sent to the GUI preserving the usual functionality, in particular keeping sending to stdout, and without changing even a single line of existing code (no replacing of std::cout with my_cout_stuff or similar) and with zero overhead when logging is disabled ?

ANSWER:
https://github.com/mcostalba/Stockfish/ ... c80cf7bf2c
I've been doing this thing for years...

I even wrote a Print() function that sends data to stdout AND the logfile at the same time, and you can control what is sent to which and what gets tossed out as you wish...
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: A logging facility

Post by mcostalba »

bob wrote: I even wrote a Print() function
The point is doing it _without_ writing a custom Print() function or whatever else. And without changing any existing line and with zero overhead (your Print() function is something added above the standard functions). Please don't take it personally, but I think you have not understood the topic, but believe me it is a very interesting piece of code otherwise I would had not dedicated a specific post here.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: A logging facility

Post by diep »

mcostalba wrote:
bob wrote: I even wrote a Print() function
The point is doing it _without_ writing a custom Print() function or whatever else. And without changing any existing line and with zero overhead (your Print() function is something added above the standard functions). Please don't take it personally, but I think you have not understood the topic, but believe me it is a very interesting piece of code otherwise I would had not dedicated a specific post here.
From the added code:

Code: Select all

 
+/// Our fancy logging facility. The trick here is to replace cout.rdbuf() with

  	110 	

+/// this one that sends the output both to console and to a file, this allow us

  	111 	

+/// to toggle the logging of std::cout to a file while preserving output to

  	112 	

+/// stdout and without changing a single line of code! Idea and code from:

  	113 	

+/// http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81
In C++ equivalents that's the same thing as Bob's Print command in C is. No matter how you define things, *somewhere* you do the exact same thing, and as USUAL, in c++ you needed to add more lines of code than Bob has in his Print function in C.

Diep had this by the way since mid 90s as well, and of course as it's C it's not so easy to use function overloading (or whatever name you want to give it) but i also call a function. Not the overloaded cout.rdbuf function, and in the background of course there runs then 'if then else' code generated by the compiler to choose which function to use, but in C of course it's a tad smaller than Bob's Print function, yet similar.

Yet i'm not doing as if there is nowhere in the code a compiler generated 'if then else' at the end that's basically the same.

BECAUSE you have an object oriented programming language, you shouldn't do as if you invent something new, as you didn't.

Thanks,
Vincent
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: A logging facility

Post by mcostalba »

diep wrote: In C++ equivalents that's the same thing as Bob's Print command in C
In C++ equivalent I could have been written my_cout object of a class derived from std::ostream at any time, replace std::cout with mine my_cout and do anything: this is _trivial_ and it takes nothing to do. What I have presented is different: suppose your program links some third part libraries that use std::cout and you want to add logging also there but you _cannot_ change their code. How do you did in the 90s ?
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A logging facility

Post by Rein Halbersma »

mcostalba wrote:
bob wrote: I even wrote a Print() function
The point is doing it _without_ writing a custom Print() function or whatever else. And without changing any existing line and with zero overhead (your Print() function is something added above the standard functions). Please don't take it personally, but I think you have not understood the topic, but believe me it is a very interesting piece of code otherwise I would had not dedicated a specific post here.
I think Boost.Iostreams offers similar functionality, but also takes care of all the buffering stuff for you. E.g. tee_device
http://www.boost.org/doc/libs/1_47_0/li ... s/tee.html

What is really nice in your code is that your Logger class can toggle this behavior at runtime and *from the outside*, as you point out.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: A logging facility

Post by mcostalba »

Rein Halbersma wrote: What is really nice in your code is that your Logger class can toggle this behavior at runtime and *from the outside*, as you point out.
Thanks Rein, and if you have noted housekeeping is guaranteed even at destruction: here the trick is to declare the object static inside a function and upon destruction (exiting from main()) the object _always_ restores the original cout buffer, this is important in case there are other static objects that call std::cout in the d'tor and are freed after the logger.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A logging facility

Post by Rein Halbersma »

mcostalba wrote:
Rein Halbersma wrote: What is really nice in your code is that your Logger class can toggle this behavior at runtime and *from the outside*, as you point out.
Thanks Rein, and if you have noted housekeeping is guaranteed even at destruction: here the trick is to declare the object static inside a function and upon destruction (exiting from main()) the object _always_ restores the original cout buffer, this is important in case there are other static objects that call std::cout in the d'tor and are freed after the logger.
Yes, it's all nice and clean. However, if you would like to take logging to the next level, you might also want to look at e.g. google-glog and Boost.Log

http://google-glog.googlecode.com/svn/t ... /glog.html
http://boost-log.sourceforge.net/libs/l ... orial.html

This would require rewriting your code, but it would also structure the logging message based on severity and boolean conditions.
diep
Posts: 1822
Joined: Thu Mar 09, 2006 11:54 pm
Location: The Netherlands

Re: A logging facility

Post by diep »

mcostalba wrote:
diep wrote: In C++ equivalents that's the same thing as Bob's Print command in C
In C++ equivalent I could have been written my_cout object of a class derived from std::ostream at any time, replace std::cout with mine my_cout and do anything: this is _trivial_ and it takes nothing to do. What I have presented is different: suppose your program links some third part libraries that use std::cout and you want to add logging also there but you _cannot_ change their code. How do you did in the 90s ?
As we print data from our own chessprograms, which is a 1 person product usually, C is far easier to use of course than C++, and there is no weird linking against third party libraries at all of course, as it's all code you wrote yourself.

No weird difficult 'namespace' definitions. No need to know worlds most complicated programming language, and no need to write as much code, as we already have the Print() command that's there doing a simple 'if then else' on what gets displayed.

Of course as my GUI's are in C++, i do know C++, yet even then it keeps a difficult programming language.

Bob however doesn't.

Yet in the end the executable you run is not an object oriented program, it's imperative machine code.

So somewhere in the C++ proces, there is always a conversion to the imperative world, at which point suddenly things start to look very similar to how Bob solved it, just in C++ you needed more code, and think about more complicated things :)

So to write espionage type software, that sneaky catches from specific program the output, and then displaying that, i'm sure C++ is the only programming language that's a requirement to get hired by N*SA. See also the NASA styleguide on C++, which is pretty ugly by the way. The Russian standards there seem more sensible there than the The North American Spy Agency styleguide, which is words most stupid and silliest styleguide ever.

Yet in this forum we are busy with computerchess, which are 1 person products usually, until start 21th century somewhere the C++ dudes got moved in, at which point computerchess became a mess.

Of course i'm using C++ for GUI's and C for the different engines i wrote.

It's silly to even start an engine in C++, as you need to be hell of a C++ programmer to even 'make' it to the same speed in nps as a much worse programmer can do in C.