| #ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_TRACE_TRACER_H_ |
| #define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_TRACE_TRACER_H_ |
| |
| #include <cstddef> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/container/btree_map.h" |
| #include "absl/container/flat_hash_map.h" |
| #include "absl/log/log.h" |
| #include "absl/time/clock.h" |
| #include "absl/time/time.h" |
| #include "trace.pb.h" |
| |
| namespace milotic_tlbmc { |
| |
| struct CheckPoint { |
| std::size_t order; |
| std::string keyword; |
| bool repeated; |
| bool operator<(const CheckPoint& other) const { return order < other.order; } |
| }; |
| |
| // A simple tracer to profile tlBMC performance. |
| // The class is thread-safe when it is disabled but thread-unsafe when enabled. |
| // Currently only support profiling single thread: useful to profile code blocks |
| // with a single client. Typical use case: |
| /* |
| |
| Tracer::Initialize(true); |
| |
| // init started |
| Tracer::GetInstance().AddOneOffDatapoint("init_started"); |
| // init finished |
| Tracer::GetInstance().AddOneOffDatapoint("init_finished"); |
| |
| void HandleRequest() { |
| // repeated work A started |
| Tracer::GetInstance().AddDatapoint("work_A_started"); |
| // repeated work A finished |
| Tracer::GetInstance().AddDatapoint("work_A_finished"); |
| // repeated work B started |
| Tracer::GetInstance().AddDatapoint("work_B_started"); |
| // repeated work B finished |
| Tracer::GetInstance().AddDatapoint("work_B_finished"); |
| } |
| |
| // tear down started |
| Tracer::GetInstance().AddOneOffDatapoint("tear_down_started"); |
| // tear down finished |
| Tracer::GetInstance().AddOneOffDatapoint("tear_down_finished"); |
| |
| // Done |
| LOG(INFO) << absl::StrCat(Tracer::GetInstance().Dump()); |
| */ |
| class Tracer { |
| public: |
| static Tracer& Initialize(bool enable); |
| static Tracer& GetInstance(); |
| |
| explicit Tracer(bool enable) : enabled_(enable) { |
| LOG(INFO) << "Tracer is " << (enabled_ ? "enabled" : "disabled"); |
| } |
| |
| // Add a datapoint (with `timestamp`) to the corresponding checkpoint |
| // specified by the `keyword`. |
| void AddRepeatedDatapoint(const std::string& keyword, |
| absl::Time timestamp = absl::Now()); |
| void AddOneOffDatapoint(const std::string& keyword, |
| absl::Time timestamp = absl::Now()); |
| void Clear(); |
| Traces Dump() const; |
| void EnableTracer(bool enable); |
| |
| protected: |
| void AddDatapoint(const std::string& keyword, absl::Time timestamp, |
| bool repeated); |
| |
| private: |
| bool enabled_; |
| absl::btree_map<CheckPoint, std::vector<absl::Time>> datapoints_; |
| absl::flat_hash_map<std::string, size_t> keyword_to_order_; |
| }; |
| |
| } // namespace milotic_tlbmc |
| |
| #endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_TRACE_TRACER_H_ |