You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-user@logging.apache.org by Andrew Chalk <ac...@magnacartasoftware.com> on 2007/02/06 19:25:55 UTC
Upgrading to v0.9.8
I had to upgrade an app. that used log4cxx. We made a lot of use of lines
like:
LOG4CXX_INFO(eventLogger, _T("Binding to: " << sBindIP.c_str() << ". Port: "
<< usPort << ". Link: " << sLinkNo.c_str()));
I.e. we used inline ostringstream constructs.
In 0.9.8 none of this appears to work. We appear to have to make major
modifications to our code along the lines of:
ostringstream os;
os << _T("Binding to: " << sBindIP.c_str() << ". Port: " << usPort << ".
Link: " << sLinkNo.c_str());
LOG4CXX_INFO(eventLogger, os.str().c_str());
Am I missing a way to continue with inline ostringstream?
Many thanks.,
Re: Upgrading to v0.9.8
Posted by Andrew Chalk <ac...@magnacartasoftware.com>.
Thanks.
"Curt Arnold" <ca...@apache.org> wrote in message
news:9823CEE2-D8F9-4D3D-87F3-11944237E318@apache.org...
>
> On Feb 6, 2007, at 12:25 PM, Andrew Chalk wrote:
>
>> I had to upgrade an app. that used log4cxx. We made a lot of use of
>> lines
>> like:
>>
>> LOG4CXX_INFO(eventLogger, _T("Binding to: " << sBindIP.c_str() << ".
>> Port: "
>> << usPort << ". Link: " << sLinkNo.c_str()));
>>
>> I.e. we used inline ostringstream constructs.
>>
>> In 0.9.8 none of this appears to work. We appear to have to make major
>> modifications to our code along the lines of:
>>
>> ostringstream os;
>> os << _T("Binding to: " << sBindIP.c_str() << ". Port: " << usPort << ".
>> Link: " << sLinkNo.c_str());
>> LOG4CXX_INFO(eventLogger, os.str().c_str());
>>
>> Am I missing a way to continue with inline ostringstream?
>>
>> Many thanks.,
>>
>
> The log4cxx 0.9.7 macros looked like:
>
> #define LOG4CXX_INFO(logger, message) { \
> if (logger->isInfoEnabled()) {\
> ::log4cxx::StringBuffer oss; \
> oss << message; \
> logger->forcedLog(::log4cxx::Level::INFO, oss.str(), __FILE__,
> __LINE__); }}
>
> And would allow you to pass a TCHAR* (where TCHAR was either char or
> wchar_t depending on the compile flags) or any other statement fragment
> that could complete the oss << message statement.
>
> In log4cxx 0.10.0, we did not want the artificial limit of supporting
> only one character type per build since many apps could easily use both
> char and wchar_t within the same application. The macro looks like:
>
> #define LOG4CXX_INFO(logger, message) { \
> if (logger->isInfoEnabled()) {\
> logger->forcedLog(::log4cxx::Level::INFO, message,
> LOG4CXX_LOCATION); }}
>
> and the compiler picks the appropriate flavor of forcedLog (std::string
> or std::wstring) based on the type of the message expression. However
> that requires that message be an expression and not a statement fragment.
> I do not believe that it is possible to construct a macro that will both
> accept statement fragments that 0.9.7 accepted and also support multiple
> string types, but I'm willing to be proved wrong.
>
> You appear to be misusing the Win32 _T construct (http://
> msdn2.microsoft.com/en-us/library/c426s321(VS.80).aspx) which is intended
> to be used to decorate a string literal so that it matches the TCHAR
> type. For example, _T("Hello, World") would expand to "Hello, World"L if
> _UNICODE is set and "Hello, World" otherwise. The examples shown about
> would not compile if _UNICODE was set since they would just add a L to
> the end of the fragment and change .c_str() to .c_str()L.
>
> log4cxx no longer defines or uses _T. It does define LOG4CXX_STR() to
> create string literals that match the internal logchar type, however
> LOG4CXX_STR should not be used in logging statements since both char and
> wchar_t flavors are provided regardless of the logchar type.
>
> That is do
>
> LOG4CXX_INFO(logger, "Hello, World");
>
> or
>
> LOG4CXX_INFO(logger, "Hello, World"L);
>
> but do not do:
>
> LOG4CXX_INFO(logger, LOG4CXX_STR("Hello, World"));
>
> The last would compile and work properly, but it reflects a
> misunderstanding of logchar as the internal char type.
>
> It appears from your fragments that you have no interest in wchar_t
> strings (or other string types like CFString on Macs) and would be
> willing to trade the multiple string type support for getting the
> statement fragment support back. You could create your own header file
> that you include after logger.h that redefines LOG4CXX_INFO et al for
> your own objectives, so instead of rewriting all your logging calls, all
> you have to do is create the header file and include it where ever you
> used statement fragments.
>
Re: Upgrading to v0.9.8
Posted by Curt Arnold <ca...@apache.org>.
On Feb 6, 2007, at 12:25 PM, Andrew Chalk wrote:
> I had to upgrade an app. that used log4cxx. We made a lot of use of
> lines
> like:
>
> LOG4CXX_INFO(eventLogger, _T("Binding to: " << sBindIP.c_str() <<
> ". Port: "
> << usPort << ". Link: " << sLinkNo.c_str()));
>
> I.e. we used inline ostringstream constructs.
>
> In 0.9.8 none of this appears to work. We appear to have to make major
> modifications to our code along the lines of:
>
> ostringstream os;
> os << _T("Binding to: " << sBindIP.c_str() << ". Port: " << usPort
> << ".
> Link: " << sLinkNo.c_str());
> LOG4CXX_INFO(eventLogger, os.str().c_str());
>
> Am I missing a way to continue with inline ostringstream?
>
> Many thanks.,
>
The log4cxx 0.9.7 macros looked like:
#define LOG4CXX_INFO(logger, message) { \
if (logger->isInfoEnabled()) {\
::log4cxx::StringBuffer oss; \
oss << message; \
logger->forcedLog(::log4cxx::Level::INFO, oss.str(), __FILE__,
__LINE__); }}
And would allow you to pass a TCHAR* (where TCHAR was either char or
wchar_t depending on the compile flags) or any other statement
fragment that could complete the oss << message statement.
In log4cxx 0.10.0, we did not want the artificial limit of supporting
only one character type per build since many apps could easily use
both char and wchar_t within the same application. The macro looks
like:
#define LOG4CXX_INFO(logger, message) { \
if (logger->isInfoEnabled()) {\
logger->forcedLog(::log4cxx::Level::INFO, message,
LOG4CXX_LOCATION); }}
and the compiler picks the appropriate flavor of forcedLog
(std::string or std::wstring) based on the type of the message
expression. However that requires that message be an expression and
not a statement fragment. I do not believe that it is possible to
construct a macro that will both accept statement fragments that
0.9.7 accepted and also support multiple string types, but I'm
willing to be proved wrong.
You appear to be misusing the Win32 _T construct (http://
msdn2.microsoft.com/en-us/library/c426s321(VS.80).aspx) which is
intended to be used to decorate a string literal so that it matches
the TCHAR type. For example, _T("Hello, World") would expand to
"Hello, World"L if _UNICODE is set and "Hello, World" otherwise. The
examples shown about would not compile if _UNICODE was set since they
would just add a L to the end of the fragment and change .c_str()
to .c_str()L.
log4cxx no longer defines or uses _T. It does define LOG4CXX_STR()
to create string literals that match the internal logchar type,
however LOG4CXX_STR should not be used in logging statements since
both char and wchar_t flavors are provided regardless of the logchar
type.
That is do
LOG4CXX_INFO(logger, "Hello, World");
or
LOG4CXX_INFO(logger, "Hello, World"L);
but do not do:
LOG4CXX_INFO(logger, LOG4CXX_STR("Hello, World"));
The last would compile and work properly, but it reflects a
misunderstanding of logchar as the internal char type.
It appears from your fragments that you have no interest in wchar_t
strings (or other string types like CFString on Macs) and would be
willing to trade the multiple string type support for getting the
statement fragment support back. You could create your own header
file that you include after logger.h that redefines LOG4CXX_INFO et
al for your own objectives, so instead of rewriting all your logging
calls, all you have to do is create the header file and include it
where ever you used statement fragments.
RE: Upgrading to v0.9.8
Posted by Stephen Bartnikowski <sb...@barkinglizards.com>.
Hi Andrew,
That's pretty much what I had to do. Fortunately, I had already been using
macros to do all of my logging, so I just changed my project's logging
macros to adapt.
In your case, however, you're going to have to either cut and paste a lot of
code, or re-factor a lot of code.
( Log4cxx dev team, please correct me if I'm wrong. )
Stephen Bartnikowski
Barking Lizards Technology
www.barkinglizards.com
-----Original Message-----
From: news [mailto:news@sea.gmane.org] On Behalf Of Andrew Chalk
Sent: Tuesday, February 06, 2007 12:26 PM
To: log4cxx-user@logging.apache.org
Subject: Upgrading to v0.9.8
I had to upgrade an app. that used log4cxx. We made a lot of use of lines
like:
LOG4CXX_INFO(eventLogger, _T("Binding to: " << sBindIP.c_str() << ". Port: "
<< usPort << ". Link: " << sLinkNo.c_str()));
I.e. we used inline ostringstream constructs.
In 0.9.8 none of this appears to work. We appear to have to make major
modifications to our code along the lines of:
ostringstream os;
os << _T("Binding to: " << sBindIP.c_str() << ". Port: " << usPort << ".
Link: " << sLinkNo.c_str());
LOG4CXX_INFO(eventLogger, os.str().c_str());
Am I missing a way to continue with inline ostringstream?
Many thanks.,