blob: 0e1cc25725a277693296fe3a44992ba9e9e07387 [file] [log] [blame]
#include "tlbmc/trace/tracer.h"
#include <algorithm>
#include <cstddef>
#include <iterator>
#include <string>
#include "google/protobuf/duration.pb.h"
#include "absl/base/no_destructor.h"
#include "absl/time/time.h"
#include "tlbmc/time/time.h"
#include "trace.pb.h"
namespace milotic_tlbmc {
void Tracer::AddDatapoint(const std::string& keyword, absl::Time timestamp,
bool repeated) {
std::size_t order = 0;
if (auto it = keyword_to_order_.find(keyword);
it != keyword_to_order_.end()) {
order = it->second;
} else {
order = keyword_to_order_.size();
keyword_to_order_[keyword] = order;
}
CheckPoint checkpoint = {
.order = order,
.keyword = keyword,
.repeated = repeated,
};
datapoints_[checkpoint].push_back(timestamp);
}
void Tracer::AddRepeatedDatapoint(const std::string& keyword,
absl::Time timestamp) {
if (!enabled_) {
return;
}
AddDatapoint(keyword, timestamp, /*repeated=*/true);
}
void Tracer::AddOneOffDatapoint(const std::string& keyword,
absl::Time timestamp) {
if (!enabled_) {
return;
}
AddDatapoint(keyword, timestamp, /*repeated=*/false);
}
void Tracer::Clear() {
datapoints_.clear();
keyword_to_order_.clear();
}
Traces Tracer::Dump() const {
Traces traces;
for (auto it = datapoints_.begin(); it != datapoints_.end(); ++it) {
if (it == datapoints_.begin()) {
continue;
}
auto prev = std::prev(it);
if (prev->first.repeated != it->first.repeated) {
continue;
}
Trace trace;
trace.set_from_checkpoint(prev->first.keyword);
trace.set_to_checkpoint(it->first.keyword);
absl::Duration total_duration = absl::ZeroDuration();
std::size_t count = std::min(it->second.size(), prev->second.size());
std::size_t index_it = it->second.size();
std::size_t index_prev = prev->second.size();
while (index_it >= 1 && index_prev >= 1) {
total_duration += it->second[index_it - 1] - prev->second[index_prev - 1];
--index_prev;
--index_it;
}
absl::Duration average_duration = total_duration / count;
*trace.mutable_metrics()->mutable_average_duration() =
EncodeGoogleApiProto(average_duration);
*traces.add_traces() = trace;
}
return traces;
}
Tracer& Tracer::Initialize(bool enable) {
static absl::NoDestructor<Tracer> tracer(enable);
return *tracer;
}
Tracer& Tracer::GetInstance() { return Initialize(false); }
void Tracer::EnableTracer(const bool enable) { enabled_ = enable; }
} // namespace milotic_tlbmc