mirror of
https://github.com/typesense/typesense.git
synced 2025-05-19 05:08:43 +08:00
Capture search related metrics separately.
This commit is contained in:
parent
d75e834ac3
commit
39910c872a
@ -10,6 +10,8 @@ class AppMetrics {
|
||||
private:
|
||||
mutable std::shared_mutex mutex;
|
||||
|
||||
static inline const std::string SEARCH_LABEL = "search";
|
||||
|
||||
// stores last complete window
|
||||
spp::sparse_hash_map<std::string, uint64_t>* counts;
|
||||
spp::sparse_hash_map<std::string, uint64_t>* durations;
|
||||
@ -51,11 +53,21 @@ public:
|
||||
(*current_counts)[identifier] += count;
|
||||
}
|
||||
|
||||
void increment_search_count(uint64_t count) {
|
||||
std::unique_lock lock(mutex);
|
||||
(*current_counts)[SEARCH_LABEL] += count;
|
||||
}
|
||||
|
||||
void increment_duration(const std::string& identifier, uint64_t duration) {
|
||||
std::unique_lock lock(mutex);
|
||||
(*current_durations)[identifier] += duration;
|
||||
}
|
||||
|
||||
void increment_search_duration(uint64_t duration) {
|
||||
std::unique_lock lock(mutex);
|
||||
(*current_durations)[SEARCH_LABEL] += duration;
|
||||
}
|
||||
|
||||
void window_reset() {
|
||||
std::unique_lock lock(mutex);
|
||||
|
||||
@ -68,24 +80,33 @@ public:
|
||||
current_durations = new spp::sparse_hash_map<std::string, uint64_t>();
|
||||
}
|
||||
|
||||
void get(const std::string& count_key, const std::string& latency_key, nlohmann::json &result) const {
|
||||
void get(const std::string& rps_key, const std::string& latency_key, nlohmann::json &result) const {
|
||||
std::shared_lock lock(mutex);
|
||||
|
||||
uint64_t total_counts = 0;
|
||||
|
||||
result[count_key] = nlohmann::json::object();
|
||||
result[rps_key] = nlohmann::json::object();
|
||||
for(const auto& kv: *counts) {
|
||||
result[count_key][kv.first] = (double(kv.second) / (METRICS_REFRESH_INTERVAL_MS / 1000));
|
||||
total_counts += kv.second;
|
||||
if(kv.first == SEARCH_LABEL) {
|
||||
result[SEARCH_LABEL + "_" + rps_key] = double(kv.second) / (METRICS_REFRESH_INTERVAL_MS / 1000);
|
||||
} else {
|
||||
result[rps_key][kv.first] = (double(kv.second) / (METRICS_REFRESH_INTERVAL_MS / 1000));
|
||||
total_counts += kv.second;
|
||||
}
|
||||
}
|
||||
|
||||
result["total_"+count_key] = double(total_counts) / (METRICS_REFRESH_INTERVAL_MS / 1000);
|
||||
result["total_" + rps_key] = double(total_counts) / (METRICS_REFRESH_INTERVAL_MS / 1000);
|
||||
|
||||
result[latency_key] = nlohmann::json::object();
|
||||
|
||||
for(const auto& kv: *durations) {
|
||||
auto counter_it = counts->find(kv.first);
|
||||
if(counter_it != counts->end() && counter_it->second != 0) {
|
||||
result[latency_key][kv.first] = (double(kv.second) / counter_it->second);
|
||||
if(kv.first == SEARCH_LABEL) {
|
||||
result[SEARCH_LABEL + "_" + latency_key] = (double(kv.second) / counter_it->second);
|
||||
} else {
|
||||
result[latency_key][kv.first] = (double(kv.second) / counter_it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <json.hpp>
|
||||
#include <app_metrics.h>
|
||||
#include "collection_manager.h"
|
||||
#include "logger.h"
|
||||
|
||||
@ -818,6 +819,8 @@ Option<bool> CollectionManager::do_search(std::map<std::string, std::string>& re
|
||||
uint64_t timeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::high_resolution_clock::now() - begin).count();
|
||||
|
||||
AppMetrics::get_instance().increment_search_count(1);
|
||||
AppMetrics::get_instance().increment_search_duration(timeMillis);
|
||||
|
||||
if(!result_op.ok()) {
|
||||
return Option<bool>(result_op.code(), result_op.error());
|
||||
|
45
test/app_metrics_test.cpp
Normal file
45
test/app_metrics_test.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "app_metrics.h"
|
||||
|
||||
class AppMetricsTest : public ::testing::Test {
|
||||
protected:
|
||||
AppMetrics& metrics = AppMetrics::get_instance();
|
||||
|
||||
virtual void SetUp() {
|
||||
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST_F(AppMetricsTest, StatefulRemoveDocs) {
|
||||
metrics.increment_count("GET /collections", 1);
|
||||
metrics.increment_count("GET /collections", 1);
|
||||
metrics.increment_count("GET /operations/vote", 1);
|
||||
|
||||
metrics.increment_duration("GET /collections", 2);
|
||||
metrics.increment_duration("GET /collections", 4);
|
||||
metrics.increment_duration("GET /operations/vote", 5);
|
||||
|
||||
metrics.increment_search_count(1);
|
||||
metrics.increment_search_count(1);
|
||||
metrics.increment_search_duration(16);
|
||||
metrics.increment_search_duration(12);
|
||||
|
||||
metrics.window_reset();
|
||||
|
||||
nlohmann::json result;
|
||||
metrics.get("rps", "latency", result);
|
||||
|
||||
ASSERT_EQ(result["search_latency"].get<double>(), 14.0);
|
||||
ASSERT_EQ(result["search_rps"].get<double>(), 0.2);
|
||||
|
||||
ASSERT_EQ(result["latency"]["GET /collections"].get<double>(), 3.0);
|
||||
ASSERT_EQ(result["latency"]["GET /operations/vote"].get<double>(), 5.0);
|
||||
|
||||
ASSERT_EQ(result["rps"]["GET /collections"].get<double>(), 0.2);
|
||||
ASSERT_EQ(result["rps"]["GET /operations/vote"].get<double>(), 0.1);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user