Leonardo Sala b427452f39 able to send data to eigerbe
tweaks on logging

added configuration_map, to flexibly pass options to the different receivers

some more fixes to method overloads

still very preliminary
2014-09-17 15:56:27 +02:00

195 lines
4.5 KiB
C++

//#ifndef __LOG_H__
//#define __LOG_H__
#include <sstream>
#include <string>
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define MYCONCAT(x,y)
#define __AT__ string(__FILE__) + string("::") + string(__func__) + string("(): ")
//":" TOSTRING(__LINE__)
/*
void error(const char *location, const char *msg){
printf("Error at %s: %s\n", location, msg);
}
*/
inline std::string NowTime();
enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
template <typename T> class Log{
public:
Log();
virtual ~Log();
std::ostringstream& Get(TLogLevel level = logINFO);
static TLogLevel& ReportingLevel();
static std::string ToString(TLogLevel level);
static TLogLevel FromString(const std::string& level);
protected:
std::ostringstream os;
private:
Log(const Log&);
Log& operator =(const Log&);
};
class Output2FILE {
public:
static FILE*& Stream();
static void Output(const std::string& msg);
};
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# if defined (BUILDING_FILELOG_DLL)
# define FILELOG_DECLSPEC __declspec (dllexport)
# elif defined (USING_FILELOG_DLL)
# define FILELOG_DECLSPEC __declspec (dllimport)
# else
# define FILELOG_DECLSPEC
# endif // BUILDING_DBSIMPLE_DLL
#else
# define FILELOG_DECLSPEC
#endif // _WIN32
class FILELOG_DECLSPEC FILELog : public Log<Output2FILE> {};
//typedef Log<Output2FILE> FILELog;
#ifndef FILELOG_MAX_LEVEL
#define FILELOG_MAX_LEVEL logDEBUG4
#endif
#define FILE_LOG(level) \
if (level > FILELOG_MAX_LEVEL) ; \
else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \
else FILELog().Get(level)
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#include <windows.h>
inline std::string NowTime()
{
const int MAX_LEN = 200;
char buffer[MAX_LEN];
if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0,
"HH':'mm':'ss", buffer, MAX_LEN) == 0)
return "Error in NowTime()";
char result[100] = {0};
static DWORD first = GetTickCount();
sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000);
return result;
}
#else
#include <sys/time.h>
inline std::string NowTime()
{
char buffer[11];
time_t t;
time(&t);
tm r = {0};
strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
struct timeval tv;
gettimeofday(&tv, 0);
char result[100] = {0};
sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
return result;
}
#endif //WIN32
template <typename T> Log<T>::Log(){}
template <typename T> std::ostringstream& Log<T>::Get(TLogLevel level)
{
os << "- " << NowTime();
os << " " << ToString(level) << ": ";
os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
return os;
}
template <typename T> Log<T>::~Log()
{
os << std::endl;
T::Output( os.str());
}
template <typename T> TLogLevel& Log<T>::ReportingLevel()
{
static TLogLevel reportingLevel = logDEBUG4;
return reportingLevel;
}
template <typename T> std::string Log<T>::ToString(TLogLevel level)
{
static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
return buffer[level];
}
template <typename T>
TLogLevel Log<T>::FromString(const std::string& level)
{
if (level == "DEBUG4")
return logDEBUG4;
if (level == "DEBUG3")
return logDEBUG3;
if (level == "DEBUG2")
return logDEBUG2;
if (level == "DEBUG1")
return logDEBUG1;
if (level == "DEBUG")
return logDEBUG;
if (level == "INFO")
return logINFO;
if (level == "WARNING")
return logWARNING;
if (level == "ERROR")
return logERROR;
Log<T>().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
return logINFO;
}
inline FILE*& Output2FILE::Stream()
{
static FILE* pStream = stderr;
return pStream;
}
inline void Output2FILE::Output(const std::string& msg)
{
FILE* pStream = Stream();
if (!pStream)
return;
fprintf(pStream, "%s", msg.c_str());
fflush(pStream);
}
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
# if defined (BUILDING_FILELOG_DLL)
# define FILELOG_DECLSPEC __declspec (dllexport)
# elif defined (USING_FILELOG_DLL)
# define FILELOG_DECLSPEC __declspec (dllimport)
# else
# define FILELOG_DECLSPEC
# endif // BUILDING_DBSIMPLE_DLL
#else
# define FILELOG_DECLSPEC
#endif // _WIN32
//#endif //__LOG_H__