2016-05-25 20:23:37 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2018-01-02 09:20:21 -08:00
|
|
|
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
|
2016-05-25 20:23:37 -07:00
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
2014-05-02 17:54:01 -04:00
|
|
|
#pragma once
|
2014-01-06 09:27:51 -05:00
|
|
|
|
2016-07-09 16:58:31 -07:00
|
|
|
#include <chrono>
|
2014-01-06 09:27:51 -05:00
|
|
|
#include <string>
|
|
|
|
|
|
2017-08-27 00:11:52 -07:00
|
|
|
#include <llvm/SmallString.h>
|
|
|
|
|
#include <llvm/raw_ostream.h>
|
2017-05-15 23:10:40 -07:00
|
|
|
|
2014-01-06 09:27:51 -05:00
|
|
|
inline std::string NowTime();
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
enum TLogLevel {
|
|
|
|
|
logNONE,
|
|
|
|
|
logERROR,
|
|
|
|
|
logWARNING,
|
|
|
|
|
logINFO,
|
|
|
|
|
logDEBUG,
|
|
|
|
|
logDEBUG1,
|
|
|
|
|
logDEBUG2,
|
|
|
|
|
logDEBUG3,
|
|
|
|
|
logDEBUG4
|
2014-01-06 09:27:51 -05:00
|
|
|
};
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
class Log {
|
|
|
|
|
public:
|
|
|
|
|
Log();
|
|
|
|
|
virtual ~Log();
|
2017-05-15 23:10:40 -07:00
|
|
|
llvm::raw_ostream& Get(TLogLevel level = logINFO);
|
2016-05-20 17:30:37 -07:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static TLogLevel& ReportingLevel();
|
|
|
|
|
static std::string ToString(TLogLevel level);
|
|
|
|
|
static TLogLevel FromString(const std::string& level);
|
2014-01-06 09:27:51 -05:00
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
protected:
|
2017-05-15 23:10:40 -07:00
|
|
|
llvm::SmallString<128> buf;
|
|
|
|
|
llvm::raw_svector_ostream oss{buf};
|
2016-05-20 17:30:37 -07:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Log(const Log&);
|
|
|
|
|
Log& operator=(const Log&);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
inline Log::Log() {}
|
|
|
|
|
|
2017-05-15 23:10:40 -07:00
|
|
|
inline llvm::raw_ostream& Log::Get(TLogLevel level) {
|
|
|
|
|
oss << "- " << NowTime();
|
|
|
|
|
oss << " " << ToString(level) << ": ";
|
2017-11-08 23:44:03 -08:00
|
|
|
if (level > logDEBUG) {
|
|
|
|
|
oss << std::string(level - logDEBUG, '\t');
|
|
|
|
|
}
|
2017-05-15 23:10:40 -07:00
|
|
|
return oss;
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
inline Log::~Log() {
|
2017-05-15 23:10:40 -07:00
|
|
|
oss << "\n";
|
2017-06-30 22:33:43 -04:00
|
|
|
llvm::errs() << oss.str();
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
inline TLogLevel& Log::ReportingLevel() {
|
|
|
|
|
static TLogLevel reportingLevel = logDEBUG4;
|
|
|
|
|
return reportingLevel;
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
inline std::string Log::ToString(TLogLevel level) {
|
|
|
|
|
static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
|
|
|
|
|
"INFO", "DEBUG", "DEBUG1",
|
|
|
|
|
"DEBUG2", "DEBUG3", "DEBUG4"};
|
|
|
|
|
return buffer[level];
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
inline TLogLevel Log::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;
|
|
|
|
|
if (level == "NONE") return logNONE;
|
|
|
|
|
Log().Get(logWARNING) << "Unknown logging level '" << level
|
|
|
|
|
<< "'. Using INFO level as default.";
|
|
|
|
|
return logINFO;
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef Log FILELog;
|
|
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
#define FILE_LOG(level) \
|
|
|
|
|
if (level > FILELog::ReportingLevel()) \
|
|
|
|
|
; \
|
|
|
|
|
else \
|
2017-11-11 22:09:51 -08:00
|
|
|
Log().Get(level)
|
2015-04-26 19:19:57 -04:00
|
|
|
|
2016-05-20 17:30:37 -07:00
|
|
|
inline std::string NowTime() {
|
2017-05-15 23:10:40 -07:00
|
|
|
llvm::SmallString<128> buf;
|
|
|
|
|
llvm::raw_svector_ostream oss(buf);
|
2016-07-09 16:58:31 -07:00
|
|
|
|
2017-08-07 17:36:34 -07:00
|
|
|
using std::chrono::duration_cast;
|
|
|
|
|
|
|
|
|
|
auto now = std::chrono::system_clock::now().time_since_epoch();
|
2016-07-09 16:58:31 -07:00
|
|
|
|
2017-05-15 23:10:40 -07:00
|
|
|
// Hours
|
2017-08-07 17:36:34 -07:00
|
|
|
auto count = duration_cast<std::chrono::hours>(now).count() % 24;
|
2017-05-15 23:10:40 -07:00
|
|
|
if (count < 10) oss << "0";
|
|
|
|
|
oss << count << ":";
|
|
|
|
|
|
|
|
|
|
// Minutes
|
2017-08-07 17:36:34 -07:00
|
|
|
count = duration_cast<std::chrono::minutes>(now).count() % 60;
|
2017-05-15 23:10:40 -07:00
|
|
|
if (count < 10) oss << "0";
|
|
|
|
|
oss << count << ":";
|
|
|
|
|
|
|
|
|
|
// Seconds
|
2017-08-07 17:36:34 -07:00
|
|
|
count = duration_cast<std::chrono::seconds>(now).count() % 60;
|
2017-05-15 23:10:40 -07:00
|
|
|
if (count < 10) oss << "0";
|
|
|
|
|
oss << count << ".";
|
|
|
|
|
|
|
|
|
|
// Milliseconds
|
2017-08-07 17:36:34 -07:00
|
|
|
oss << duration_cast<std::chrono::milliseconds>(now).count() % 1000;
|
2016-07-09 16:58:31 -07:00
|
|
|
|
2017-05-15 23:10:40 -07:00
|
|
|
return oss.str();
|
2014-01-06 09:27:51 -05:00
|
|
|
}
|