remote/DebugInfo.cpp (63 lines of code) (raw):
#include "DebugInfo.h"
#include <map>
#include <sstream>
#include <mutex>
#include "Utils.h"
namespace {
struct Measure {
int64_t count = 0;
int64_t max;
int64_t min;
int64_t sum;
};
std::map<std::string, Measure> MEASURES;
std::mutex MEASURES_MUTEX;
std::string printMeasure(const std::string & name, const Measure & m, int tabs) {
std::stringstream ss;
for (int i = 0; i < tabs; ++i) ss << "\t";
ss << name << ": count=" << m.count << ", min=" << m.min << ", max=" << m.max << ", avg=" << m.sum/m.count << ", total ms: " << m.sum/1000;
return ss.str();
}
std::string printAllMeasures(int tabs) {
std::unique_lock lock(MEASURES_MUTEX);
if (MEASURES.empty())
return "";
std::stringstream ss;
for (auto kv : MEASURES)
ss << printMeasure(kv.first, kv.second, tabs) << std::endl;
return ss.str();
}
}
std::vector<std::function<std::string()>> DebugInfo::INFO_PROVIDERS;
void DebugInfo::addInfoProvider(std::function<std::string()> f) {
INFO_PROVIDERS.push_back(f);
}
std::string DebugInfo::getInfo(int tabs) {
std::stringstream ss;
for (auto p : INFO_PROVIDERS) {
for (int i = 0; i < tabs; ++i) ss << "\t";
ss << p() << std::endl;
}
return ss.str();
}
std::string DebugInfo::getMeasures(int tabs) {
return printAllMeasures(tabs);
}
void DebugInfo::addMeasure(const std::string & name, int64_t value) {
std::unique_lock lock(MEASURES_MUTEX);
Measure & m = MEASURES[name];
if (m.count == 0) {
m.min = m.max = m.sum = value;
} else {
m.max = std::max(m.max, value);
m.min = std::min(m.min, value);
m.sum += value;
}
m.count++;
}
namespace utils {
// NOTE: when implementation of this dtor is placed in Utils.cpp then OSX-linker fails.
Measurer::~Measurer() {
if (isEnabled)
DebugInfo::addMeasure(name, std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count());
}
}