blob: 10a6a5b933d9c530179fada626d75f82be9fab97 [file] [log] [blame]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_SHARED_MEM_METRICS_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_SHARED_MEM_METRICS_H_
#include <sys/types.h>
#include <array>
#include <atomic>
#include <chrono> // NOLINT
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
#include "absl/time/time.h"
// copybara:strip_begin(g3-shared-libs)
#include "nlohmann/json.hpp"
// copybara:strip_end
#include "pattern_to_entity_array.h"
namespace milotic_tlbmc {
constexpr std::size_t kResourceCount =
milotic::authz::pattern_entity_pair_array.size();
// clang-format off
constexpr std::array<int, 4> kSupportedStatusCodes = {
// go/keep-sorted start
200,
401,
404,
500,
// go/keep-sorted end
};
// clang-format on
constexpr size_t kResponseTimeHistogramBucketCount = 20;
constexpr absl::Duration kResponseTimeHistogramBucketTime =
absl::Milliseconds(50);
constexpr size_t kMaxResponseStatusCode = 600;
constexpr size_t kTopLatencyResourcesCount = 20;
// The class is thread-safe.
class TlbmcMetrics {
public:
using MetricsIntegerType =
std::conditional_t<sizeof(void*) == 4, uint32_t, uint64_t>;
TlbmcMetrics() {
static_assert(std::atomic<MetricsIntegerType>::is_always_lock_free);
}
// copybara:strip_begin(g3-shared-libs)
void UpdateMetricsRequestCount(bool is_tlbmc_request);
void UpdateMetricsResponse(absl::Duration response_time, int status_code,
std::string_view resource_url);
// Calculates the Requests Per Second of TLBMC and gBMCWeb Redfish requests.
void UpdateMetricsRps(absl::Duration time_delta);
// Dumps to a JSON used for metrics collection. Contains the top
// `kTopLatencyResourcesCount` resources with the highest average latency.
// This call is expensive. Please call it only periodically, e.g., every
// minute.
nlohmann::json ToJson() const;
// Dumps to a JSON used for metrics collection. Contains the top
// `top_latency_resources_count` resources with the highest average latency.
nlohmann::json ToJson(int top_latency_resources_count) const;
// Dumps to a JSON used for debugging.
nlohmann::json ToDebugJson() const;
MetricsIntegerType GetTlbmcRequestCount() const {
return total_tlbmc_request_count_.load();
}
MetricsIntegerType GetGbmcwebRequestCount() const {
return total_gbmcweb_request_count_.load();
}
MetricsIntegerType GetTlbmcRps() const {
return tlbmc_requests_per_second_.load();
}
MetricsIntegerType GetBmcwebRps() const {
return bmcweb_requests_per_second_.load();
}
MetricsIntegerType GetTotalRps() const {
return total_requests_per_second_.load();
}
// copybara:strip_end
private:
std::atomic<MetricsIntegerType> total_tlbmc_request_count_ = 0;
std::atomic<MetricsIntegerType> total_gbmcweb_request_count_ = 0;
// Response status code count.
std::atomic<MetricsIntegerType>
response_status_code_count_[kMaxResponseStatusCode + 1] = {0};
// Historgram of response time. Every 50ms the response time is recorded.
// At this moment, the histogram is 20 buckets, and each bucket is 50ms.
// The first bucket is [0, 50ms), the last bucket is [950ms, inf).
std::atomic<MetricsIntegerType>
response_time_histogram_[kResponseTimeHistogramBucketCount] = {0};
// Resource average latency distribution.
std::atomic<MetricsIntegerType>
total_response_count_per_resource_[kResourceCount] = {0};
// TODO(nanzhou): handles overflow.
std::atomic<MetricsIntegerType>
response_total_latency_ms_per_resource_[kResourceCount] = {0};
std::atomic<MetricsIntegerType> tlbmc_requests_per_second_ = 0;
std::atomic<MetricsIntegerType> bmcweb_requests_per_second_ = 0;
std::atomic<MetricsIntegerType> total_requests_per_second_ = 0;
std::atomic<MetricsIntegerType> prev_tlbmc_request_count_ = 0;
std::atomic<MetricsIntegerType> prev_bmcweb_request_count_ = 0;
};
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_HAL_SHARED_MEM_METRICS_H_