blob: eb221e79c465c3fbdc4a1c686bb56bba408ed9f1 [file] [log] [blame]
Brian Silverman9c0f1452015-01-10 21:19:39 -08001#pragma once
2
3#include <sstream>
4#include <iomanip>
5#include <string>
6#include <stdio.h>
7#include <sys/time.h>
8
9inline std::string NowTime();
10
11enum TLogLevel {logNONE, logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
12
13class Log
14{
15public:
16 Log();
17 virtual ~Log();
18 std::ostringstream& Get(TLogLevel level = logINFO);
19public:
20 static TLogLevel& ReportingLevel();
21 static std::string ToString(TLogLevel level);
22 static TLogLevel FromString(const std::string& level);
23protected:
24 std::ostringstream os;
25private:
26 Log(const Log&);
27 Log& operator =(const Log&);
28};
29
30inline Log::Log()
31{
32}
33
34inline std::ostringstream& Log::Get(TLogLevel level)
35{
36 os << "- " << NowTime();
37 os << " " << ToString(level) << ": ";
38 os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
39 return os;
40}
41
42inline Log::~Log()
43{
44 os << std::endl;
45 fprintf(stderr, "%s", os.str().c_str());
46 fflush(stderr);
47}
48
49inline TLogLevel& Log::ReportingLevel()
50{
51 static TLogLevel reportingLevel = logDEBUG4;
52 return reportingLevel;
53}
54
55inline std::string Log::ToString(TLogLevel level)
56{
57 static const char* const buffer[] = {"NONE", "ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
58 return buffer[level];
59}
60
61inline TLogLevel Log::FromString(const std::string& level)
62{
63 if (level == "DEBUG4")
64 return logDEBUG4;
65 if (level == "DEBUG3")
66 return logDEBUG3;
67 if (level == "DEBUG2")
68 return logDEBUG2;
69 if (level == "DEBUG1")
70 return logDEBUG1;
71 if (level == "DEBUG")
72 return logDEBUG;
73 if (level == "INFO")
74 return logINFO;
75 if (level == "WARNING")
76 return logWARNING;
77 if (level == "ERROR")
78 return logERROR;
79 if (level == "NONE")
80 return logNONE;
81 Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
82 return logINFO;
83}
84
85typedef Log FILELog;
86
87#define FILE_LOG(level) \
88 if (level > FILELog::ReportingLevel()) ; \
89 else Log().Get(level)
90
91inline std::string NowTime()
92{
93 char buffer[11];
94 time_t t;
95 time(&t);
96 tm * r = gmtime(&t);
97 strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
98 struct timeval tv;
99 gettimeofday(&tv, 0);
100 char result[100] = {0};
101 sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
102 return result;
103}