blob: 4ddbd4fe248845f67c25efbf1bf72c0d0b536ece [file] [log] [blame]
Brian Silvermanf7f267a2017-02-04 16:16:08 -08001/*----------------------------------------------------------------------------*/
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 <sstream>
14#include <string>
15
16inline std::string NowTime();
17
18enum TLogLevel {
19 logNONE,
20 logERROR,
21 logWARNING,
22 logINFO,
23 logDEBUG,
24 logDEBUG1,
25 logDEBUG2,
26 logDEBUG3,
27 logDEBUG4
28};
29
30class Log {
31 public:
32 Log();
33 virtual ~Log();
34 std::ostringstream& 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 std::ostringstream os;
43
44 private:
45 Log(const Log&);
46 Log& operator=(const Log&);
47};
48
49inline Log::Log() {}
50
51inline std::ostringstream& Log::Get(TLogLevel level) {
52 os << "- " << NowTime();
53 os << " " << ToString(level) << ": ";
54 os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
55 return os;
56}
57
58inline Log::~Log() {
59 os << std::endl;
60 std::cerr << os.str();
61}
62
63inline TLogLevel& Log::ReportingLevel() {
64 static TLogLevel reportingLevel = logDEBUG4;
65 return reportingLevel;
66}
67
68inline std::string Log::ToString(TLogLevel level) {
69 static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
70 "INFO", "DEBUG", "DEBUG1",
71 "DEBUG2", "DEBUG3", "DEBUG4"};
72 return buffer[level];
73}
74
75inline TLogLevel Log::FromString(const std::string& level) {
76 if (level == "DEBUG4") return logDEBUG4;
77 if (level == "DEBUG3") return logDEBUG3;
78 if (level == "DEBUG2") return logDEBUG2;
79 if (level == "DEBUG1") return logDEBUG1;
80 if (level == "DEBUG") return logDEBUG;
81 if (level == "INFO") return logINFO;
82 if (level == "WARNING") return logWARNING;
83 if (level == "ERROR") return logERROR;
84 if (level == "NONE") return logNONE;
85 Log().Get(logWARNING) << "Unknown logging level '" << level
86 << "'. Using INFO level as default.";
87 return logINFO;
88}
89
90typedef Log FILELog;
91
92#define FILE_LOG(level) \
93 if (level > FILELog::ReportingLevel()) \
94 ; \
95 else \
96 Log().Get(level)
97
98inline std::string NowTime() {
99 std::stringstream ss;
100 ss << std::setfill('0') << std::setw(2);
101
102 using namespace std::chrono;
103 auto now = system_clock::now().time_since_epoch();
104
105 ss << duration_cast<hours>(now).count() % 24 << ":"
106 << duration_cast<minutes>(now).count() % 60 << ":"
107 << duration_cast<seconds>(now).count() % 60 << "."
108 << duration_cast<milliseconds>(now).count() % 1000;
109
110 return ss.str();
111}