Solved

Log abstraction layer and log4cpp

Posted on 2010-09-01
11
1,241 Views
Last Modified: 2013-11-12
I want to use log4cpp library with an abstraction layer like below
 
logLog4Cpp includes Appender, Category, Layout classes.

log4cpp
I don’t want to loose this capabilities becouse of abstraction layer.
If I add parameters which are needed by Log4Cpp library like below:

virtual void getLogger(const String& AppenderType, const String& CategoryName, const String& LayoutName, Boolean Additivity);

I have to change LoggerFactory interface’s getLogger method too. Soi that my interface become useless for other logging libraries.
How can I manage to use Log4Cpp’s capabilites? Could you suggest a convenient way?  
0
Comment
Question by:vileda
  • 3
  • 3
  • 3
  • +1
11 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 33575251
I recently implemented an abstraction layer for log4cxx so it became part of our standard toolkit but did not include a code level dependency on a specifically logger.

I can't share code because it is copyrighted but I don't mind assisting you with some pointers if you think this might be a solution for you.
0
 

Author Comment

by:vileda
ID: 33575418
I've just looked log4xxx library. It looks similiar with log4cpp. If you could give me main ideas and the right path, it would help me alot. Thanks.
0
 
LVL 22

Assisted Solution

by:ambience
ambience earned 100 total points
ID: 33575669
How about this, use a DTO --
class LoggerTraits {
};
class LoggerFactory {
 void getLogger(const String& AppenderType, LoggerTraits* pTraits);
};
------------------------------

class Log4CPP_LoggerTraits : public LoggerTraits {
public:
String CategoryName;
String LayoutName;
Boolean Additivity;
}
class Log4CPP_LoggerFactory : public LoggerFactory {
void getLogger(const String& AppenderType, LoggerTraits* pTraits) {
Log4CPP_LoggerTraits* myTraits = (Log4CPP_LoggerTraits*) pTraits;
...
}
};
0
 
LVL 40

Accepted Solution

by:
evilrix earned 200 total points
ID: 33575821
>> I've just looked log4xxx library. It looks similiar with log4cpp
It is similar, but far more mature and better supported than log4cpp since it is part of the apache movement.

I implemented 3 specific set of macros, one for generic logging, one for function level logging and the other for class level logging. As you know, log4 allows you to define specific loggers at runtime, which can then be controlled by a runtime config script to enable or disable loggers and implement output formatting on them.

Below is an example of the kind of thing I did. There is a hell of a lot more to my framework than that, this is a very (VERY) simplified view of how you can implement macro layer abstraction. I'm not saying this is the best solution but it was nice and simple for my needs and may be suitable for yours. If your requirements are more complex; however. it probably won't work for you.

Either way, I would strongly recommend log4cxx over log4cpp :)



// For generic logging I implemented a set of macros that did something like this...



#define MLOG_TRACE(msg) LOG4CXX_TRACE(log4cxx::Logger::getLogger("default"), msg)

#define MLOG_DEBUG(msg) LOG4CXX_DEBUG(log4cxx::Logger::getLogger("default"), msg)

#define MLOG_INFO(msg) LOG4CXX_INFO(log4cxx::Logger::getLogger("default"), msg)

#define MLOG_WARN(msg) LOG4CXX_WARN(log4cxx::Logger::getLogger("default"), msg)

#define MLOG_ERROR(msg) LOG4CXX_ERROR(log4cxx::Logger::getLogger("default"), msg)

#define MLOG_FATAL(msg) LOG4CXX_FATAL(log4cxx::Logger::getLogger("default"), msg)



// For function level logging I did something like this...



#define MLOG_FUNC_TRACE(msg) LOG4CXX_TRACE(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)

#define MLOG_FUNC_DEBUG(msg) LOG4CXX_DEBUG(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)

#define MLOG_FUNC_INFO(msg) LOG4CXX_INFO(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)

#define MLOG_FUNC_WARN(msg) LOG4CXX_WARN(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)

#define MLOG_FUNC_ERROR(msg) LOG4CXX_ERROR(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)

#define MLOG_FUNC_FATAL(msg) LOG4CXX_FATAL(log4cxx::Logger::getLogger(BOOST_CURRENT_FUNCTION), msg)



// For class level logging I did something like this...



#define MLOG_CLASS_TRACE(msg) LOG4CXX_TRACE(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

#define MLOG_CLASS_DEBUG(msg) LOG4CXX_DEBUG(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

#define MLOG_CLASS_INFO(msg) LOG4CXX_INFO(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

#define MLOG_CLASS_WARN(msg) LOG4CXX_WARN(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

#define MLOG_CLASS_ERROR(msg) LOG4CXX_ERROR(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

#define MLOG_CLASS_FATAL(msg) LOG4CXX_FATAL(log4cxx::Logger::getLogger(typeid(*this).name()), msg)

Open in new window

0
 
LVL 22

Expert Comment

by:ambience
ID: 33575864
@evilrix: Thanks for the link, I was looking for something like that but it always eluded me - always found log4cpp and log4cplus.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 53

Expert Comment

by:Infinity08
ID: 33576006
If you are using a well-supported, cross-platform logging library like log4cxx, I'd say there's no reason to have an abstraction layer around it ... It would only serve to complicate and slow down the code - probably introducing some bugs at the same time.

What is the reason for wanting an abstraction layer ?
0
 

Author Comment

by:vileda
ID: 33576192

It's adviced by some writers (like below link) to reduce dependency and to achive a loosely coupled design.

http://www.amazon.com/Code-Leader-Processes-Successful-Programmer/dp/0470259248
0
 
LVL 22

Expert Comment

by:ambience
ID: 33576252
Did you have a look at my earlier comment?
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 200 total points
ID: 33576400
>> It's adviced by some writers (like below link) to reduce dependency and to achive a loosely coupled design.

My point is that using the log4cxx (or similar) library, already achieves "loose coupling", since it already abstracts logging (it's cross-platform, and provides a unified, commonly used interface).

There's a point where adding abstractions just for the sake of adding them, does more harm than good to a project. And unless there is a really good reason, I would not recommend complicating the design by adding more abstraction layers.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33576689
>> My point is that using the log4cxx (or similar) library, already achieves "loose coupling"

You'll note that all my abstraction layer does is removes the explicit need to define a logger (something specific to the log4 logger) so that if you do choose to use a different library in the future your code does not been to be molested to incorporate it.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 33576785
>> so that if you do choose to use a different library in the future your code does not been to be molested to incorporate it.

If it's estimated that there is a very high probability that such a change will happen in the future, and if it's estimated that it's more cost-effective to put effort into making the abstraction now, rather than modifying the code when it's needed, then adding an abstraction layer might be a good idea.

I'm just talking from the general point of view, and from experience : most of the constructs put into place in code to facilitate possible future changes to the code, will never be used. In other words : most such changes are wasted effort, and result in needless complication (with performance loss and additional bugs as likely symptoms).

Note that I said "most", not "all" :)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Template syntax for variable length arrays 9 71
Task manager indicates my c++ program memory consumption is growing? 12 98
dividesSelf challange 15 112
Best book to learn C++ 4 70
What is Waterfall Model? Waterfall model is the classic Software Development Life Cycle method practiced in software development process. As the name "waterfall" describes, this development is flowing downwards steadily like waterfall, i.e., procee…
Introduction A frequently used term in Object-Oriented design is "SOLID" which is a mnemonic acronym that covers five principles of OO design.  These principles do not stand alone; there is interplay among them.  And they are not laws, merely princ…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now