WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
Log.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2016-2017. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 #include <chrono>
11 #include <string>
12 
13 #include "llvm/SmallString.h"
14 #include "llvm/raw_ostream.h"
15 
16 inline std::string NowTime();
17 
18 enum TLogLevel {
19  logNONE,
20  logERROR,
21  logWARNING,
22  logINFO,
23  logDEBUG,
24  logDEBUG1,
25  logDEBUG2,
26  logDEBUG3,
27  logDEBUG4
28 };
29 
30 class Log {
31  public:
32  Log();
33  virtual ~Log();
34  llvm::raw_ostream& Get(TLogLevel level = logINFO);
35 
36  public:
37  static TLogLevel& ReportingLevel();
38  static std::string ToString(TLogLevel level);
39  static TLogLevel FromString(const std::string& level);
40 
41  protected:
42  llvm::SmallString<128> buf;
43  llvm::raw_svector_ostream oss{buf};
44 
45  private:
46  Log(const Log&);
47  Log& operator=(const Log&);
48 };
49 
50 inline Log::Log() {}
51 
52 inline llvm::raw_ostream& Log::Get(TLogLevel level) {
53  oss << "- " << NowTime();
54  oss << " " << ToString(level) << ": ";
55  oss << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
56  return oss;
57 }
58 
59 inline Log::~Log() {
60  oss << "\n";
61  llvm::errs() << oss.str();
62 }
63 
64 inline TLogLevel& Log::ReportingLevel() {
65  static TLogLevel reportingLevel = logDEBUG4;
66  return reportingLevel;
67 }
68 
69 inline std::string Log::ToString(TLogLevel level) {
70  static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
71  "INFO", "DEBUG", "DEBUG1",
72  "DEBUG2", "DEBUG3", "DEBUG4"};
73  return buffer[level];
74 }
75 
76 inline TLogLevel Log::FromString(const std::string& level) {
77  if (level == "DEBUG4") return logDEBUG4;
78  if (level == "DEBUG3") return logDEBUG3;
79  if (level == "DEBUG2") return logDEBUG2;
80  if (level == "DEBUG1") return logDEBUG1;
81  if (level == "DEBUG") return logDEBUG;
82  if (level == "INFO") return logINFO;
83  if (level == "WARNING") return logWARNING;
84  if (level == "ERROR") return logERROR;
85  if (level == "NONE") return logNONE;
86  Log().Get(logWARNING) << "Unknown logging level '" << level
87  << "'. Using INFO level as default.";
88  return logINFO;
89 }
90 
91 typedef Log FILELog;
92 
93 #define FILE_LOG(level) \
94  if (level > FILELog::ReportingLevel()) \
95  ; \
96  else \
97  Log().Get(level)
98 
99 inline std::string NowTime() {
100  llvm::SmallString<128> buf;
101  llvm::raw_svector_ostream oss(buf);
102 
103  using namespace std::chrono;
104  auto now = system_clock::now().time_since_epoch();
105 
106  // Hours
107  auto count = duration_cast<hours>(now).count() % 24;
108  if (count < 10) oss << "0";
109  oss << count << ":";
110 
111  // Minutes
112  count = duration_cast<minutes>(now).count() % 60;
113  if (count < 10) oss << "0";
114  oss << count << ":";
115 
116  // Seconds
117  count = duration_cast<seconds>(now).count() % 60;
118  if (count < 10) oss << "0";
119  oss << count << ".";
120 
121  // Milliseconds
122  oss << duration_cast<milliseconds>(now).count() % 1000;
123 
124  return oss.str();
125 }
Definition: Log.h:30