| #ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_MONITORING_H_ |
| #define THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_MONITORING_H_ |
| |
| #include <array> |
| #include <memory> |
| #include <tuple> |
| |
| #include "absl/functional/function_ref.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/time/clock.h" |
| #include "absl/time/time.h" |
| #include <source_location> |
| #include "request_response.h" |
| |
| namespace milotic { |
| |
| namespace metrics { |
| struct CreationOptions { |
| absl::string_view description; |
| }; |
| |
| template <typename... FieldT> |
| using FieldNames = std::array<absl::string_view, sizeof...(FieldT)>; |
| |
| template <typename... FieldT> |
| using FieldValues = std::tuple<FieldT...>; |
| |
| // Implementations should define the members of the following templates |
| template <typename... FieldT> |
| class Latency { |
| public: |
| explicit Latency(absl::string_view name, FieldNames<FieldT...> field_names, |
| const CreationOptions& options); |
| ~Latency(); |
| void Set( |
| absl::Duration latency, const FieldValues<FieldT...>& field_values, |
| const std::source_location& location = std::source_location::current()); |
| |
| private: |
| struct ImplData; |
| std::unique_ptr<ImplData> data_; |
| }; |
| |
| template <typename... FieldT> |
| class EventCounter { |
| public: |
| explicit EventCounter(absl::string_view name, |
| FieldNames<FieldT...> field_names, |
| const CreationOptions& options); |
| ~EventCounter(); |
| void Increment( |
| const FieldValues<FieldT...>& field_values, |
| const std::source_location& location = std::source_location::current()); |
| |
| private: |
| struct ImplData; |
| std::unique_ptr<ImplData> data_; |
| }; |
| |
| template <typename... FieldT> |
| class State { |
| public: |
| explicit State(absl::string_view name, FieldNames<FieldT...> field_names, |
| const CreationOptions& options); |
| ~State(); |
| void SetState( |
| absl::string_view state, const FieldValues<FieldT...>& field_values, |
| const std::source_location& location = std::source_location::current()); |
| |
| private: |
| struct ImplData; |
| std::unique_ptr<ImplData> data_; |
| }; |
| |
| // This exists mostly to enforce that a single implementation is linked. |
| extern const absl::string_view kImplementationName; |
| } // namespace metrics |
| |
| template <typename... FieldT> |
| class LatencyMonitor { |
| public: |
| LatencyMonitor( |
| metrics::Latency<FieldT...>* request_latency, |
| metrics::FieldValues<FieldT...> field_values, |
| absl::FunctionRef<absl::Time()> now = absl::Now, |
| std::source_location location = std::source_location::current()) |
| : now_(now), |
| request_latency_(request_latency), |
| field_values_(std::move(field_values)), |
| start_time_(now_()), |
| location_(location) {} |
| LatencyMonitor(const LatencyMonitor&) = delete; |
| LatencyMonitor& operator=(const LatencyMonitor&) = delete; |
| |
| ~LatencyMonitor() { |
| request_latency_->Set(now_() - start_time_, field_values_, location_); |
| } |
| |
| private: |
| absl::FunctionRef<absl::Time()> now_; |
| metrics::Latency<FieldT...>* request_latency_; |
| metrics::FieldValues<FieldT...> field_values_; |
| absl::Time start_time_; |
| std::source_location location_; |
| }; |
| |
| template <typename... FieldT> |
| absl::StatusOr<ProxyResponse> CaptureResponseCode( |
| const absl::StatusOr<ProxyResponse>& http_response, |
| metrics::EventCounter<absl::string_view, int, FieldT...>* event_counter, |
| absl::string_view url, metrics::FieldValues<FieldT...> field_values, |
| const std::source_location& location = std::source_location::current()) { |
| if (http_response.ok()) { |
| event_counter->Increment( |
| std::tuple_cat(std::make_tuple(url, http_response->code), |
| std::move(field_values)), |
| location); |
| } |
| return http_response; |
| } |
| |
| template <typename... FieldT> |
| LatencyMonitor(metrics::Latency<FieldT...>*, |
| metrics::FieldValues<FieldT...>) -> LatencyMonitor<FieldT...>; |
| |
| } // namespace milotic |
| #endif // THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_MONITORING_H_ |