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 Salvati Marc <sa...@hi.pi.titech.ac.jp> on 2006/09/14 11:02:14 UTC

Thread safety problem

Hello,
I m using QThread and Log4cxx in a project. I created a simple class 
with static member to access logging anywhere in my soft.
But when I m accessing from another thread I have some kind of random crash.
I tested without multithread and it work fine.
It s written in Log4cxx Faq that it s Thread safe. Am I wrong to use 
class static members or is there a bug in the thread safe 
functionnality? Is it problem to use QT Qthread with log4cxx?

Thank you for any kind help.
Best regards.

here the class declaration, initialization, and log sample.

//my class
class Log{
public :   
    static log4cxx::logstream stream;
    static log4cxx::LoggerPtr logger;
};

//initialization
log4cxx::LoggerPtr Log::logger(log4cxx::Logger::getLogger("Logger"));
log4cxx::logstream Log::stream(Log::logger, log4cxx::Level::DEBUG);

//logging sample
Log::stream<<"message"<<LOG4CXX_ENDMSG;


Re: Thread safety problem

Posted by salvati marc <sa...@hi.pi.titech.ac.jp>.
Hello,
thank you for your answer.
I was wondering why there where no problem with std::cout, while there 
was with log4cxx::stream...
if internal is synchronised, it shouldnt crash and have the same 
behavior as std::cout, no?

> For example:
>
> Log::stream<<"message"<<LOG4CXX_ENDMSG;
>
> is equivalent to:
>
> Log::stream.operator<<("message");
> Log::stream::operator<<(LocationFlush(__FILE__, __LINE__, ...));
>
> Even if all operator<<'s had internal synchronization, you could  
> still have other calls to the same logstream occurring between the  
> insertion of "message" and the insertion of the LocationFlush object  
> which triggers the call to Logger::debug().


of course it can maybe not preserve my intent....i could not get the 
message i was thinking to... but it shouldnt crash, no?

regards


	

	
		
___________________________________________________________________________ 
Découvrez un nouveau moyen de poser toutes vos questions quelque soit le sujet ! 
Yahoo! Questions/Réponses pour partager vos connaissances, vos opinions et vos expériences. 
http://fr.answers.yahoo.com 


Re: Thread safety problem

Posted by Curt Arnold <ca...@apache.org>.
On Sep 19, 2006, at 3:27 AM, Salvati Marc wrote:

> Hellom
> Thank you for answering. I tried to use log4cxx::Level::getDebug().
> It does not change my problem.
> Aas my Stream and Logger are static,
> static log4cxx::logstream stream;
> static log4cxx::LoggerPtr logger;
> I was wondering if I had to "lock" each time I wanted to send a  
> logging  message. It looks maybe like a beginners question, but I  
> have no problem and no need to lock with std::cout.
>
> regards.
>
>


Sorry, I did not notice that an instance of logstream was static in  
your example.   log4cxx::Logger is designed to be thread-safe and can  
be since every operation is atomic.  However, since several method  
calls on a logstream may participate in the generation of one  
message, there is no effective means that logstream could be  
internally synchronized and preserve the callers intent.  The  
anticipated use of logstream is that it would be declared within a  
method body and a single instance would be exclusive to a single thread.

For example:

Log::stream<<"message"<<LOG4CXX_ENDMSG;

is equivalent to:

Log::stream.operator<<("message");
Log::stream::operator<<(LocationFlush(__FILE__, __LINE__, ...));

Even if all operator<<'s had internal synchronization, you could  
still have other calls to the same logstream occurring between the  
insertion of "message" and the insertion of the LocationFlush object  
which triggers the call to Logger::debug().

The intended use of logstream would be like:

class Foo {
private:
     static log4cxx::LoggerPtr logger;
public:
     Foo();
     void run();
}


log4cxx::LoggerPtr Foo::logger(log4cxx::Logger::getLogger("Foo"));


Foo::Foo() {
    log4cxx::logstream stream(logger, log4cxx::Level::getDebug());
    stream << "message" << LOG4CXX_ENDMSG;
}

void Foo::run() {
    log4cxx::logstream stream(logger, log4cxx::Level::getInfo());
    stream << "message" << LOG4CXX_ENDMSG;
}

Obviously that type of usage demands that construction of logstream  
be as cheap as possible.  Unfortunately, the STL stream base template  
constructors seem to be pretty expensive.  I like the semantics of  
the current logstream, but the performance isn't where it needs to be  
and it may not be possible to preserve full compatibility with STL  
stream semantics and get reasonable performance.  All that to say  
that log4cxx::logstream is still experimental and subject to change  
or removal.

Re: Thread safety problem

Posted by Salvati Marc <sa...@hi.pi.titech.ac.jp>.
Hellom
Thank you for answering. I tried to use log4cxx::Level::getDebug().
It does not change my problem.
Aas my Stream and Logger are static,
static log4cxx::logstream stream;
static log4cxx::LoggerPtr logger;
I was wondering if I had to "lock" each time I wanted to send a logging  
message. It looks maybe like a beginners question, but I have no problem 
and no need to lock with std::cout.

regards.


Curt Arnold wrote:

> Could you test using log4cxx::Level::getDebug() instead of  
> log4cxx::Level::DEBUG?  The static members DEBUG, INFO, etc are held  
> over from 0.9.7 and log4j however non-local static member variables  
> are problematic at best.  I believe that DEBUG et al are marked as  
> deprecated for that reason.  I've been tempted to remove them  
> entirely but that would probably warrant a vote to see how many  
> people would be affected.
>
>
> On Sep 14, 2006, at 4:02 AM, Salvati Marc wrote:
>
>> Hello,
>> I m using QThread and Log4cxx in a project. I created a simple  class 
>> with static member to access logging anywhere in my soft.
>> But when I m accessing from another thread I have some kind of  
>> random crash.
>> I tested without multithread and it work fine.
>> It s written in Log4cxx Faq that it s Thread safe. Am I wrong to  use 
>> class static members or is there a bug in the thread safe  
>> functionnality? Is it problem to use QT Qthread with log4cxx?
>>
>> Thank you for any kind help.
>> Best regards.
>>
>> here the class declaration, initialization, and log sample.
>>
>> //my class
>> class Log{
>> public :      static log4cxx::logstream stream;
>>    static log4cxx::LoggerPtr logger;
>> };
>>
>> //initialization
>> log4cxx::LoggerPtr Log::logger(log4cxx::Logger::getLogger("Logger"));
>> log4cxx::logstream Log::stream(Log::logger, log4cxx::Level::DEBUG);
>>
>> //logging sample
>> Log::stream<<"message"<<LOG4CXX_ENDMSG;
>
>
>
>
>



Re: Thread safety problem

Posted by Curt Arnold <ca...@apache.org>.
Could you test using log4cxx::Level::getDebug() instead of  
log4cxx::Level::DEBUG?  The static members DEBUG, INFO, etc are held  
over from 0.9.7 and log4j however non-local static member variables  
are problematic at best.  I believe that DEBUG et al are marked as  
deprecated for that reason.  I've been tempted to remove them  
entirely but that would probably warrant a vote to see how many  
people would be affected.


On Sep 14, 2006, at 4:02 AM, Salvati Marc wrote:

> Hello,
> I m using QThread and Log4cxx in a project. I created a simple  
> class with static member to access logging anywhere in my soft.
> But when I m accessing from another thread I have some kind of  
> random crash.
> I tested without multithread and it work fine.
> It s written in Log4cxx Faq that it s Thread safe. Am I wrong to  
> use class static members or is there a bug in the thread safe  
> functionnality? Is it problem to use QT Qthread with log4cxx?
>
> Thank you for any kind help.
> Best regards.
>
> here the class declaration, initialization, and log sample.
>
> //my class
> class Log{
> public :      static log4cxx::logstream stream;
>    static log4cxx::LoggerPtr logger;
> };
>
> //initialization
> log4cxx::LoggerPtr Log::logger(log4cxx::Logger::getLogger("Logger"));
> log4cxx::logstream Log::stream(Log::logger, log4cxx::Level::DEBUG);
>
> //logging sample
> Log::stream<<"message"<<LOG4CXX_ENDMSG;