| #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 |