Re: Logging
On Nov 14, 7:23 pm, Andrea Crotti <andrea.crott...@gmail.com> wrote:
I need some logging for my application, nothing too complicated, and I
found this (from the link cited at drdobbs)
#ifndef LOG_H
#define LOG_H
#include <stdio.h>
#include <iostream>
#include <sstream>
#define LOG(level) \
if (level > Log::ReportingLevel()) ; \
else Log().Get(level)
// Log, version 0.1: a simple logging class
// taken fromhttp://www.drdobbs.com/cpp/201804215
enum TLogLevel
{
logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, lo=
gDEBUG3, logDEBUG4
};
class Log
{
private:
Log(const Log&);
Log& operator =(const Log&);
TLogLevel messageLevel;
public:
Log() {}
virtual ~Log();
std::ostringstream& Get(TLogLevel level = logINFO);
public:
static TLogLevel& ReportingLevel();
protected:
std::ostringstream os;
};
std::ostringstream& Log::Get(TLogLevel level)
{
os << std::string(level > logDEBUG ? 0 : level - logDEBUG, '\t');
messageLevel = level;
return os;
}
Log::~Log()
{
os << std::endl;
fprintf(stderr, "%s", os.str().c_str());
fflush(stderr);
}
#endif /* LOG_H */
which looks perfectly fine for me, BUT this thing is puzzling
static TLogLevel& ReportingLevel();
to actually use this code I should
int main() {
Log::ReportingLevel() = logDEBUG1;
LOG(logWARNING) << "warning";
}
I get the infamous not found symbol
Undefined symbols:
"Log::ReportingLevel()", referenced from:
testLogging() in test.o
testLogging() in test.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Now a couple of questions
- what can be the problem? (Log.hpp was an header included and that
thing is public)
It looks like Log::ReportingLevel() is declared in header but it is
nowhere defined so linker does not find it.
- is assigning the value of a function in that way good? Doesn't really
look that nice to me...)
- what is the sense of having multiple "public" / "private".
I've seen it in other code also but I don't get why someone should do=
that...
Not sure. It is not forbidden to write "private: private: private:" so
it is up to designer of class.
I usually organize my classes in the way that public section is first,
then comes protected and finally private.
Some have the sections sliced and slices of sections intermixed and so
when later reorganizing them then some slices with same access remain
adjacent. That is perhaps a mess, but mind of most people is a mess
most of the time.
Other reason may be style. For example designer views public type/
constant/enumerator definitions as one section and public member
declarations as other section. The redundant "public:" serves then for
visually separating the two sections.