stats.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <inttypes.h>
24 #include <string.h>
25 
26 #include <algorithm>
27 #include <vector>
28 
29 #include "absl/strings/str_format.h"
30 #include "absl/strings/str_join.h"
31 
32 #include <grpc/support/alloc.h>
33 #include <grpc/support/cpu.h>
34 #include <grpc/support/sync.h>
35 
37 static size_t g_num_cores;
39 
40 void grpc_stats_init(void) {
41  gpr_once_init(&g_once, []() {
45  });
46 }
47 
49  memset(output, 0, sizeof(*output));
50  for (size_t core = 0; core < g_num_cores; core++) {
51  for (size_t i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
52  output->counters[i] += gpr_atm_no_barrier_load(
53  &grpc_stats_per_cpu_storage[core].counters[i]);
54  }
55  for (size_t i = 0; i < GRPC_STATS_HISTOGRAM_BUCKETS; i++) {
56  output->histograms[i] += gpr_atm_no_barrier_load(
57  &grpc_stats_per_cpu_storage[core].histograms[i]);
58  }
59  }
60 }
61 
63  grpc_stats_data* c) {
64  for (size_t i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
65  c->counters[i] = b->counters[i] - a->counters[i];
66  }
67  for (size_t i = 0; i < GRPC_STATS_HISTOGRAM_BUCKETS; i++) {
68  c->histograms[i] = b->histograms[i] - a->histograms[i];
69  }
70 }
71 
73  int table_size) {
75  const int* const start = table;
76  while (table_size > 0) {
77  int step = table_size / 2;
78  const int* it = table + step;
79  if (value >= *it) {
80  table = it + 1;
81  table_size -= step + 1;
82  } else {
83  table_size = step;
84  }
85  }
86  return static_cast<int>(table - start) - 1;
87 }
88 
91  size_t sum = 0;
92  for (int i = 0; i < grpc_stats_histo_buckets[histogram]; i++) {
93  sum += static_cast<size_t>(
94  stats->histograms[grpc_stats_histo_start[histogram] + i]);
95  }
96  return sum;
97 }
98 
99 static double threshold_for_count_below(const gpr_atm* bucket_counts,
100  const int* bucket_boundaries,
101  int num_buckets, double count_below) {
102  double count_so_far;
103  double lower_bound;
104  double upper_bound;
105  int lower_idx;
106  int upper_idx;
107 
108  /* find the lowest bucket that gets us above count_below */
109  count_so_far = 0.0;
110  for (lower_idx = 0; lower_idx < num_buckets; lower_idx++) {
111  count_so_far += static_cast<double>(bucket_counts[lower_idx]);
112  if (count_so_far >= count_below) {
113  break;
114  }
115  }
116  if (count_so_far == count_below) {
117  /* this bucket hits the threshold exactly... we should be midway through
118  any run of zero values following the bucket */
119  for (upper_idx = lower_idx + 1; upper_idx < num_buckets; upper_idx++) {
120  if (bucket_counts[upper_idx]) {
121  break;
122  }
123  }
124  return (bucket_boundaries[lower_idx] + bucket_boundaries[upper_idx]) / 2.0;
125  } else {
126  /* treat values as uniform throughout the bucket, and find where this value
127  should lie */
128  lower_bound = bucket_boundaries[lower_idx];
129  upper_bound = bucket_boundaries[lower_idx + 1];
130  return upper_bound - (upper_bound - lower_bound) *
131  (count_so_far - count_below) /
132  static_cast<double>(bucket_counts[lower_idx]);
133  }
134 }
135 
138  double percentile) {
140  if (count == 0) return 0.0;
142  stats->histograms + grpc_stats_histo_start[histogram],
145  static_cast<double>(count) * percentile / 100.0);
146 }
147 
149  std::vector<std::string> parts;
150  parts.push_back("{");
151  for (size_t i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
152  parts.push_back(absl::StrFormat(
153  "\"%s\": %" PRIdPTR, grpc_stats_counter_name[i], data->counters[i]));
154  }
155  for (size_t i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
156  parts.push_back(absl::StrFormat("\"%s\": [", grpc_stats_histogram_name[i]));
157  for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) {
158  parts.push_back(
159  absl::StrFormat("%s%" PRIdPTR, j == 0 ? "" : ",",
160  data->histograms[grpc_stats_histo_start[i] + j]));
161  }
162  parts.push_back(
163  absl::StrFormat("], \"%s_bkt\": [", grpc_stats_histogram_name[i]));
164  for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) {
165  parts.push_back(absl::StrFormat(
166  "%s%d", j == 0 ? "" : ",", grpc_stats_histo_bucket_boundaries[i][j]));
167  }
168  parts.push_back("]");
169  }
170  parts.push_back("}");
171  return absl::StrJoin(parts, "");
172 }
gpr_cpu_num_cores
GPRAPI unsigned gpr_cpu_num_cores(void)
grpc_stats_per_cpu_storage
grpc_stats_data * grpc_stats_per_cpu_storage
Definition: stats.cc:36
gpr_atm_no_barrier_load
#define gpr_atm_no_barrier_load(p)
Definition: impl/codegen/atm_gcc_atomic.h:53
regen-readme.it
it
Definition: regen-readme.py:15
memset
return memset(p, 0, total)
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_stats_histo_buckets
const int grpc_stats_histo_buckets[13]
Definition: stats_data.cc:663
gpr_once
pthread_once_t gpr_once
Definition: impl/codegen/sync_posix.h:50
GRPC_STATS_HISTOGRAM_COUNT
@ GRPC_STATS_HISTOGRAM_COUNT
Definition: stats_data.h:142
grpc::testing::sum
double sum(const T &container, F functor)
Definition: test/cpp/qps/stats.h:30
string.h
grpc_stats_data_as_json
std::string grpc_stats_data_as_json(const grpc_stats_data *data)
Definition: stats.cc:148
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
threshold_for_count_below
static double threshold_for_count_below(const gpr_atm *bucket_counts, const int *bucket_boundaries, int num_buckets, double count_below)
Definition: stats.cc:99
GPR_ONCE_INIT
#define GPR_ONCE_INIT
Definition: impl/codegen/sync_posix.h:52
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
grpc_stats_counter_name
const char * grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT]
Definition: stats_data.cc:30
stats.h
profile_analyzer.percentile
def percentile(N, percent, key=lambda x:x)
Definition: profile_analyzer.py:187
gpr_once_init
GPRAPI void gpr_once_init(gpr_once *once, void(*init_function)(void))
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
g_num_cores
static size_t g_num_cores
Definition: stats.cc:37
grpc_stats_histo_count
size_t grpc_stats_histo_count(const grpc_stats_data *stats, grpc_stats_histograms histogram)
Definition: stats.cc:89
start
static uint64_t start
Definition: benchmark-pound.c:74
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
absl::StrJoin
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
Definition: abseil-cpp/absl/strings/str_join.h:239
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc_stats_init
void grpc_stats_init(void)
Definition: stats.cc:40
grpc_stats_histo_find_bucket_slow
int grpc_stats_histo_find_bucket_slow(int value, const int *table, int table_size)
Definition: stats.cc:72
gen_stats_data.stats
list stats
Definition: gen_stats_data.py:58
histogram
static grpc_histogram * histogram
Definition: test/core/fling/client.cc:34
cpu.h
grpc_stats_histo_start
const int grpc_stats_histo_start[13]
Definition: stats_data.cc:665
g_once
static gpr_once g_once
Definition: stats.cc:38
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
grpc_stats_collect
void grpc_stats_collect(grpc_stats_data *output)
Definition: stats.cc:48
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
grpc_stats_histogram_name
const char * grpc_stats_histogram_name[GRPC_STATS_HISTOGRAM_COUNT]
Definition: stats_data.cc:254
value
const char * value
Definition: hpack_parser_table.cc:165
gpr_atm
intptr_t gpr_atm
Definition: impl/codegen/atm_gcc_atomic.h:32
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
alloc.h
grpc_stats_data
Definition: src/core/lib/debug/stats.h:33
step
static int step
Definition: test-mutexes.c:31
GRPC_STATS_HISTOGRAM_BUCKETS
@ GRPC_STATS_HISTOGRAM_BUCKETS
Definition: stats_data.h:173
grpc_stats_histograms
grpc_stats_histograms
Definition: stats_data.h:128
grpc_stats_histo_percentile
double grpc_stats_histo_percentile(const grpc_stats_data *stats, grpc_stats_histograms histogram, double percentile)
Definition: stats.cc:136
GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS
#define GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS()
Definition: stats_data.h:204
grpc_stats_diff
void grpc_stats_diff(const grpc_stats_data *b, const grpc_stats_data *a, grpc_stats_data *c)
Definition: stats.cc:62
table
uint8_t table[256]
Definition: hpack_parser.cc:456
GRPC_STATS_COUNTER_COUNT
@ GRPC_STATS_COUNTER_COUNT
Definition: stats_data.h:124
sync.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc_stats_histo_bucket_boundaries
const int *const grpc_stats_histo_bucket_boundaries[13]
Definition: stats_data.cc:667
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:22