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
A logging facility
Moderators: hgm, Rebel, chrisw
-
- Posts: 568
- Joined: Tue Dec 12, 2006 10:10 am
- Full name: Gary Linscott
Re: A logging facility
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++.
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++.
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: A logging facility
I've been doing this thing for years...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 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...
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: A logging facility
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.bob wrote: I even wrote a Print() function
-
- Posts: 1822
- Joined: Thu Mar 09, 2006 11:54 pm
- Location: The Netherlands
Re: A logging facility
From the added code:mcostalba wrote: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.bob wrote: I even wrote a Print() function
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
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
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: A logging facility
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 ?diep wrote: In C++ equivalents that's the same thing as Bob's Print command in C
-
- Posts: 741
- Joined: Tue May 22, 2007 11:13 am
Re: A logging facility
I think Boost.Iostreams offers similar functionality, but also takes care of all the buffering stuff for you. E.g. tee_devicemcostalba wrote: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.bob wrote: I even wrote a Print() function
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.
-
- Posts: 2684
- Joined: Sat Jun 14, 2008 9:17 pm
Re: A logging facility
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 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.
-
- Posts: 741
- Joined: Tue May 22, 2007 11:13 am
Re: A logging facility
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.Logmcostalba wrote: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 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.
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.
-
- Posts: 1822
- Joined: Thu Mar 09, 2006 11:54 pm
- Location: The Netherlands
Re: A logging facility
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.mcostalba wrote: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 ?diep wrote: In C++ equivalents that's the same thing as Bob's Print command in C
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.