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 <iomanip>
12 #include <iostream>
13 #include <string>
14 
15 #include "llvm/SmallString.h"
16 #include "llvm/raw_ostream.h"
17 
18 inline std::string NowTime();
19 
20 enum TLogLevel {
21  logNONE,
22  logERROR,
23  logWARNING,
24  logINFO,
25  logDEBUG,
26  logDEBUG1,
27  logDEBUG2,
28  logDEBUG3,
29  logDEBUG4
30 };
31 
32 class Log {
33  public:
34  Log();
35  virtual ~Log();
36  llvm::raw_ostream& Get(TLogLevel level = logINFO);
37 
38  public:
39  static TLogLevel& ReportingLevel();
40  static std::string ToString(TLogLevel level);
41  static TLogLevel FromString(const std::string& level);
42 
43  protected:
44  llvm::SmallString<128> buf;
45  llvm::raw_svector_ostream oss{buf};
46 
47  private:
48  Log(const Log&);
49  Log& operator=(const Log&);
50 };
51 
52 inline Log::Log() {}
53 
54 inline llvm::raw_ostream& Log::Get(TLogLevel level) {
55  oss << "- " << NowTime();
56  oss << " " << ToString(level) << ": ";
57  oss << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
58  return oss;
59 }
60 
61 inline Log::~Log() {
62  oss << "\n";
63  std::cerr << oss.str();
64 }
65 
66 inline TLogLevel& Log::ReportingLevel() {
67  static TLogLevel reportingLevel = logDEBUG4;
68  return reportingLevel;
69 }
70 
71 inline std::string Log::ToString(TLogLevel level) {
72  static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
73  "INFO", "DEBUG", "DEBUG1",
74  "DEBUG2", "DEBUG3", "DEBUG4"};
75  return buffer[level];
76 }
77 
78 inline TLogLevel Log::FromString(const std::string& level) {
79  if (level == "DEBUG4") return logDEBUG4;
80  if (level == "DEBUG3") return logDEBUG3;
81  if (level == "DEBUG2") return logDEBUG2;
82  if (level == "DEBUG1") return logDEBUG1;
83  if (level == "DEBUG") return logDEBUG;
84  if (level == "INFO") return logINFO;
85  if (level == "WARNING") return logWARNING;
86  if (level == "ERROR") return logERROR;
87  if (level == "NONE") return logNONE;
88  Log().Get(logWARNING) << "Unknown logging level '" << level
89  << "'. Using INFO level as default.";
90  return logINFO;
91 }
92 
93 typedef Log FILELog;
94 
95 #define FILE_LOG(level) \
96  if (level > FILELog::ReportingLevel()) \
97  ; \
98  else \
99  Log().Get(level)
100 
101 inline std::string NowTime() {
102  llvm::SmallString<128> buf;
103  llvm::raw_svector_ostream oss(buf);
104 
105  using namespace std::chrono;
106  auto now = system_clock::now().time_since_epoch();
107 
108  // Hours
109  auto count = duration_cast<hours>(now).count() % 24;
110  if (count < 10) oss << "0";
111  oss << count << ":";
112 
113  // Minutes
114  count = duration_cast<minutes>(now).count() % 60;
115  if (count < 10) oss << "0";
116  oss << count << ":";
117 
118  // Seconds
119  count = duration_cast<seconds>(now).count() % 60;
120  if (count < 10) oss << "0";
121  oss << count << ".";
122 
123  // Milliseconds
124  oss << duration_cast<milliseconds>(now).count() % 1000;
125 
126  return oss.str();
127 }
Definition: Log.h:32