[log] Boost.Log formal review closing down

Boosters, just a a friendly reminder that the formal review of the Boost.Log library, written by Andrey Semashev, is nearly the end, with about 24 hours remaining. If you planned to submit a review but have not done so, it's just about the time! The documentation for the current version is available at: http://boost-log.sourceforge.net The downloads are at: http://sourceforge.net/projects/boost-log Here are the important points: 1. All comments are appreciated. Even if you don't have the time for in-depth study of everything, comments on parts of the library are welcome. In particular, if you are already using logging in your applications and have specialized requirements, you might want to directly check how the proposed library handles them. 2. The reviews and all comments should be submitted to the developers list, boost@lists.boost.org and the email should have "[log]" prefix in the subject to make sure it's not missed. The deadline for reviews is 23:59, March 17, PST = 2:59, March 18, EST = 7:59 March 18, GMT = 10:59, March 18 MSK 3. Please explicitly state in your review whether the library should be accepted. 4. The general review checklist is provided below: - What is your evaluation of the design? - What is your evaluation of the implementation? - What is your evaluation of the documentation? - What is your evaluation of the potential usefulness of the library? - Did you try to use the library? With what compiler? Did you have any problems? - How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? - Are you knowledgeable about the problem domain? Thanks, Volodya

Hi, I though the review will continue until Sunday. Here is a a part of my review. I will continue this evening.
- What is your evaluation of the design?
First say that in general I like the library general architecture. Going into details: * Trivial log Trivial log should be logged to std::cerr Trivial log should contain in the record message only the application part and the severity. If the user want line number, a timestamp, thread identifier the library need to let the user configure this trivial logger. * Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions. attr< logging::severity_level >("Severity") should return the attribute value when called. The following expression attr< logging::severity_level >("Severity") >= logging::info should return a filter. Can this make be possible and unanbigous? Note that I have removed the trivial namespace which didn't add any information in the preceding expressions. The same applies to formatters fmt::stream << fmt::attr< unsigned int >("LineID") << ": <" << fmt::attr< logging::trivial::severity_level >("Severity") << "> " << fmt::message() should be just written fmt::stream << attr< unsigned int >("LineID") << ": <" << attr< logging::severity_level >("Severity") << "> " << message() or even the library could provide some functions returning the predefined attrributes: fmt::stream << line_id() << ": <" << severity_level() << "> " << message() Specific formats could be written as fmt::stream << (format("%08x") % line_id())<< ": <" << severity_level()<< "> " << message() * Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? How many rotation files are maintained? Can this number be configured? Best, Vicente

On Wednesday 17 March 2010 11:26:46 vicente.botet wrote:
Hi,
I though the review will continue until Sunday.
Generally no -- as the review schedule say, and as I've mentioned in all announcement, it runs until 17th. If you ran out of time, you can send a review at a later date (CC me), but there will not be a time for much follow-up discussion. - Volodya

----- Original Message ----- From: "Vladimir Prus" <ghost@cs.msu.su> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 11:30 AM Subject: Re: [boost] [log] Boost.Log formal review closing down
On Wednesday 17 March 2010 11:26:46 vicente.botet wrote:
Hi,
I though the review will continue until Sunday.
Generally no -- as the review schedule say, and as I've mentioned in all announcement, it runs until 17th. If you ran out of time, you can send a review at a later date (CC me), but there will not be a time for much follow-up discussion.
My bad. I will try however to send a complete review today. Best, Vicente

----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:26 AM Subject: Re: [boost] [log] Boost.Log formal review closing down
Hi,
I though the review will continue until Sunday.
Here is a a part of my review. I will continue this evening.
- What is your evaluation of the design?
First say that in general I like the library general architecture. Going into details:
* Trivial log Trivial log should be logged to std::cerr Trivial log should contain in the record message only the application part and the severity. If the user want line number, a timestamp, thread identifier the library need to let the user configure this trivial logger.
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level >("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level >("Severity") >= logging::info
should return a filter. Can this make be possible and unanbigous?
Note that I have removed the trivial namespace which didn't add any information in the preceding expressions.
The same applies to formatters fmt::stream << fmt::attr< unsigned int >("LineID") << ": <" << fmt::attr< logging::trivial::severity_level >("Severity") << "> " << fmt::message()
should be just written
fmt::stream << attr< unsigned int >("LineID") << ": <" << attr< logging::severity_level >("Severity") << "> " << message()
or even the library could provide some functions returning the predefined attrributes:
fmt::stream << line_id() << ": <" << severity_level() << "> " << message()
Specific formats could be written as
fmt::stream << (format("%08x") % line_id())<< ": <" << severity_level()<< "> " << message()
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? How many rotation files are maintained? Can this number be configured?
* Custom formatting functons I find this code extremly complex void my_formatter(std::ostream& strm, logging::record const& rec) { namespace lambda = boost::lambda; unsigned int line_id; if (logging::extract< unsigned int >( "LineID", rec.attribute_values(), lambda::var(line_id) = lambda::_1)) { strm << line_id << ": "; } logging::trivial::severity_level severity; if (logging::extract< logging::trivial::severity_level >( "Severity", rec.attribute_values(), lambda::var(severity) = lambda::_1)) { strm << "<" << severity << "> "; } strm << rec.message(); } I would expect something simpler as void my_formatter(std::ostream& strm, logging::record const& rec) { strm << rec.line_id() << ": "; strm << "<" << rec.severity() << "> "; strm << rec.message(); } What am I missing? *Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes. Some attributes could be identified staticaly using a tag. tagged_attr< unsigned int, tag_severity > Others using a std::string key named_attr< unsigned int >("id") and others using an int index index_attr< unsigned int >(3) The mapping could be done at two levels: The first level maps &type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value. * Which is the interest of registering the attribute "ProcessID" * Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal) << ineficient_function(); More later, Best, Vicente

AMDG vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal) << ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called. In Christ, Steven Watanabe

Steven Watanabe-4 wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal) << ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
In Christ, Steven Watanabe
If you say that it should be right. :) Best, Vicente -- View this message in context: http://old.nabble.com/-log--Boost.Log-formal-review-closing-down-tp27928143p... Sent from the Boost - Dev mailing list archive at Nabble.com.

On 03/17/2010 05:52 PM, Steven Watanabe wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal) << ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
I confirm.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:28 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/17/2010 05:52 PM, Steven Watanabe wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal) << ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
I confirm.
Yes I see, but the log record will be build with all its attributes which will take more time than just checking for severity. Vicente

On 03/18/2010 12:33 AM, vicente.botet wrote:
On 03/17/2010 05:52 PM, Steven Watanabe wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal)<< ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
I confirm.
Yes I see, but the log record will be build with all its attributes which will take more time than just checking for severity.
No, it won't. Only the attributes involved in filtering will be used.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 10:39 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 12:33 AM, vicente.botet wrote:
On 03/17/2010 05:52 PM, Steven Watanabe wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal)<< ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
I confirm.
Yes I see, but the log record will be build with all its attributes which will take more time than just checking for severity.
No, it won't. Only the attributes involved in filtering will be used.
Well all the attributes involved on filtering + creation of the log record. Is this not enough saving for 99% of the logs? Vicente

On 03/18/2010 12:53 AM, vicente.botet wrote:
On 03/18/2010 12:33 AM, vicente.botet wrote:
On 03/17/2010 05:52 PM, Steven Watanabe wrote:
AMDG
vicente.botet wrote:
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function(). BOOST_LOG_SEV(slg, normal)<< ineficient_function();
I'm pretty sure that if no sink is going to accept the record, then inefficient_function will indeed not be called.
I confirm.
Yes I see, but the log record will be build with all its attributes which will take more time than just checking for severity.
No, it won't. Only the attributes involved in filtering will be used.
Well all the attributes involved on filtering + creation of the log record. Is this not enough saving for 99% of the logs?
I don't follow. Could you be more specific, please? An example would be helpful.

On 03/17/2010 03:42 PM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:26 AM Subject: Re: [boost] [log] Boost.Log formal review closing down
Hi,
I though the review will continue until Sunday.
Here is a a part of my review. I will continue this evening.
- What is your evaluation of the design?
First say that in general I like the library general architecture. Going into details:
* Trivial log Trivial log should be logged to std::cerr Trivial log should contain in the record message only the application part and the severity. If the user want line number, a timestamp, thread identifier the library need to let the user configure this trivial logger.
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
Note that I have removed the trivial namespace which didn't add any information in the preceding expressions.
The same applies to formatters fmt::stream << fmt::attr< unsigned int>("LineID") << ":<"<< fmt::attr< logging::trivial::severity_level>("Severity") << "> "<< fmt::message()
should be just written
fmt::stream << attr< unsigned int>("LineID") << ":<"<< attr< logging::severity_level>("Severity") << "> "<< message()
or even the library could provide some functions returning the predefined attrributes:
fmt::stream << line_id() << ":<"<< severity_level() << "> "<< message()
Specific formats could be written as
fmt::stream << (format("%08x") % line_id())<< ":<"<< severity_level()<< "> "<< message()
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? How many rotation files are maintained? Can this number be configured?
* Custom formatting functons I find this code extremly complex void my_formatter(std::ostream& strm, logging::record const& rec) { namespace lambda = boost::lambda;
unsigned int line_id; if (logging::extract< unsigned int>( "LineID", rec.attribute_values(), lambda::var(line_id) = lambda::_1)) { strm<< line_id<< ": "; }
logging::trivial::severity_level severity; if (logging::extract< logging::trivial::severity_level>( "Severity", rec.attribute_values(), lambda::var(severity) = lambda::_1)) { strm<< "<"<< severity<< "> "; }
strm<< rec.message(); }
void my_formatter(std::ostream& strm, logging::record const& rec) { logging::extract< unsigned int >("LineID", rec.attribute_values(), lambda::var(strm) << lambda::_1 << ": "); logging::extract< severity_level >( "Severity", rec.attribute_values(), lambda::var(strm) << "<" << lambda::_1 << "> "); strm << rec.message(); }
*Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes.
Some attributes could be identified staticaly using a tag.
tagged_attr< unsigned int, tag_severity>
Others using a std::string key
named_attr< unsigned int>("id")
and others using an int index
index_attr< unsigned int>(3)
The mapping could be done at two levels: The first level maps&type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value.
That would complicate the library, both in terms of usage and implementation. I'd rather not introduce several different interfaces for the same thing.
* Which is the interest of registering the attribute "ProcessID"
Some users expressed the need to start logging by appending to the log file leftover from the previous runs of the application. This attribute can help to detect the point of the application restart. The attribute may also be useful if log records are sent to a remote process, which may accumulate logs from a group of processes.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:26 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/17/2010 03:42 PM, vicente.botet wrote:
----- Original Message ----- From: "vicente.botet"<vicente.botet@wanadoo.fr> To:<boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:26 AM Subject: Re: [boost] [log] Boost.Log formal review closing down
Hi,
I though the review will continue until Sunday.
Here is a a part of my review. I will continue this evening.
- What is your evaluation of the design?
First say that in general I like the library general architecture. Going into details:
* Trivial log Trivial log should be logged to std::cerr Trivial log should contain in the record message only the application part and the severity. If the user want line number, a timestamp, thread identifier the library need to let the user configure this trivial logger.
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
Note that I have removed the trivial namespace which didn't add any information in the preceding expressions.
The same applies to formatters fmt::stream << fmt::attr< unsigned int>("LineID") << ":<"<< fmt::attr< logging::trivial::severity_level>("Severity") << "> "<< fmt::message()
should be just written
fmt::stream << attr< unsigned int>("LineID") << ":<"<< attr< logging::severity_level>("Severity") << "> "<< message()
or even the library could provide some functions returning the predefined attrributes:
fmt::stream << line_id() << ":<"<< severity_level() << "> "<< message()
Specific formats could be written as
fmt::stream << (format("%08x") % line_id())<< ":<"<< severity_level()<< "> "<< message()
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? How many rotation files are maintained? Can this number be configured?
* Custom formatting functons I find this code extremly complex void my_formatter(std::ostream& strm, logging::record const& rec) { namespace lambda = boost::lambda;
unsigned int line_id; if (logging::extract< unsigned int>( "LineID", rec.attribute_values(), lambda::var(line_id) = lambda::_1)) { strm<< line_id<< ": "; }
logging::trivial::severity_level severity; if (logging::extract< logging::trivial::severity_level>( "Severity", rec.attribute_values(), lambda::var(severity) = lambda::_1)) { strm<< "<"<< severity<< "> "; }
strm<< rec.message(); }
void my_formatter(std::ostream& strm, logging::record const& rec) { logging::extract< unsigned int >("LineID", rec.attribute_values(), lambda::var(strm) << lambda::_1 << ": ");
logging::extract< severity_level >( "Severity", rec.attribute_values(), lambda::var(strm) << "<" << lambda::_1 << "> ");
strm << rec.message(); }
Sorry I find this yet clearer void my_formatter(std::ostream& strm, logging::record const& rec) fmt::stream << attr< unsigned int >("LineID") << ": <" << attr< logging::severity_level >("Severity") << "> " << message() }
*Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes.
Some attributes could be identified staticaly using a tag.
tagged_attr< unsigned int, tag_severity>
Others using a std::string key
named_attr< unsigned int>("id")
and others using an int index
index_attr< unsigned int>(3)
The mapping could be done at two levels: The first level maps&type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value.
That would complicate the library, both in terms of usage and implementation. I'd rather not introduce several different interfaces for the same thing.
I don't know if this will complicate or not your library. One thing is clear, accessing attributes by using string is expensive, and the user expects the best performance. If your library doesn't respond to this request, your library will not be used at the end. My proposal was multiple to respond to the needs of other users. From my side it is enough to identify an attribute using a tag. What is wrong using tags?
* Which is the interest of registering the attribute "ProcessID"
Some users expressed the need to start logging by appending to the log file leftover from the previous runs of the application. This attribute can help to detect the point of the application restart.
Well, maybe it could be useful. I have never use it in my ammpications as each process log on different files localy, or use distributed log service. Could you add an example on the documentation? BTW, which is the value of ProcessId, a number?
The attribute may also be useful if log records are sent to a remote process, which may accumulate logs from a group of processes.
May be useful, but current there is no backend sending log recods remotely. Best, Vicente

On 03/18/2010 12:32 AM, vicente.botet wrote:
void my_formatter(std::ostream& strm, logging::record const& rec) { logging::extract< unsigned int>("LineID", rec.attribute_values(), lambda::var(strm)<< lambda::_1<< ": ");
logging::extract< severity_level>( "Severity", rec.attribute_values(), lambda::var(strm)<< "<"<< lambda::_1<< "> ");
strm<< rec.message(); }
Sorry I find this yet clearer
void my_formatter(std::ostream& strm, logging::record const& rec) fmt::stream << attr< unsigned int>("LineID") << ":<"<< attr< logging::severity_level>("Severity") << "> "<< message() }
Then the current lambda syntax is your friend.
*Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes.
Some attributes could be identified staticaly using a tag.
tagged_attr< unsigned int, tag_severity>
Others using a std::string key
named_attr< unsigned int>("id")
and others using an int index
index_attr< unsigned int>(3)
The mapping could be done at two levels: The first level maps&type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value.
That would complicate the library, both in terms of usage and implementation. I'd rather not introduce several different interfaces for the same thing.
I don't know if this will complicate or not your library. One thing is clear, accessing attributes by using string is expensive, and the user expects the best performance. If your library doesn't respond to this request, your library will not be used at the end.
You keep talking of performance and something being expensive. Do you have specific requirements, or have you tried the library in an actual project and faced the problem? Because the tests that were mentioned during the discussion show that the current approach is not slower than other libraries that don't have attributes at all.
My proposal was multiple to respond to the needs of other users. From my side it is enough to identify an attribute using a tag. What is wrong using tags?
I think, using tags as keys in the attribute set is less natural than strings or any other runtime object for that matter.
The attribute may also be useful if log records are sent to a remote process, which may accumulate logs from a group of processes.
May be useful, but current there is no backend sending log recods remotely.
Syslog does this. In a way, Event log does this, too. Anyway, it doesn't mean the attribute should not be in the library.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 10:48 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 12:32 AM, vicente.botet wrote:
void my_formatter(std::ostream& strm, logging::record const& rec) { logging::extract< unsigned int>("LineID", rec.attribute_values(), lambda::var(strm)<< lambda::_1<< ": ");
logging::extract< severity_level>( "Severity", rec.attribute_values(), lambda::var(strm)<< "<"<< lambda::_1<< "> ");
strm<< rec.message(); }
Sorry I find this yet clearer
void my_formatter(std::ostream& strm, logging::record const& rec) fmt::stream << attr< unsigned int>("LineID") << ":<"<< attr< logging::severity_level>("Severity") << "> "<< message() }
Then the current lambda syntax is your friend.
My bad. I did the bad copy/past fmt::stream << rec.line_id() << ": <" << rec.severity_level() << "> " << rec.message() Could you show me this with your lambdas?
*Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes.
Some attributes could be identified staticaly using a tag.
tagged_attr< unsigned int, tag_severity>
Others using a std::string key
named_attr< unsigned int>("id")
and others using an int index
index_attr< unsigned int>(3)
The mapping could be done at two levels: The first level maps&type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value.
That would complicate the library, both in terms of usage and implementation. I'd rather not introduce several different interfaces for the same thing.
I don't know if this will complicate or not your library. One thing is clear, accessing attributes by using string is expensive, and the user expects the best performance. If your library doesn't respond to this request, your library will not be used at the end.
You keep talking of performance and something being expensive. Do you have specific requirements, or have you tried the library in an actual project and faced the problem? Because the tests that were mentioned during the discussion show that the current approach is not slower than other libraries that don't have attributes at all.
I don't need to make a test to see that looking on a map of strings is much more expensive than access a staticaly binded field (which is possible with the tag interface). Am I missing something?
My proposal was multiple to respond to the needs of other users. From my side it is enough to identify an attribute using a tag. What is wrong using tags?
I think, using tags as keys in the attribute set is less natural than strings or any other runtime object for that matter.
Note that tags are static. So no runtime penality.
The attribute may also be useful if log records are sent to a remote process, which may accumulate logs from a group of processes.
May be useful, but current there is no backend sending log recods remotely.
Syslog does this. In a way, Event log does this, too. Anyway, it doesn't mean the attribute should not be in the library.
You are right. This is not a reason to don't include it, but neither a reason to include it. Could you answer my question, What is the value of "ProcessId"? Vicente

On 03/18/2010 01:07 AM, vicente.botet wrote:
My proposal was multiple to respond to the needs of other users. From my side it is enough to identify an attribute using a tag. What is wrong using tags?
I think, using tags as keys in the attribute set is less natural than strings or any other runtime object for that matter.
Note that tags are static. So no runtime penality.
If you're after a fully static logging library, the proposed library does not suit you. There was a discussion on that topic during the review.
Could you answer my question, What is the value of "ProcessId"?
It's an integral process identifier. The result of getpid on UNIX and GetCurrentProcessId on Windows.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 6:33 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 01:07 AM, vicente.botet wrote:
My proposal was multiple to respond to the needs of other users. >From my side it is enough to identify an attribute using a tag. What is wrong using tags?
I think, using tags as keys in the attribute set is less natural than strings or any other runtime object for that matter.
Note that tags are static. So no runtime penality.
If you're after a fully static logging library, the proposed library does not suit you. There was a discussion on that topic during the review.
I'm for a pragmatic log library that is able to make the difference between typical log attributes that are intrinsic to the library and that can be staticaly binded as know already, and extrinsic attributes (specific to the application) that need to be managed in a more dynamic way. Up to you to take advantage of this separation or not, but I'm sure your library will win in simplicity and efficiency, presenving the openess that it has now.
Could you answer my question, What is the value of "ProcessId"?
It's an integral process identifier. The result of getpid on UNIX and GetCurrentProcessId on Windows.
On the projects I work with multiple process logging on the same file, we use to add a readble label identifying the process which correspond by default to the program name. Just my 2cts. Best, Vicente

On 03/18/2010 09:47 PM, vicente.botet wrote:
On 03/18/2010 01:07 AM, vicente.botet wrote:
My proposal was multiple to respond to the needs of other users. From my side it is enough to identify an attribute using a tag. What is wrong using tags?
I think, using tags as keys in the attribute set is less natural than strings or any other runtime object for that matter.
Note that tags are static. So no runtime penality.
If you're after a fully static logging library, the proposed library does not suit you. There was a discussion on that topic during the review.
I'm for a pragmatic log library that is able to make the difference between typical log attributes that are intrinsic to the library and that can be staticaly binded as know already, and extrinsic attributes (specific to the application) that need to be managed in a more dynamic way.
Up to you to take advantage of this separation or not, but I'm sure your library will win in simplicity and efficiency, presenving the openess that it has now.
There are no attributes implied by the library, and I don't want to change that, as that would limit the scope of the library.
Could you answer my question, What is the value of "ProcessId"?
It's an integral process identifier. The result of getpid on UNIX and GetCurrentProcessId on Windows.
On the projects I work with multiple process logging on the same file, we use to add a readble label identifying the process which correspond by default to the program name.
You can use the "constant" attribute for that purpose.

Andrey Semashev wrote:
On 03/18/2010 12:32 AM, vicente.botet wrote:
Andrey Semashev wrote:
void my_formatter(std::ostream& strm, logging::record const& rec) { logging::extract< unsigned int>("LineID", rec.attribute_values(), lambda::var(strm)<< lambda::_1<< ": ");
logging::extract< severity_level>( "Severity", rec.attribute_values(), lambda::var(strm)<< "<"<< lambda::_1<< "> ");
strm<< rec.message(); }
Sorry I find this yet clearer
void my_formatter(std::ostream& strm, logging::record const& rec) fmt::stream << attr< unsigned int>("LineID") << ":<"<< attr< logging::severity_level>("Severity") << "> "<< message() }
Then the current lambda syntax is your friend.
Vicente's corrected version: void my_formatter(std::ostream & strm, logging::record const & rec) { fmt::stream << rec.line_id() << ": <" << rec.severity_level() << "> " << rec.message() } I doubt the lambda version can be clearer than that and it would certainly lead to more chances to make hard to diagnose syntax mistakes. Concerns from others about reinvention, in this case inventing your own lambda support, means that users cannot apply whatever knowledge they may have with using other lambda libraries to understanding errors in using yours. Vicente's suggested syntax is clear, simple, and permits meaningful, direct compile diagnostics. It is worth serious consideration. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On 03/18/2010 07:51 PM, Stewart, Robert wrote:
Vicente's corrected version:
void my_formatter(std::ostream& strm, logging::record const& rec) { fmt::stream<< rec.line_id()<< ":<"<< rec.severity_level() << "> "<< rec.message() }
I doubt the lambda version can be clearer than that and it would certainly lead to more chances to make hard to diagnose syntax mistakes. Concerns from others about reinvention, in this case inventing your own lambda support, means that users cannot apply whatever knowledge they may have with using other lambda libraries to understanding errors in using yours. Vicente's suggested syntax is clear, simple, and permits meaningful, direct compile diagnostics. It is worth serious consideration.
I agree that it is very clear, but I fail to see how it can be supported without hardcoding the line_id and severity_level attributes into the record. I think that something like that could be done, however: strm << line_id(rec) << ":<" << severity_level(rec) << "> " << rec.message();

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 6:17 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 07:51 PM, Stewart, Robert wrote:
Vicente's corrected version:
void my_formatter(std::ostream& strm, logging::record const& rec) { fmt::stream<< rec.line_id()<< ":<"<< rec.severity_level() << "> "<< rec.message() }
I doubt the lambda version can be clearer than that and it would certainly lead to more chances to make hard to diagnose syntax mistakes. Concerns from others about reinvention, in this case inventing your own lambda support, means that users cannot apply whatever knowledge they may have with using other lambda libraries to understanding errors in using yours. Vicente's suggested syntax is clear, simple, and permits meaningful, direct compile diagnostics. It is worth serious consideration.
I agree that it is very clear, but I fail to see how it can be supported without hardcoding the line_id and severity_level attributes into the record.
I don't see any trouble the predefined attributes to be hard coded in the log record as this can improve the efficiency of the library. Do you see a problem hard coding the attributes defined by the library?
I think that something like that could be done, however:
strm << line_id(rec) << ":<" << severity_level(rec) << "> " << rec.message();
This is fine for me. This allows to manage with intrinsec and extrinsec attributes in the same way. But why message will be different from all other attributes? Best, Vicente

On 03/18/2010 09:38 PM, vicente.botet wrote:
I doubt the lambda version can be clearer than that and it would certainly lead to more chances to make hard to diagnose syntax mistakes. Concerns from others about reinvention, in this case inventing your own lambda support, means that users cannot apply whatever knowledge they may have with using other lambda libraries to understanding errors in using yours. Vicente's suggested syntax is clear, simple, and permits meaningful, direct compile diagnostics. It is worth serious consideration.
I agree that it is very clear, but I fail to see how it can be supported without hardcoding the line_id and severity_level attributes into the record.
I don't see any trouble the predefined attributes to be hard coded in the log record as this can improve the efficiency of the library. Do you see a problem hard coding the attributes defined by the library?
No, I don't think hardcoding is an acceptable solution for a generic library.
I think that something like that could be done, however:
strm<< line_id(rec)<< ":<"<< severity_level(rec) << "> "<< rec.message();
But why message will be different from all other attributes?
Because it's not an attribute. But a free function could be provided for consistency.

Continuation ... ----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 1:42 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:26 AM Subject: Re: [boost] [log] Boost.Log formal review closing down
Hi,
I though the review will continue until Sunday.
Here is a a part of my review. I will continue this evening.
- What is your evaluation of the design?
First say that in general I like the library general architecture. Going into details:
* Trivial log Trivial log should be logged to std::cerr Trivial log should contain in the record message only the application part and the severity. If the user want line number, a timestamp, thread identifier the library need to let the user configure this trivial logger.
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level >("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level >("Severity") >= logging::info
should return a filter. Can this make be possible and unanbigous?
Note that I have removed the trivial namespace which didn't add any information in the preceding expressions.
The same applies to formatters fmt::stream << fmt::attr< unsigned int >("LineID") << ": <" << fmt::attr< logging::trivial::severity_level >("Severity") << "> " << fmt::message()
should be just written
fmt::stream << attr< unsigned int >("LineID") << ": <" << attr< logging::severity_level >("Severity") << "> " << message()
or even the library could provide some functions returning the predefined attrributes:
fmt::stream << line_id() << ": <" << severity_level() << "> " << message()
Specific formats could be written as
fmt::stream << (format("%08x") % line_id())<< ": <" << severity_level()<< "> " << message()
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? How many rotation files are maintained? Can this number be configured?
* Custom formatting functons I find this code extremly complex void my_formatter(std::ostream& strm, logging::record const& rec) { namespace lambda = boost::lambda;
unsigned int line_id; if (logging::extract< unsigned int >( "LineID", rec.attribute_values(), lambda::var(line_id) = lambda::_1)) { strm << line_id << ": "; }
logging::trivial::severity_level severity; if (logging::extract< logging::trivial::severity_level >( "Severity", rec.attribute_values(), lambda::var(severity) = lambda::_1)) { strm << "<" << severity << "> "; }
strm << rec.message(); }
I would expect something simpler as void my_formatter(std::ostream& strm, logging::record const& rec) { strm << rec.line_id() << ": "; strm << "<" << rec.severity() << "> "; strm << rec.message();
} What am I missing? *Attributes: I don't like that std::string is used as attribute key. I suspect that this is not the more efficient way to have dynamics attributes. I would prefer the library manage several kinds of attributes.
Some attributes could be identified staticaly using a tag.
tagged_attr< unsigned int, tag_severity >
Others using a std::string key
named_attr< unsigned int >("id")
and others using an int index
index_attr< unsigned int >(3)
The mapping could be done at two levels: The first level maps &type_info, to either the value_type extractor. - For tagged attributes the extractor is able to get the attribute value directly. - For named attributes and index attributes the extractor needs the additional name or index information to get attribute value.
* Which is the interest of registering the attribute "ProcessID"
* Severity: I would like that any sink filters thie severity the log_record is not added at all. Could this optimization be taken in account. For example if severity must be GT error to be logged, the following will not evaluate the ineficient_function().
BOOST_LOG_SEV(slg, normal) << ineficient_function();
More later,
* __FILE__, __LINE__ and BOOST_CURRENT_FUNCTION are missing. The library could make easier is use. * all the logger macros should be able to generate non executed code. In addition I would like that the filter on the severity be included in. For example #if defined (BOOST_LOG_INCLUDED) #define BOOST_LOG_SEV(LOGGER, SEVERITY) if (true); else logger #else #define BOOST_LOG_SEV(LOGGER, SEVERITY) \ if (boost::log::core::enabled(SEVERITY) //as before #endif The rational is that most of the time the application should not trace nothing, except critical errors. This test avoids the construction of the record_log, and evaluate the filter on all the attributes. In the same way the severity is a special attribute, we need special filter for this attribute. - What is your evaluation of the implementation? I 'm confident the author know well C++ and will be able to improbe the library if he take care of the suggestions of this review. I would like the assynchronous front end uses one lock_free queue by thread which will have less contention than the actual implementation using one queue for all the threads. - What is your evaluation of the documentation? The documentation is quite good. It can be however be improved by: * adding links when a class or funcion appears on the text to the references, * adding links to the complete examples or even bettern include them with systax highligled on the documentation * adding the output expected by the execution of concrete examples. - What is your evaluation of the potential usefulness of the library? Completly useful. Every body uses logs in a profesional context. - Did you try to use the library? With what compiler? Did you have any problems? Yes I have tried to use it on cygwin-gcc3.4, and mingw-gcc4.4 and msvc Express 9. * I get a lot of errors on cygwin as there are nor wide characters on cygwin. * when compiling the library using just bjam, there were alot of errors because the library don't work on single_threaded environements. * when I compiled with msvc on mingw, a 'mc' tool was missing * when I compiled with gcc4.4 on mingw the same issue with 'mc' Unfortunatelly these error have not been corrected. - How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? I have spent a lot of time trying to use the library without success. So my review is based on the documentation. - Are you knowledgeable about the problem domain? Yes, I use to use log in all my applications, and we have an asynchronous implementation using one queue by thread that outperforms the one using one queue for all the threads. In our applications the use of asynchronous logging is an imperative. 3. Please explicitly state in your review whether the library should be accepted. I think the architecture of the library is the correct one. I have signaled some points of improvement either on the design, the implementation or the documentation. I know the author and I don't expect he will take care of all my suggestions. Anyway I think that Boost needs a Log library, so even if Boost.Log should be improved in quite a lot details, it is not less useful other libraries already included on Boost. Thus, I vote for a provisional inclusion on Boost, as there are a lot of improvements that will need to be checked for coherency. Best, Vicente

On 03/18/2010 12:13 AM, vicente.botet wrote:
* __FILE__, __LINE__ and BOOST_CURRENT_FUNCTION are missing. The library could make easier is use.
Is this what you mean? http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/attributes.h...
* all the logger macros should be able to generate non executed code. In addition I would like that the filter on the severity be included in. For example
#if defined (BOOST_LOG_INCLUDED) #define BOOST_LOG_SEV(LOGGER, SEVERITY) if (true); else logger #else #define BOOST_LOG_SEV(LOGGER, SEVERITY) \ if (boost::log::core::enabled(SEVERITY) //as before #endif
The rational is that most of the time the application should not trace nothing, except critical errors. This test avoids the construction of the record_log, and evaluate the filter on all the attributes.
Answered on this earlier.
In the same way the severity is a special attribute, we need special filter for this attribute.
Severity is not special. Users of channel-based logging would argue the same way about channels and they would be right.
- Did you try to use the library? With what compiler? Did you have any problems?
Yes I have tried to use it on cygwin-gcc3.4, and mingw-gcc4.4 and msvc Express 9. * I get a lot of errors on cygwin as there are nor wide characters on cygwin. * when compiling the library using just bjam, there were alot of errors because the library don't work on single_threaded environements. * when I compiled with msvc on mingw, a 'mc' tool was missing * when I compiled with gcc4.4 on mingw the same issue with 'mc'
Unfortunatelly these error have not been corrected.
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 10:23 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 12:13 AM, vicente.botet wrote:
* __FILE__, __LINE__ and BOOST_CURRENT_FUNCTION are missing. The library could make easier is use.
Is this what you mean?
http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/attributes.h...
I had read this already. If I have understoo you need two lines to add __FILE__, __LINE__ and BOOST_CURRENT_FUNCTION BOOST_LOG_NAMED_SCOPE("case 1"); BOOST_LOG(lg) << "Some log record";
* all the logger macros should be able to generate non executed code. In addition I would like that the filter on the severity be included in. For example
#if defined (BOOST_LOG_INCLUDED) #define BOOST_LOG_SEV(LOGGER, SEVERITY) if (true); else logger #else #define BOOST_LOG_SEV(LOGGER, SEVERITY) \ if (boost::log::core::enabled(SEVERITY) //as before #endif
The rational is that most of the time the application should not trace nothing, except critical errors. This test avoids the construction of the record_log, and evaluate the filter on all the attributes.
Answered on this earlier.
Not completly. You have no commented about testing severity before creating the log record. Could you comment?
In the same way the severity is a special attribute, we need special filter for this attribute.
Severity is not special. Users of channel-based logging would argue the same way about channels and they would be right.
And maybe they are right. The macro that using channel should check first if the channel is enabled.
- Did you try to use the library? With what compiler? Did you have any problems?
Yes I have tried to use it on cygwin-gcc3.4, and mingw-gcc4.4 and msvc Express 9. * I get a lot of errors on cygwin as there are nor wide characters on cygwin. * when compiling the library using just bjam, there were alot of errors because the library don't work on single_threaded environements. * when I compiled with msvc on mingw, a 'mc' tool was missing * when I compiled with gcc4.4 on mingw the same issue with 'mc'
Unfortunatelly these error have not been corrected.
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly? Vicente

On 03/18/2010 12:45 AM, vicente.botet wrote:
* all the logger macros should be able to generate non executed code. In addition I would like that the filter on the severity be included in. For example
#if defined (BOOST_LOG_INCLUDED) #define BOOST_LOG_SEV(LOGGER, SEVERITY) if (true); else logger #else #define BOOST_LOG_SEV(LOGGER, SEVERITY) \ if (boost::log::core::enabled(SEVERITY) //as before #endif
The rational is that most of the time the application should not trace nothing, except critical errors. This test avoids the construction of the record_log, and evaluate the filter on all the attributes.
Answered on this earlier.
Not completly. You have no commented about testing severity before creating the log record. Could you comment?
I thought I did. But let me say it again: if the filter rejects the log record, no attributes are evaluated, except for those involved in filtering. More specifically, only severity attribute is evaluated. An empty record is constructed (which equivalent to assigning NULL to a pointer).
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 10:54 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 12:45 AM, vicente.botet wrote:
* all the logger macros should be able to generate non executed code. In addition I would like that the filter on the severity be included in. For example
#if defined (BOOST_LOG_INCLUDED) #define BOOST_LOG_SEV(LOGGER, SEVERITY) if (true); else logger #else #define BOOST_LOG_SEV(LOGGER, SEVERITY) \ if (boost::log::core::enabled(SEVERITY) //as before #endif
The rational is that most of the time the application should not trace nothing, except critical errors. This test avoids the construction of the record_log, and evaluate the filter on all the attributes.
Answered on this earlier.
Not completly. You have no commented about testing severity before creating the log record. Could you comment?
I thought I did. But let me say it again: if the filter rejects the log record, no attributes are evaluated, except for those involved in filtering. More specifically, only severity attribute is evaluated. An empty record is constructed (which equivalent to assigning NULL to a pointer).
I will take a look at the code then. :(
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly? Vicente

On 03/18/2010 01:10 AM, vicente.botet wrote:
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 6:35 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 01:10 AM, vicente.botet wrote:
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected to be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread. Thanks, Vicente

On Thu, Mar 18, 2010 at 1:51 PM, vicente.botet <vicente.botet@wanadoo.fr>wrote:
----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 6:35 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 01:10 AM, vicente.botet wrote:
mc is not present in MinGW, GCC or MSVC Express. You would have to install Windows SDK or full MSVC to get it. The mc tool is expected
to
be present in MSVC 10 Express. I have added the note to the docs in trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread.
Unless I'm mistaken, you can already use it without dependency on external tools if you're not using the event log backend. If you are using the event log backend, the the mc compiler isn't a requirement of boost.log, it's a requirement of windows itself so I don't see any obvious ways around it. Zach

On 03/18/2010 10:12 PM, Zachary Turner wrote:
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread.
You already can disable wide character support.
Unless I'm mistaken, you can already use it without dependency on external tools if you're not using the event log backend. If you are using the event log backend, the the mc compiler isn't a requirement of boost.log, it's a requirement of windows itself so I don't see any obvious ways around it.
Well, order to build without mc, the event log sink would have to be removed from the Jamfile.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 8:24 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 10:12 PM, Zachary Turner wrote:
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread.
You already can disable wide character support.
Can you tell me how? Do I need to download a new version? I have placed the log file on the directory for /boost_1_41_0 I do $ bjam --with-log threading=multi define=BOOST_LOG_USE_CHAR > mt.2.log lib.jam: No such file or directory The Jamfile on build contains import lib that seems to fail. Next, here it is the log: gcc.compile.c++ ../../../bin.v2/libs/log/test/util_string_literal.test/gcc-3.4.4/debug/threading-multi/run/util_string_literal.o run\util_string_literal.cpp: In member function `void string_literal_ctors::test_method()': run\util_string_literal.cpp:48: error: `wstring_literal' is not a member of `logging' I have needed to add all the lines following //BUG WCHAR *********************************************** //BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T // Copying { logging::wstring_literal lit1 = L"Hello"; logging::wstring_literal lit2 = lit1; BOOST_CHECK(wcscmp(lit2.c_str(), L"Hello") == 0); BOOST_CHECK(wcscmp(lit1.c_str(), lit2.c_str()) == 0); } //BUG WCHAR #endif // Generator functions { logging::string_literal lit1 = logging::str_literal("Wow!"); BOOST_CHECK(strcmp(lit1.c_str(), "Wow!") == 0); //BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T logging::wstring_literal lit2 = logging::str_literal(L"Wow!"); BOOST_CHECK(wcscmp(lit2.c_str(), L"Wow!") == 0); //BUG WCHAR #endif *********************************************** More errors gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/code_conversion.o In file included from C:\cygwin\boost_1_41_0\libs\log\src\code_conversion.cpp:20: ../../../boost/log/detail/code_conversion.hpp:107: error: variable or field `code_convert' declared void I have needed to add all the lines following //BUG WCHAR *********************************************** // BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T //! The function converts one string to the character type of another inline void code_convert(std::wstring const& str1, std::string& str2) { converting_ostringstreambuf< wchar_t > buf(str2); buf.sputn(str1.data(), static_cast< std::streamsize >(str1.size())); buf.pubsync(); } //! The function converts one string to the character type of another inline void code_convert(std::wstring const& str1, std::wstring& str2) { str2 = str1; } //! The function converts one string to the character type of another inline void code_convert(std::string const& str1, std::wstring& str2) { converting_ostringstreambuf< char > buf(str2); buf.sputn(str1.data(), static_cast< std::streamsize >(str1.size())); buf.pubsync(); } // BUG WCHAR #endif //! The function converts the passed string to the narrow-character encoding inline std::string const& to_narrow(std::string const& str) { return str; } // BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T //! The function converts the passed string to the narrow-character encoding inline std::string to_narrow(std::wstring const& str) { std::string res; aux::code_convert(str, res); return res; } //! The function converts the passed string to the wide-character encoding inline std::wstring const& to_wide(std::wstring const& str) { return str; } //! The function converts the passed string to the wide-character encoding inline std::wstring to_wide(std::string const& str) { std::wstring res; aux::code_convert(str, res); return res; } // BUG WCHAR #endif *********************************************** More gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/text_file_backend.o C:\cygwin\boost_1_41_0\libs\log\src\text_file_backend.cpp:150: error: ISO C++ forbids declaration of `wstring' with no type C:\cygwin\boost_1_41_0\libs\log\src\text_file_backend.cpp:150: error: invalid use of `::' *********************************************** //BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T template< > struct file_char_traits< wchar_t > { typedef wchar_t char_type; static const char_type percent = L'%'; static const char_type number_placeholder = L'N'; static const char_type day_placeholder = L'd'; static const char_type month_placeholder = L'm'; static const char_type year_placeholder = L'y'; static const char_type full_year_placeholder = L'Y'; static const char_type frac_sec_placeholder = L'f'; static const char_type seconds_placeholder = L'S'; static const char_type minutes_placeholder = L'M'; static const char_type hours_placeholder = L'H'; static const char_type space = L' '; static const char_type plus = L'+'; static const char_type minus = L'-'; static const char_type zero = L'0'; static const char_type dot = L'.'; static const char_type newline = L'\n'; static bool is_digit(wchar_t c) { return (iswdigit(c) != 0); } static std::wstring default_file_name_pattern() { return L"%5N.log"; } }; #ifndef BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::percent; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::number_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::day_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::month_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::year_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::full_year_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::frac_sec_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::seconds_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::minutes_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::hours_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::space; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::plus; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::minus; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::zero; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::dot; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::newline; #endif // BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE //BUG WCHAR #endif *********************************************** I have added in file prologue.hpp //BUG WCHAR #ifdef BOOST_NO_STD_WSTRING //BUG WCHAR # undef BOOST_LOG_USE_WCHAR_T //BUG WCHAR #endif So the user don't needs to state that he wants only use CHAR when WCHAR is not available. ========================= After modifying these files: gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/syslog_backend.o In file included from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: ../../../boost/asio/detail/socket_types.hpp:37:5: warning: #warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. ../../../boost/asio/detail/socket_types.hpp:38:5: warning: #warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. ../../../boost/asio/detail/socket_types.hpp:39:5: warning: #warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). ../../../boost/asio/detail/socket_types.hpp:73:5: #error You must add -D__USE_W32_SOCKETS to your compiler options. In file included from ../../../boost/asio/detail/socket_types.hpp:79, from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api/winsock2.h:103:2: warning: #warning "fd_set and associated macros have been defined in sys/types. This may cause runtime problems with W32 sockets" In file included from ../../../boost/asio/detail/socket_types.hpp:79, from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api/winsock2.h:635: error: declaration of C function `int gethostname(char*, int)' conflicts with /usr/include/sys/unistd.h:206: error: previous declaration `int gethostname(char*, size_t)' here In file included from ../../../boost/asio/detail/fd_set_adapter.hpp:25, from ../../../boost/asio/detail/select_reactor.hpp:32, from ../../../boost/asio/impl/io_service.ipp:27, from ../../../boost/asio/io_service.hpp:641, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:26: ../../../boost/asio/detail/win_fd_set_adapter.hpp: In member function `bool boost::asio::detail::win_fd_set_adapter::is_set(boost::asio::detail::socket_type) const': ../../../boost/asio/detail/win_fd_set_adapter.hpp:56: error: `__WSAFDIsSet' undeclared (first use this function) ../../../boost/asio/detail/win_fd_set_adapter.hpp:56: error: (Each undeclared identifier is reported only once for each function it appears in.) I have comment #syslog_backend.cpp ================= Next gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/trivial.o ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >': ../../../boost/log/formatters/wrappers.hpp:148: instantiated from `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:141: error: base `boost::log_mt_posix::formatters::wrap_if_c<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, true>' with only non-default constructor in class without a constructor ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:148: error: base `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >' with only non-default constructor in class without a constructor C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp: In function `void boost::log_mt_posix::trivial::aux::init()': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: error: no match for 'operator<<' in 'boost::log_mt_posix::formatters::stream_placeholder<CharT>::operator<<(const T&) const [with T = boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>, CharT = char](((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>&)((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>*)(&boost::log_mt_posix::formatters::attr(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) [with AttributeValueTypesT = unsigned int]())))) << " ["' Here I have stopped for cygcin-gcc-3.4, as I don't thisk this is related toWCHAR. As you can say your library was not able to work only with CHAR on cygcin-gcc-3.4. Let me know if you want we continue to remove the other compile errors.
Unless I'm mistaken, you can already use it without dependency on external tools if you're not using the event log backend. If you are using the event log backend, the the mc compiler isn't a requirement of boost.log, it's a requirement of windows itself so I don't see any obvious ways around it.
Well, order to build without mc, the event log sink would have to be removed from the Jamfile.
Can you tell me how? I didn't see which define is needed to do that. Do I need to download a new version? Best, Vicente

----- Original Message ----- From: "vicente.botet" <vicente.botet@wanadoo.fr> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 11:14 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 8:24 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 10:12 PM, Zachary Turner wrote:
> It is the Message Compiler. It is required for the Event Log backend on > Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread.
You already can disable wide character support.
Can you tell me how? Do I need to download a new version?
I have placed the log file on the directory for /boost_1_41_0
I do
$ bjam --with-log threading=multi define=BOOST_LOG_USE_CHAR > mt.2.log lib.jam: No such file or directory
The Jamfile on build contains import lib that seems to fail.
Next, here it is the log: gcc.compile.c++ ../../../bin.v2/libs/log/test/util_string_literal.test/gcc-3.4.4/debug/threading-multi/run/util_string_literal.o run\util_string_literal.cpp: In member function `void string_literal_ctors::test_method()': run\util_string_literal.cpp:48: error: `wstring_literal' is not a member of `logging'
I have needed to add all the lines following //BUG WCHAR
*********************************************** //BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T // Copying { logging::wstring_literal lit1 = L"Hello"; logging::wstring_literal lit2 = lit1; BOOST_CHECK(wcscmp(lit2.c_str(), L"Hello") == 0); BOOST_CHECK(wcscmp(lit1.c_str(), lit2.c_str()) == 0); } //BUG WCHAR #endif // Generator functions { logging::string_literal lit1 = logging::str_literal("Wow!"); BOOST_CHECK(strcmp(lit1.c_str(), "Wow!") == 0);
//BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T logging::wstring_literal lit2 = logging::str_literal(L"Wow!"); BOOST_CHECK(wcscmp(lit2.c_str(), L"Wow!") == 0); //BUG WCHAR #endif ***********************************************
More errors gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/code_conversion.o In file included from C:\cygwin\boost_1_41_0\libs\log\src\code_conversion.cpp:20: ../../../boost/log/detail/code_conversion.hpp:107: error: variable or field `code_convert' declared void
I have needed to add all the lines following //BUG WCHAR
*********************************************** // BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T //! The function converts one string to the character type of another inline void code_convert(std::wstring const& str1, std::string& str2) { converting_ostringstreambuf< wchar_t > buf(str2); buf.sputn(str1.data(), static_cast< std::streamsize >(str1.size())); buf.pubsync(); } //! The function converts one string to the character type of another inline void code_convert(std::wstring const& str1, std::wstring& str2) { str2 = str1; } //! The function converts one string to the character type of another inline void code_convert(std::string const& str1, std::wstring& str2) { converting_ostringstreambuf< char > buf(str2); buf.sputn(str1.data(), static_cast< std::streamsize >(str1.size())); buf.pubsync(); } // BUG WCHAR #endif
//! The function converts the passed string to the narrow-character encoding inline std::string const& to_narrow(std::string const& str) { return str; }
// BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T //! The function converts the passed string to the narrow-character encoding inline std::string to_narrow(std::wstring const& str) { std::string res; aux::code_convert(str, res); return res; }
//! The function converts the passed string to the wide-character encoding inline std::wstring const& to_wide(std::wstring const& str) { return str; }
//! The function converts the passed string to the wide-character encoding inline std::wstring to_wide(std::string const& str) { std::wstring res; aux::code_convert(str, res); return res; } // BUG WCHAR #endif *********************************************** More gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/text_file_backend.o C:\cygwin\boost_1_41_0\libs\log\src\text_file_backend.cpp:150: error: ISO C++ forbids declaration of `wstring' with no type C:\cygwin\boost_1_41_0\libs\log\src\text_file_backend.cpp:150: error: invalid use of `::'
*********************************************** //BUG WCHAR #ifdef BOOST_LOG_USE_WCHAR_T template< > struct file_char_traits< wchar_t > { typedef wchar_t char_type;
static const char_type percent = L'%'; static const char_type number_placeholder = L'N'; static const char_type day_placeholder = L'd'; static const char_type month_placeholder = L'm'; static const char_type year_placeholder = L'y'; static const char_type full_year_placeholder = L'Y'; static const char_type frac_sec_placeholder = L'f'; static const char_type seconds_placeholder = L'S'; static const char_type minutes_placeholder = L'M'; static const char_type hours_placeholder = L'H'; static const char_type space = L' '; static const char_type plus = L'+'; static const char_type minus = L'-'; static const char_type zero = L'0'; static const char_type dot = L'.'; static const char_type newline = L'\n';
static bool is_digit(wchar_t c) { return (iswdigit(c) != 0); } static std::wstring default_file_name_pattern() { return L"%5N.log"; } }; #ifndef BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::percent; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::number_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::day_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::month_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::year_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::full_year_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::frac_sec_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::seconds_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::minutes_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::hours_placeholder; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::space; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::plus; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::minus; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::zero; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::dot; const file_char_traits< wchar_t >::char_type file_char_traits< wchar_t >::newline; #endif // BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE //BUG WCHAR #endif ***********************************************
I have added in file prologue.hpp
//BUG WCHAR #ifdef BOOST_NO_STD_WSTRING //BUG WCHAR # undef BOOST_LOG_USE_WCHAR_T //BUG WCHAR #endif
So the user don't needs to state that he wants only use CHAR when WCHAR is not available.
=========================
After modifying these files:
gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/syslog_backend.o In file included from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: ../../../boost/asio/detail/socket_types.hpp:37:5: warning: #warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. ../../../boost/asio/detail/socket_types.hpp:38:5: warning: #warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. ../../../boost/asio/detail/socket_types.hpp:39:5: warning: #warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). ../../../boost/asio/detail/socket_types.hpp:73:5: #error You must add -D__USE_W32_SOCKETS to your compiler options. In file included from ../../../boost/asio/detail/socket_types.hpp:79, from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api/winsock2.h:103:2: warning: #warning "fd_set and associated macros have been defined in sys/types. This may cause runtime problems with W32 sockets" In file included from ../../../boost/asio/detail/socket_types.hpp:79, from ../../../boost/asio/detail/io_control.hpp:25, from ../../../boost/asio/socket_base.hpp:25, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:25: /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api/winsock2.h:635: error: declaration of C function `int gethostname(char*, int)' conflicts with /usr/include/sys/unistd.h:206: error: previous declaration `int gethostname(char*, size_t)' here In file included from ../../../boost/asio/detail/fd_set_adapter.hpp:25, from ../../../boost/asio/detail/select_reactor.hpp:32, from ../../../boost/asio/impl/io_service.ipp:27, from ../../../boost/asio/io_service.hpp:641, from C:\cygwin\boost_1_41_0\libs\log\src\syslog_backend.cpp:26: ../../../boost/asio/detail/win_fd_set_adapter.hpp: In member function `bool boost::asio::detail::win_fd_set_adapter::is_set(boost::asio::detail::socket_type) const': ../../../boost/asio/detail/win_fd_set_adapter.hpp:56: error: `__WSAFDIsSet' undeclared (first use this function) ../../../boost/asio/detail/win_fd_set_adapter.hpp:56: error: (Each undeclared identifier is reported only once for each function it appears in.)
I have comment #syslog_backend.cpp
================= Next
gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/trivial.o ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >': ../../../boost/log/formatters/wrappers.hpp:148: instantiated from `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:141: error: base `boost::log_mt_posix::formatters::wrap_if_c<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, true>' with only non-default constructor in class without a constructor ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:148: error: base `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >' with only non-default constructor in class without a constructor C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp: In function `void boost::log_mt_posix::trivial::aux::init()': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: error: no match for 'operator<<' in 'boost::log_mt_posix::formatters::stream_placeholder<CharT>::operator<<(const T&) const [with T = boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>, CharT = char](((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>&)((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>*)(&boost::log_mt_posix::formatters::attr(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) [with AttributeValueTypesT = unsigned int]())))) << " ["'
Here I have stopped for cygcin-gcc-3.4, as I don't thisk this is related toWCHAR.
As you can say your library was not able to work only with CHAR on cygcin-gcc-3.4.
Let me know if you want we continue to remove the other compile errors.
Unless I'm mistaken, you can already use it without dependency on external tools if you're not using the event log backend. If you are using the event log backend, the the mc compiler isn't a requirement of boost.log, it's a requirement of windows itself so I don't see any obvious ways around it.
Well, order to build without mc, the event log sink would have to be removed from the Jamfile.
Can you tell me how? I didn't see which define is needed to do that. Do I need to download a new version?
Andrey, I would like to be able to compile Boost.Log. Please could you see what you can do? Thanks, Vicente

AMDG vicente.botet wrote:
Well, order to build without mc, the event log sink would have to be removed from the Jamfile.
Can you tell me how? I didn't see which define is needed to do that. Do I need to download a new version?
I would like to be able to compile Boost.Log. Please could you see what you can do?
Just edit libs/log/build/Jamfile.v2 In Christ, Steven Watanabe

----- Original Message ----- From: "Steven Watanabe" <watanabesj@gmail.com> To: <boost@lists.boost.org> Sent: Sunday, March 21, 2010 7:23 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
AMDG
vicente.botet wrote:
Well, order to build without mc, the event log sink would have to be removed from the Jamfile.
Can you tell me how? I didn't see which define is needed to do that. Do I need to download a new version?
I would like to be able to compile Boost.Log. Please could you see what you can do?
Just edit libs/log/build/Jamfile.v2
In Christ, Steven Watanabe
Thanks Steven to note me the answer was already given. I have commented from the Jamfile what I consider can be optional (related to mc). For the moment I haven't a complete build. I expect from Andrey to continue to solve the pending issues. Thanks, Vicente

On 03/21/2010 07:54 PM, vicente.botet wrote:
================= Next
gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/trivial.o ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >': ../../../boost/log/formatters/wrappers.hpp:148: instantiated from `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:141: error: base `boost::log_mt_posix::formatters::wrap_if_c<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, true>' with only non-default constructor in class without a constructor ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:148: error: base `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >' with only non-default constructor in class without a constructor C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp: In function `void boost::log_mt_posix::trivial::aux::init()': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: error: no match for 'operator<<' in 'boost::log_mt_posix::formatters::stream_placeholder<CharT>::operator<<(const T&) const [with T = boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>, CharT = char](((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>&)((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>*)(&boost::log_mt_posix::formatters::attr(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) [with AttributeValueTypesT = unsigned int]()))))<< " ["'
Here I have stopped for cygcin-gcc-3.4, as I don't thisk this is related toWCHAR.
As you can say your library was not able to work only with CHAR on cygcin-gcc-3.4.
Let me know if you want we continue to remove the other compile errors.
I did not try to support GCC 3.4 (and very likely, I won't), so I'd recommend upgrading to 4.4, which is available for Cygwin. Also, it looks like you're using RC4 version. I've fixed a few bugs in trunk after it was released, so you might want to try with a fresh checkout. These fixes do not include your changes though.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Sunday, March 21, 2010 7:38 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/21/2010 07:54 PM, vicente.botet wrote:
================= Next
gcc.compile.c++ ../../../bin.v2/libs/log/build/gcc-3.4.4/debug/threading-multi/trivial.o ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >': ../../../boost/log/formatters/wrappers.hpp:148: instantiated from `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:141: error: base `boost::log_mt_posix::formatters::wrap_if_c<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, true>' with only non-default constructor in class without a constructor ../../../boost/log/formatters/wrappers.hpp: In instantiation of `boost::log_mt_posix::formatters::wrap_if_not_formatter<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: instantiated from here ../../../boost/log/formatters/wrappers.hpp:148: error: base `boost::log_mt_posix::formatters::wrap_if<char, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::mpl::not_<boost::log_mt_posix::formatters::is_formatter<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >' with only non-default constructor in class without a constructor C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp: In function `void boost::log_mt_posix::trivial::aux::init()': C:\cygwin\boost_1_41_0\libs\log\src\trivial.cpp:134: error: no match for 'operator<<' in 'boost::log_mt_posix::formatters::stream_placeholder<CharT>::operator<<(const T&) const [with T = boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>, CharT = char](((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>&)((const boost::log_mt_posix::formatters::fmt_attr<char, unsigned int, boost::log_mt_posix::formatters::throw_policy>*)(&boost::log_mt_posix::formatters::attr(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) [with AttributeValueTypesT = unsigned int]()))))<< " ["'
Here I have stopped for cygcin-gcc-3.4, as I don't thisk this is related toWCHAR.
As you can say your library was not able to work only with CHAR on cygcin-gcc-3.4.
Let me know if you want we continue to remove the other compile errors.
I did not try to support GCC 3.4 (and very likely, I won't), so I'd recommend upgrading to 4.4, which is available for Cygwin.
I have already tried to install 4.4 without success. It is a shame that you don't want to support the official cygwin compiler version. I was completly confident that you will try it.
Also, it looks like you're using RC4 version. I've fixed a few bugs in trunk after it was released, so you might want to try with a fresh checkout. These fixes do not include your changes though.
I expect that you will include the modifications I sent in the previous mail. I'm using the revised version, yes. Do you plan to move to the Boost sandbox? Best, Vicente

On 21.03.2010 23:20, vicente.botet wrote:
I have already tried to install 4.4 without success. It is a shame that you don't want to support the official cygwin compiler version. I was completly confident that you will try it.
GCC 4.x is as official as 3.x. But it's 4.3, not 4.4 as I initially suggested (I'm not an active user of cygwin). I've incorporated a few changes to the trunk to fix a few errors with 4.3, but it doesn't compile yet. If the syslog and event log are disabled, the only errors left are in Boost.Parameter and Boost.Range (being used from Boost.DateTime).
Also, it looks like you're using RC4 version. I've fixed a few bugs in trunk after it was released, so you might want to try with a fresh checkout. These fixes do not include your changes though.
I expect that you will include the modifications I sent in the previous mail. I'm using the revised version, yes.
Some of the suggested changes will be included, but not the ones about commenting something in the Jamfile. I will provide more configuration options to make it possible to disable certain sinks from the build.
Do you plan to move to the Boost sandbox?
No. There is no reason to.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Monday, March 22, 2010 8:43 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 21.03.2010 23:20, vicente.botet wrote:
I have already tried to install 4.4 without success. It is a shame that you don't want to support the official cygwin compiler version. I was completly confident that you will try it.
GCC 4.x is as official as 3.x. But it's 4.3, not 4.4 as I initially suggested (I'm not an active user of cygwin).
Thanks. I forgoten that I have already installed this version. I will try it.
I've incorporated a few changes to the trunk to fix a few errors with 4.3, but it doesn't compile yet. If the syslog and event log are disabled, the only errors left are in Boost.Parameter and Boost.Range (being used from Boost.DateTime).
have you open a ticket for those errors in Boost.DateTime?
Also, it looks like you're using RC4 version. I've fixed a few bugs in trunk after it was released, so you might want to try with a fresh checkout. These fixes do not include your changes though.
I expect that you will include the modifications I sent in the previous mail. I'm using the revised version, yes.
Some of the suggested changes will be included, but not the ones about commenting something in the Jamfile. I will provide more configuration options to make it possible to disable certain sinks from the build.
Great? I'm waiting for that.
Do you plan to move to the Boost sandbox?
No. There is no reason to.
It was just a question :) I don't find the Boost.Log repository on the ML. Please could you recall me its address? Thanks, Vicente

AMDG vicente.botet wrote:
Do you plan to move to the Boost sandbox?
No. There is no reason to.
It was just a question :) I don't find the Boost.Log repository on the ML. Please could you recall me its address?
http://boost-log.svn.sourceforge.net/svnroot/boost-log/trunk In Christ, Steven Watanabe

On 22.03.2010 23:56, vicente.botet wrote:
I've incorporated a few changes to the trunk to fix a few errors with 4.3, but it doesn't compile yet. If the syslog and event log are disabled, the only errors left are in Boost.Parameter and Boost.Range (being used from Boost.DateTime).
have you open a ticket for those errors in Boost.DateTime?
I've added yet another workaround to Boost.Log. Try if it compiles for you now.

----- Original Message ----- From: "Zachary Turner" <divisortheory@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 8:12 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On Thu, Mar 18, 2010 at 1:51 PM, vicente.botet <vicente.botet@wanadoo.fr>wrote:
----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Thursday, March 18, 2010 6:35 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 01:10 AM, vicente.botet wrote:
> mc is not present in MinGW, GCC or MSVC Express. You would have to > install Windows SDK or full MSVC to get it. The mc tool is expected
to
> be present in MSVC 10 Express. I have added the note to the docs in > trunk about that.
What this tool does, and can the library work without? Could this be used conditionaly?
It is the Message Compiler. It is required for the Event Log backend on Windows.
Could this be used conditionaly?
Not right now, I'm afraid. But I have plans of improving configurability of the library.
Great. Let me know when the library will be able to run on platforms not supporting wide chars, without dependencies to external tools (mc) and in single thread.
Unless I'm mistaken, you can already use it without dependency on external tools if you're not using the event log backend. If you are using the event log backend, the the mc compiler isn't a requirement of boost.log, it's a requirement of windows itself so I don't see any obvious ways around it.
Hi, As I said the library doesn't compiles if the platform doesn't support wide char characters (I use to work on my own computer with cygwin). Maybe you are right, but before using the library I wanted to run the test of the library. Once the own test of the library run on my platform I will start to try to use the library for my own needs. I can also remove the test that doesn't work on the platform I use, but I have no had the time to do this kind of work :( Best, Vicente Best, Vicente

Andrey Semashev wrote;
On 03/18/2010 12:13 AM, vicente.botet wrote:
In the same way the severity is a special attribute, we need special filter for this attribute.
Severity is not special. Users of channel-based logging would argue the same way about channels and they would be right.
They differ from all other attributes in determining whether to log a message in the *very* common severity/component scheme. You are within your rights to say otherwise for Boost.Log, but you will need to defend performance and complexity differences between Boost.Log and systems supporting severity/component in order to sway users to Boost.Log. I expect this will be a FAQ for Boost.Log. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On 03/17/2010 11:26 AM, vicente.botet wrote:
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
See our conversation with Steven on this topic. In short, it needs researching on my side. On the spot I can see the problem with attr returning the attribute value upon being called, if more than one type is specified.
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day?
As I said in another email, this is currently not possible, but will be implemented.
How many rotation files are maintained?
You can specify maximum total size of the files or minimum free space on the drive.
Can this number be configured?
See here: http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backend...

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 9:09 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/17/2010 11:26 AM, vicente.botet wrote:
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
See our conversation with Steven on this topic. In short, it needs researching on my side. On the spot I can see the problem with attr returning the attribute value upon being called, if more than one type is specified.
Does this mean that you will take care of the separation between attributes/filters and formatters?
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day?
As I said in another email, this is currently not possible, but will be implemented.
Great. This is a must to have feature.
How many rotation files are maintained?
You can specify maximum total size of the files or minimum free space on the drive.
Can this number be configured?
See here:
http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backend...
I dont see how to configure the number of rotation files? Could you show me how? Best, Vicente

On 03/18/2010 12:21 AM, vicente.botet wrote:
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
See our conversation with Steven on this topic. In short, it needs researching on my side. On the spot I can see the problem with attr returning the attribute value upon being called, if more than one type is specified.
Does this mean that you will take care of the separation between attributes/filters and formatters?
This means, I will try to, but I can't promise that I'll succeed.
How many rotation files are maintained?
You can specify maximum total size of the files or minimum free space on the drive.
Can this number be configured?
See here:
http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backend...
I dont see how to configure the number of rotation files? Could you show me how?
As I said, you can't give the actual number of files, but you can limit their size. If you construct the backend like this: boost::shared_ptr< sinks::text_file_backend > backend( new sinks::text_file_backend( keywords::file_name = "file_%5N.log", keywords::rotation_size = 5 * 1024 * 1024 )); backend->set_file_collector( sinks::file::make_collector( keywords::target = "./logs", keywords::max_size = 100 * 1024 * 1024, )); You won't have more than 20 files in the ./logs directory.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Wednesday, March 17, 2010 10:31 PM Subject: Re: [boost] [log] Boost.Log formal review closing down
On 03/18/2010 12:21 AM, vicente.botet wrote:
* Filters, Formatters and attributes: An attribute is a different think than a filter. Filters contains attributes as part of its expressions.
attr< logging::severity_level>("Severity") should return the attribute value when called.
The following expression
attr< logging::severity_level>("Severity")>= logging::info
should return a filter. Can this make be possible and unanbigous?
See our conversation with Steven on this topic. In short, it needs researching on my side. On the spot I can see the problem with attr returning the attribute value upon being called, if more than one type is specified.
Does this mean that you will take care of the separation between attributes/filters and formatters?
This means, I will try to, but I can't promise that I'll succeed.
Let me know if I can do something.
How many rotation files are maintained?
You can specify maximum total size of the files or minimum free space on the drive.
Can this number be configured?
See here:
http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/sink_backend...
I dont see how to configure the number of rotation files? Could you show me how?
As I said, you can't give the actual number of files, but you can limit their size.
Sorry I mis your comment. I understood the rotation can not be made possible based on time, not that the number can not be configured. "
* Rotation on files. Can rotation be based only on time? Can we rotate at 2:00AM every day? As I said in another email, this is currently not possible, but will be implemented. "
Vicente

I'm late to the game, but I wanted to add my thoughts to the mix. - Should the library be accepted? Yes, with conditions. There are numerous things, most raised already in the discussions and reviews, that give me pause. They aren't sufficient for me to reject the library, even as I have doubts as to whether I can use it to replace our in-house logging. Sadly, real life, including illness, has prevented me from attempting to integrate the proposed library into any of our applications for performance comparisons or to verify features. I'm also concerned about the number of suggestions Andrey has entertained during the review. The interface and mechanisms for assembling pieces will, it seems, change dramatically in some cases, so its hard to say I'll like the result. I propose a mini-review to verify that the result is still acceptable. - What is your evaluation of the design? The design, as is, was well conceived, with useful, orthogonal concepts. Unfortunately, it seems that many good ideas were left in the shadows until the review, so Andrey couldn't start the review having considered and assimilated them. - What is your evaluation of the implementation? I didn't look. - What is your evaluation of the documentation? There is a great deal of room to improve the text as English is clearly not Andrey's first language. I will try to help in that regard once Andrey has incorporated his intended changes. Otherwise, it does a nice job of walking the newcomer through the features of the library and of providing details when desired. Others have commented on missing details, examples, and links between the parts, so there's no need for me to rehash those points. - What is your evaluation of the potential usefulness of the library? Logging is an important part of any serious application or library. This library seems to be reasonably competitive in features and performance with well known, extant libraries. Therefore, it provides useful capabilities that have long been missing from Boost. It provides all of the features of our internal logging library, if less accessible in some ways, making it at least as capable. - Did you try to use the library? Unfortunately, no. - How much effort did you put into your evaluation? I spent a lot of time just following the review discussions. My hat is off to Andrey for keeping up with it all. I spent some hours reading the documentation. - Are you knowledgeable about the problem domain? Yes. I maintain and have significantly refactored the logging mechanisms used in my company's libraries and applications. I have used various logging mechanisms in years past. I congratulate Andrey on crafting a very nice library. I hope he can make sense of the varied concerns and ideas raised during the review. He has been staunch in defending his view of the scope of the library, so that will serve him well, even as he considers extending that scope somewhat. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
participants (7)
-
Andrey Semashev
-
Steven Watanabe
-
Stewart, Robert
-
Vicente Botet Escriba
-
vicente.botet
-
Vladimir Prus
-
Zachary Turner