Phoenix V3 and Logging library help.

Hi Thomas, all, I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me. I'm thinking of writing a simple logging library, and to avoid the use of macros, I decided to do something like this: namespace prototype1 { namespace levels { boost::phoenix::expression::argument<1>::type const trace = {{{}}}; boost::phoenix::expression::argument<1>::type const debug = {{{}}}; boost::phoenix::expression::argument<1>::type const info = {{{}}}; boost::phoenix::expression::argument<1>::type const warn = {{{}}}; boost::phoenix::expression::argument<1>::type const error = {{{}}}; boost::phoenix::expression::argument<1>::type const fatal = {{{}}}; } //namespace levels struct dynamic_logger { template <typename Pred> void log( Pred const & pred ) const { streams_type::const_iterator it = streams_.begin(); streams_type::const_iterator end = streams_.end(); for ( ; it != end; ++it ) { pred( **it ); } } void add_target ( std::ostream & ostr ) { streams_.push_back( &ostr ); } typedef std::vector< std::ostream* > streams_type; //to improve streams_type streams_; }; template <typename Logger, typename Pred> void log( Logger & logger, Pred const & pred ) { return logger.log(pred); } } //namespace prototype1 int main(/*int argc, char* argv[]*/) { { using namespace prototype1; using namespace prototype1::levels; std::ofstream outfile ("test.log"); dynamic_logger dl; dl.add_target( std::cout ); dl.add_target( outfile ); dl.log ( info << "hello" << " world!" << std::endl ); dl.log ( warn << "hello" << " world!" << std::endl ); dl.log ( error << "hello" << " world!" << std::endl ); log( dl, info "hello" << " world!" << std::endl ); //free function } return 0; } This code is a simple prototype, This code is a prototype should be improved. The questions are: 1. Does PhoenixV3 (and Proto) supports GCC 3? 2. How to make the above code write the following ... ? INFO - hello world! WARN - hello world! ERROR - hello world! INFO - hello world! Is it possible? The key is to identify the different Levels. (see namespace prototype1::levels) Please, suggestions and criticisms are welcome. Note: I do not intend to compete with Boost.Log. Thanks and regards, Fernando Pelliccioni.

On 07/04/2011 07:04 PM, Fernando Pelliccioni wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me.
A few notes, if I may: 1. You probably wouldn't want the streaming expressions to be executed when the record is dropped anyway (e.g. when its severity level is not high enough). So there should be some "if (dl.is_enabled(info))" before each logging expression. Such check is usually hidden behind macros. 2. Thread safety and contention might be an issue. If there's going to be a global logger, accessible from different parts of program, it will have to synchronize concurrent access from different threads and, if possible, not to block for too long. Also, did you take a look at Google glog? http://code.google.com/p/google-glog/ I don't know about support for GCC 3.4, but it looks simple enough.

Thanks Andrey, On Mon, Jul 4, 2011 at 3:22 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
On 07/04/2011 07:04 PM, Fernando Pelliccioni wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me.
A few notes, if I may:
1. You probably wouldn't want the streaming expressions to be executed when the record is dropped anyway (e.g. when its severity level is not high enough). So there should be some "if (dl.is_enabled(info))" before each logging expression. Such check is usually hidden behind macros.
2. Thread safety and contention might be an issue. If there's going to be a global logger, accessible from different parts of program, it will have to synchronize concurrent access from different threads and, if possible, not to block for too long.
The example I wrote is very simple, just to show the concept. I will consider your recommendations.
Also, did you take a look at Google glog?
http://code.google.com/p/**google-glog/<http://code.google.com/p/google-glog/>
I don't know about support for GCC 3.4, but it looks simple enough.
I've seen, but it seems very alpha. Thank you! Fernando.

Hi Fernando, On Mon, Jul 4, 2011 at 5:04 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me.
Yes, Phoenix seems to work with 3.4.6. For a complete overview see: http://www.boost.org/development/tests/trunk/developer/phoenix.html If you run into any problems, let me know.
I'm thinking of writing a simple logging library, and to avoid the use of macros, I decided to do something like this:
Will comment inline.
namespace prototype1 { namespace levels {
This won't work. If you want to get the stuff working you sketched further down, All these placeholders would need to be of a different type. I would suggest to define different expression nodes for every level, please have a look at the docs: http://beta.boost.org/doc/libs/1_47_0_beta1/libs/phoenix/doc/html/phoenix/ex...
boost::phoenix::expression::argument<1>::type const trace = {{{}}}; boost::phoenix::expression::argument<1>::type const debug = {{{}}}; boost::phoenix::expression::argument<1>::type const info = {{{}}}; boost::phoenix::expression::argument<1>::type const warn = {{{}}}; boost::phoenix::expression::argument<1>::type const error = {{{}}}; boost::phoenix::expression::argument<1>::type const fatal = {{{}}}; } //namespace levels
struct dynamic_logger { template <typename Pred> void log( Pred const & pred ) const { streams_type::const_iterator it = streams_.begin(); streams_type::const_iterator end = streams_.end();
for ( ; it != end; ++it ) { pred( **it ); } }
void add_target ( std::ostream & ostr ) { streams_.push_back( &ostr ); }
typedef std::vector< std::ostream* > streams_type; //to improve streams_type streams_; };
template <typename Logger, typename Pred> void log( Logger & logger, Pred const & pred ) { return logger.log(pred); }
} //namespace prototype1
int main(/*int argc, char* argv[]*/) { { using namespace prototype1; using namespace prototype1::levels;
std::ofstream outfile ("test.log");
dynamic_logger dl; dl.add_target( std::cout ); dl.add_target( outfile );
dl.log ( info << "hello" << " world!" << std::endl ); dl.log ( warn << "hello" << " world!" << std::endl ); dl.log ( error << "hello" << " world!" << std::endl );
log( dl, info "hello" << " world!" << std::endl ); //free function }
return 0; }
This code is a simple prototype,
This code is a prototype should be improved. The questions are:
1. Does PhoenixV3 (and Proto) supports GCC 3?
See above
2. How to make the above code write the following ... ?
INFO - hello world! WARN - hello world! ERROR - hello world! INFO - hello world!
Is it possible?
Yes, please work through the docs, the link i posted you above should get you started.
The key is to identify the different Levels. (see namespace prototype1::levels)
Please, suggestions and criticisms are welcome.
HTH, Thomas

Thanks Thomas !! On Mon, Jul 4, 2011 at 3:23 PM, Thomas Heller <thom.heller@googlemail.com>wrote:
Hi Fernando,
On Mon, Jul 4, 2011 at 5:04 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me.
Yes, Phoenix seems to work with 3.4.6. For a complete overview see: http://www.boost.org/development/tests/trunk/developer/phoenix.html
If you run into any problems, let me know.
Sure, thanks!
I'm thinking of writing a simple logging library, and to avoid the use of macros, I decided to do something like this:
Will comment inline.
namespace prototype1 { namespace levels {
This won't work. If you want to get the stuff working you sketched further down, All these placeholders would need to be of a different type. I would suggest to define different expression nodes for every level, please have a look at the docs:
http://beta.boost.org/doc/libs/1_47_0_beta1/libs/phoenix/doc/html/phoenix/ex...
boost::phoenix::expression::argument<1>::type const trace = {{{}}}; boost::phoenix::expression::argument<1>::type const debug = {{{}}}; boost::phoenix::expression::argument<1>::type const info = {{{}}}; boost::phoenix::expression::argument<1>::type const warn = {{{}}}; boost::phoenix::expression::argument<1>::type const error = {{{}}}; boost::phoenix::expression::argument<1>::type const fatal = {{{}}}; } //namespace levels
struct dynamic_logger { template <typename Pred> void log( Pred const & pred ) const { streams_type::const_iterator it = streams_.begin(); streams_type::const_iterator end = streams_.end();
for ( ; it != end; ++it ) { pred( **it ); } }
void add_target ( std::ostream & ostr ) { streams_.push_back( &ostr ); }
typedef std::vector< std::ostream* > streams_type; //to improve streams_type streams_; };
template <typename Logger, typename Pred> void log( Logger & logger, Pred const & pred ) { return logger.log(pred); }
} //namespace prototype1
int main(/*int argc, char* argv[]*/) { { using namespace prototype1; using namespace prototype1::levels;
std::ofstream outfile ("test.log");
dynamic_logger dl; dl.add_target( std::cout ); dl.add_target( outfile );
dl.log ( info << "hello" << " world!" << std::endl ); dl.log ( warn << "hello" << " world!" << std::endl ); dl.log ( error << "hello" << " world!" << std::endl );
log( dl, info "hello" << " world!" << std::endl ); //free function }
return 0; }
This code is a simple prototype,
This code is a prototype should be improved. The questions are:
1. Does PhoenixV3 (and Proto) supports GCC 3?
See above
2. How to make the above code write the following ... ?
INFO - hello world! WARN - hello world! ERROR - hello world! INFO - hello world!
Is it possible?
Yes, please work through the docs, the link i posted you above should get you started.
I have read quickly the link you sent me, I have some doubts. I will read all the documentation from Phoenix to see if I will clarify concepts. Thanks, Fernando.

On Mon, Jul 4, 2011 at 9:36 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote:
Thanks Thomas !!
On Mon, Jul 4, 2011 at 3:23 PM, Thomas Heller <thom.heller@googlemail.com>wrote:
Hi Fernando,
On Mon, Jul 4, 2011 at 5:04 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does not support GCC 3.4. I've seen other libraries, but none convinced me.
Yes, Phoenix seems to work with 3.4.6. For a complete overview see: http://www.boost.org/development/tests/trunk/developer/phoenix.html
If you run into any problems, let me know.
Sure, thanks!
I'm thinking of writing a simple logging library, and to avoid the use of macros, I decided to do something like this:
Will comment inline.
namespace prototype1 { namespace levels {
This won't work. If you want to get the stuff working you sketched further down, All these placeholders would need to be of a different type. I would suggest to define different expression nodes for every level, please have a look at the docs:
http://beta.boost.org/doc/libs/1_47_0_beta1/libs/phoenix/doc/html/phoenix/ex...
<snip>
Yes, please work through the docs, the link i posted you above should get you started.
I have read quickly the link you sent me, I have some doubts. I will read all the documentation from Phoenix to see if I will clarify concepts.
Please do. If you encounter any problems I will be glad to help. Also patches to the documentation are welcome at any time ;)

On Tue, Jul 5, 2011 at 5:40 AM, Thomas Heller <thom.heller@googlemail.com>wrote:
Thanks Thomas !!
On Mon, Jul 4, 2011 at 3:23 PM, Thomas Heller <
On Mon, Jul 4, 2011 at 9:36 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote: thom.heller@googlemail.com>wrote:
Hi Fernando,
On Mon, Jul 4, 2011 at 5:04 PM, Fernando Pelliccioni <fpelliccioni@gmail.com> wrote:
Hi Thomas, all,
I am researching about logging libraries. I had to discard Boost.Log ( from Andrey) because this library does
not
support GCC 3.4. I've seen other libraries, but none convinced me.
Yes, Phoenix seems to work with 3.4.6. For a complete overview see: http://www.boost.org/development/tests/trunk/developer/phoenix.html
If you run into any problems, let me know.
Sure, thanks!
I'm thinking of writing a simple logging library, and to avoid the use
of
macros, I decided to do something like this:
Will comment inline.
namespace prototype1 { namespace levels {
This won't work. If you want to get the stuff working you sketched further down, All these placeholders would need to be of a different type. I would suggest to define different expression nodes for every level, please have a look at the docs:
http://beta.boost.org/doc/libs/1_47_0_beta1/libs/phoenix/doc/html/phoenix/ex... <snip>
Yes, please work through the docs, the link i posted you above should get you started.
I have read quickly the link you sent me, I have some doubts. I will read all the documentation from Phoenix to see if I will clarify concepts.
Please do. If you encounter any problems I will be glad to help. Also patches to the documentation are welcome at any time ;)
Thank you Thomas.
I was thinking, and came to the conclusion that it is easier to play with Proto in this case... See... //------------------------------------------------------------------------------------------------------------------------------------------- #include <string> #include <iostream> #include <boost/proto/proto.hpp> namespace proto = boost::proto; struct trace_ {}; proto::terminal<trace_>::type trace = {}; template <typename Expr> void run_predicate_internal( Expr const & expr) { using proto::value; using proto::child_c; run_predicate_internal( child_c<0>(expr) ); std::cout << value( child_c<1>(expr) ); } void run_predicate_internal(proto::terminal<trace_>::type const &) { std::cout << "[TRACE] - "; } template <typename Expr> void run_predicate( Expr const & expr) { run_predicate_internal(expr); std::cout << std::endl; } int main() { //proto::display_expr( trace << "hello " << "world " << 99.85 ); run_predicate( trace << "hello " << "world " << 99.85 ); return 0; } //------------------------------------------------------------------------------------------------------------------------------------------- Do you think that I can get some benefit using PhoenixV3 instead of Proto?
participants (3)
-
Andrey Semashev
-
Fernando Pelliccioni
-
Thomas Heller