On May 26, 2006, at 7:13 AM, Jeffrey Graham wrote:
Hello,
I downloaded the CVS version 408722 just several days ago and have
the following 2 problems with the pattern layout under Linux..
1) %p always shows the current log level, not the level of the message
When you set the level of the logstream, you are setting the level of
the logging requests that are generated from the logstream, not the
threshold for the logger. So if I do:
log4cxx::logstream logWrapper::logs(Logger::getRootLogger(),
Level::getInfo());
logs << "Info Message" << LOG4CXX_ENDMSG;
logs.setLevel(Level::getDebug());
logs << "Debug Message" << LOG4CXX_ENDMSG;
You would generate an INFO level request and a DEBUG level request.
The threshold of the logger is a totally distinct thing.
2) %Q does not print the fractional seconds fo time, but the "%d
{ISO8601}" does.
You should use the java.text.SimpleDateFormat syntax (http://
java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html
which does support fractional seconds. For backward compatibility
with log4cxx 0.9.7 if a strftime-type format (that is with %'s) is
detected, then apr_strftime used to format the time. %Q is not
implemented in APR's apr_strftime (and is not documented typically in
systems that do implement it).
Help, especially on the %p issue is greatly appreciated.
I am using streams in C++.
My code looks like this (inside a class called logWrapper where
logger and logs are declared static):
Have a logstream as a class member is strongly discouraged. All
actions on a logger are atomic, so they can be members or static
members. However, logstreams keep an internal state and interleaved
calls could result in scrambled messages. For example, if you had:
class Foo {
private:
static log4cxx::logstream ls(Logger::getRootLogger(),
Level::getInfo());
public:
Foo() {}
void action1() {
ls << "Hello" << " World" << LOG4CXX_ENDMSG;
}
void action2() {
ls << "Kitty" << LOG4CXX_ENDMSG;
}
}
you could end up with any of the following combinations if action2
and action2 were called simultaneously;
Hello World
Kitty
Kitty
Hello World
KittyHello World
(blank)
HelloKitty
World
KittyHello
World
logstream's make no attempt to synchronize their action and couldn't
avoid the interleaving of actions if they tried. They are designed
to be instantiated upon entry to a routine and potentially used
repeatedly in the body of a routine. They are not designed to be
shared or long-lived.
In addition, use Level::getInfo() in preference to Level::INFO as
static member variables have initialization order issues and INFO and
the like may be removed if they prove to be unsafe in the current
implementation.
Using a logstream* seems to be strange since it would likely leak.