31 metric_sample sample1{
"operation1", std::chrono::nanoseconds(1000),
true};
32 metric_sample sample2{
"operation1", std::chrono::nanoseconds(2000),
true};
33 metric_sample sample3{
"operation1", std::chrono::nanoseconds(1500),
false};
35 EXPECT_TRUE(buffer.
record(sample1));
36 EXPECT_TRUE(buffer.
record(sample2));
37 EXPECT_TRUE(buffer.
record(sample3));
39 EXPECT_EQ(buffer.
size(), 3);
42 size_t flushed = buffer.
flush();
43 EXPECT_EQ(flushed, 3);
44 EXPECT_EQ(buffer.
size(), 0);
47 auto stats = collector->get_stats();
48 EXPECT_EQ(stats.total_samples, 3);
49 EXPECT_EQ(stats.batches_received, 1);
50 EXPECT_EQ(stats.operation_count, 1);
53 auto profile_result = collector->get_profile(
"operation1");
54 ASSERT_TRUE(profile_result.is_ok());
56 auto profile = profile_result.value();
57 EXPECT_EQ(profile.total_calls, 3);
58 EXPECT_EQ(profile.error_count, 1);
59 EXPECT_EQ(profile.min_duration_ns, 1000);
60 EXPECT_EQ(profile.max_duration_ns, 2000);
88 constexpr int NUM_THREADS = 4;
89 constexpr int SAMPLES_PER_THREAD = 1000;
91 std::vector<std::thread> threads;
93 for (
int t = 0; t < NUM_THREADS; ++t) {
94 threads.emplace_back([
this, t]() {
96 std::string op_name =
"thread_op_" + std::to_string(t);
98 for (
int i = 0; i < SAMPLES_PER_THREAD; ++i) {
101 std::chrono::nanoseconds(100 + i),
113 for (
auto& t : threads) {
118 auto stats = collector->get_stats();
119 EXPECT_EQ(stats.total_samples, NUM_THREADS * SAMPLES_PER_THREAD);
120 EXPECT_EQ(stats.operation_count, NUM_THREADS);
123 for (
int t = 0; t < NUM_THREADS; ++t) {
124 std::string op_name =
"thread_op_" + std::to_string(t);
125 auto profile_result = collector->get_profile(op_name);
126 ASSERT_TRUE(profile_result.is_ok());
128 auto profile = profile_result.value();
129 EXPECT_EQ(profile.total_calls, SAMPLES_PER_THREAD);
130 EXPECT_EQ(profile.error_count, SAMPLES_PER_THREAD / 10);
135 auto limited_collector = std::make_shared<central_collector>(10);
140 for (
int i = 0; i < 15; ++i) {
141 std::string op_name =
"op_" + std::to_string(i);
142 metric_sample sample{op_name, std::chrono::nanoseconds(1000),
true};
149 auto stats = limited_collector->get_stats();
150 EXPECT_LE(stats.operation_count, 10);
151 EXPECT_GE(stats.lru_evictions, 5);
158 for (
int i = 0; i < 5; ++i) {
159 std::string op_name =
"operation_" + std::to_string(i);
160 metric_sample sample{op_name, std::chrono::nanoseconds(1000 * (i + 1)),
true};
167 auto all_profiles = collector->get_all_profiles();
168 EXPECT_EQ(all_profiles.size(), 5);
171 for (
int i = 0; i < 5; ++i) {
172 std::string op_name =
"operation_" + std::to_string(i);
173 EXPECT_NE(all_profiles.find(op_name), all_profiles.end());
174 EXPECT_EQ(all_profiles[op_name].total_calls, 1);
175 EXPECT_EQ(all_profiles[op_name].avg_duration_ns, 1000 * (i + 1));
183 for (
int i = 0; i < 10; ++i) {
184 metric_sample sample{
"op", std::chrono::nanoseconds(1000),
true};
190 auto stats_before = collector->get_stats();
191 EXPECT_GT(stats_before.total_samples, 0);
197 auto stats_after = collector->get_stats();
198 EXPECT_EQ(stats_after.total_samples, 0);
199 EXPECT_EQ(stats_after.operation_count, 0);
200 EXPECT_EQ(stats_after.batches_received, 0);