diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f87beb02b9..db629e8499d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1073,6 +1073,8 @@ add_library(grpc src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/lib/debug/trace.c + src/core/lib/debug/stats.c + src/core/lib/debug/stats_data.c src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c src/core/ext/transport/chttp2/transport/bin_decoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c @@ -1416,6 +1418,8 @@ add_library(grpc_cronet src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/lib/debug/trace.c + src/core/lib/debug/stats.c + src/core/lib/debug/stats_data.c src/core/ext/transport/cronet/client/secure/cronet_channel_create.c src/core/ext/transport/cronet/transport/cronet_api_dummy.c src/core/ext/transport/cronet/transport/cronet_transport.c @@ -1737,6 +1741,8 @@ add_library(grpc_test_util src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/lib/debug/trace.c + src/core/lib/debug/stats.c + src/core/lib/debug/stats_data.c ) if(WIN32 AND MSVC) @@ -2000,6 +2006,8 @@ add_library(grpc_unsecure src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/lib/debug/trace.c + src/core/lib/debug/stats.c + src/core/lib/debug/stats_data.c src/core/ext/transport/chttp2/server/insecure/server_chttp2.c src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c src/core/ext/transport/chttp2/transport/bin_decoder.c @@ -2659,6 +2667,8 @@ add_library(grpc++_cronet src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/lib/debug/trace.c + src/core/lib/debug/stats.c + src/core/lib/debug/stats_data.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/filters/http/client/http_client_filter.c src/core/ext/filters/http/http_filters_plugin.c diff --git a/Makefile b/Makefile index 2ae02297165..d942f94e4a5 100644 --- a/Makefile +++ b/Makefile @@ -3017,6 +3017,8 @@ LIBGRPC_SRC = \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ src/core/ext/transport/chttp2/transport/bin_decoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \ @@ -3358,6 +3360,8 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \ src/core/ext/transport/cronet/transport/cronet_api_dummy.c \ src/core/ext/transport/cronet/transport/cronet_transport.c \ @@ -3676,6 +3680,8 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ PUBLIC_HEADERS_C += \ include/grpc/byte_buffer.h \ @@ -3911,6 +3917,8 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \ src/core/ext/transport/chttp2/transport/bin_decoder.c \ @@ -4554,6 +4562,8 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/filters/http/client/http_client_filter.c \ src/core/ext/filters/http/http_filters_plugin.c \ diff --git a/binding.gyp b/binding.gyp index d11a60a68af..f091850be1d 100644 --- a/binding.gyp +++ b/binding.gyp @@ -762,6 +762,8 @@ 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/lib/debug/trace.c', + 'src/core/lib/debug/stats.c', + 'src/core/lib/debug/stats_data.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c', diff --git a/build.yaml b/build.yaml index 5dac7706147..0811606e409 100644 --- a/build.yaml +++ b/build.yaml @@ -422,6 +422,7 @@ filegroups: uses: - grpc_codegen - grpc_trace + - grpc_stats - name: grpc_client_channel headers: - src/core/ext/filters/client_channel/client_channel.h @@ -679,6 +680,15 @@ filegroups: - src/core/ext/filters/workarounds/workaround_utils.c uses: - grpc_base +- name: grpc_stats + headers: + - src/core/lib/debug/stats.h + - src/core/lib/debug/stats_data.h + src: + - src/core/lib/debug/stats.c + - src/core/lib/debug/stats_data.c + deps: + - gpr - name: grpc_test_util_base build: test headers: diff --git a/config.m4 b/config.m4 index f97baadde4d..9e43a78be59 100644 --- a/config.m4 +++ b/config.m4 @@ -212,6 +212,8 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/lib/debug/trace.c \ + src/core/lib/debug/stats.c \ + src/core/lib/debug/stats_data.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ src/core/ext/transport/chttp2/transport/bin_decoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \ diff --git a/config.w32 b/config.w32 index c00f3f953d4..2dd3b4d3de8 100644 --- a/config.w32 +++ b/config.w32 @@ -189,6 +189,8 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\transport\\transport.c " + "src\\core\\lib\\transport\\transport_op_string.c " + "src\\core\\lib\\debug\\trace.c " + + "src\\core\\lib\\debug\\stats.c " + + "src\\core\\lib\\debug\\stats_data.c " + "src\\core\\ext\\transport\\chttp2\\server\\secure\\server_secure_chttp2.c " + "src\\core\\ext\\transport\\chttp2\\transport\\bin_decoder.c " + "src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.c " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 57b6f92d1e0..4135c6522ed 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -355,6 +355,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/lib/debug/trace.h', + 'src/core/lib/debug/stats.h', + 'src/core/lib/debug/stats_data.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', 'src/core/ext/transport/chttp2/transport/bin_encoder.h', 'src/core/ext/transport/chttp2/transport/chttp2_transport.h', @@ -586,6 +588,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/lib/debug/trace.c', + 'src/core/lib/debug/stats.c', + 'src/core/lib/debug/stats_data.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c', @@ -839,6 +843,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/lib/debug/trace.h', + 'src/core/lib/debug/stats.h', + 'src/core/lib/debug/stats_data.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', 'src/core/ext/transport/chttp2/transport/bin_encoder.h', 'src/core/ext/transport/chttp2/transport/chttp2_transport.h', diff --git a/grpc.gemspec b/grpc.gemspec index dedee020b7d..9c4badb5a6a 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -287,6 +287,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/transport.h ) s.files += %w( src/core/lib/transport/transport_impl.h ) s.files += %w( src/core/lib/debug/trace.h ) + s.files += %w( src/core/lib/debug/stats.h ) + s.files += %w( src/core/lib/debug/stats_data.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.h ) @@ -522,6 +524,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/transport.c ) s.files += %w( src/core/lib/transport/transport_op_string.c ) s.files += %w( src/core/lib/debug/trace.c ) + s.files += %w( src/core/lib/debug/stats.c ) + s.files += %w( src/core/lib/debug/stats_data.c ) s.files += %w( src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.c ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.c ) diff --git a/package.xml b/package.xml index 38f51424e6a..ded7ffc52bd 100644 --- a/package.xml +++ b/package.xml @@ -301,6 +301,8 @@ + + @@ -536,6 +538,8 @@ + + diff --git a/src/core/lib/debug/stats.c b/src/core/lib/debug/stats.c new file mode 100644 index 00000000000..6daf03484a3 --- /dev/null +++ b/src/core/lib/debug/stats.c @@ -0,0 +1,67 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/debug/stats.h" + +#include +#include + +#include +#include +#include + +#include "src/core/lib/support/string.h" + +grpc_stats_data *grpc_stats_per_cpu_storage; +static size_t g_num_cores; + +void grpc_stats_init(void) { + g_num_cores = GPR_MAX(1, gpr_cpu_num_cores()); + grpc_stats_per_cpu_storage = + gpr_zalloc(sizeof(grpc_stats_data) * g_num_cores); +} + +void grpc_stats_shutdown(void) { gpr_free(grpc_stats_per_cpu_storage); } + +void grpc_stats_collect(grpc_stats_data *output) { + memset(output, 0, sizeof(*output)); + for (size_t core = 0; core < g_num_cores; core++) { + for (size_t i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) { + output->counters[i] += gpr_atm_no_barrier_load( + &grpc_stats_per_cpu_storage[core].counters[i]); + } + } +} + +char *grpc_stats_data_as_json(const grpc_stats_data *data) { + gpr_strvec v; + char *tmp; + bool is_first = true; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("{")); + for (size_t i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) { + gpr_asprintf(&tmp, "%s\"%s\": %" PRIdPTR, is_first ? "" : ", ", + grpc_stats_counter_name[i], data->counters[i]); + gpr_strvec_add(&v, tmp); + is_first = false; + } + gpr_strvec_add(&v, gpr_strdup("}")); + tmp = gpr_strvec_flatten(&v, NULL); + gpr_strvec_destroy(&v); + return tmp; +} diff --git a/src/core/lib/debug/stats.h b/src/core/lib/debug/stats.h new file mode 100644 index 00000000000..b30e008e2b1 --- /dev/null +++ b/src/core/lib/debug/stats.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_DEBUG_STATS_H +#define GRPC_CORE_LIB_DEBUG_STATS_H + +#include +#include "src/core/lib/debug/stats_data.h" +#include "src/core/lib/iomgr/exec_ctx.h" + +typedef struct grpc_stats_data { + gpr_atm counters[GRPC_STATS_COUNTER_COUNT]; +} grpc_stats_data; + +extern grpc_stats_data *grpc_stats_per_cpu_storage; + +#define GRPC_THREAD_STATS_DATA(exec_ctx) \ + (&grpc_stats_per_cpu_storage[(exec_ctx)->starting_cpu]) + +#define GRPC_STATS_INC_COUNTER(exec_ctx, ctr) \ + (gpr_atm_no_barrier_fetch_add( \ + &GRPC_THREAD_STATS_DATA((exec_ctx))->counters[(ctr)], 1), \ + 0) + +void grpc_stats_init(void); +void grpc_stats_shutdown(void); +void grpc_stats_collect(grpc_stats_data *output); +char *grpc_stats_data_as_json(const grpc_stats_data *data); + +#endif diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c new file mode 100644 index 00000000000..f2969654ef9 --- /dev/null +++ b/src/core/lib/debug/stats_data.c @@ -0,0 +1,25 @@ +/* + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Automatically generated by tools/codegen/core/gen_stats_data.py + */ + +#include "src/core/lib/debug/stats_data.h" +const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { + "client_calls_created", + "server_calls_created", +}; diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h new file mode 100644 index 00000000000..3107205c44f --- /dev/null +++ b/src/core/lib/debug/stats_data.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Automatically generated by tools/codegen/core/gen_stats_data.py + */ + +#ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H +#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H + +typedef enum { + GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED, + GRPC_STATS_COUNTER_SERVER_CALLS_CREATED, + GRPC_STATS_COUNTER_COUNT +} grpc_stats_counters; +#define GRPC_STATS_INC_CLIENT_CALLS_CREATED(exec_ctx) GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED) +#define GRPC_STATS_INC_SERVER_CALLS_CREATED(exec_ctx) GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SERVER_CALLS_CREATED) +extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT]; + +#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */ diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml new file mode 100644 index 00000000000..3347d9c8ae7 --- /dev/null +++ b/src/core/lib/debug/stats_data.yaml @@ -0,0 +1,5 @@ +# Stats data declaration +# use tools/codegen/core/gen_stats_data.py to turn this into stats_data.h + +- counter: client_calls_created +- counter: server_calls_created diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index a0d2a965d53..c89792c8c4f 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -19,6 +19,7 @@ #ifndef GRPC_CORE_LIB_IOMGR_EXEC_CTX_H #define GRPC_CORE_LIB_IOMGR_EXEC_CTX_H +#include #include "src/core/lib/iomgr/closure.h" /* #define GRPC_EXECUTION_CONTEXT_SANITIZER 1 */ @@ -62,6 +63,7 @@ struct grpc_exec_ctx { /** last active combiner in the active combiner list */ grpc_combiner *last_combiner; uintptr_t flags; + unsigned starting_cpu; void *check_ready_to_finish_arg; bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg); }; @@ -69,7 +71,10 @@ struct grpc_exec_ctx { /* initializer for grpc_exec_ctx: prefer to use GRPC_EXEC_CTX_INIT whenever possible */ #define GRPC_EXEC_CTX_INITIALIZER(flags, finish_check, finish_check_arg) \ - { GRPC_CLOSURE_LIST_INIT, NULL, NULL, flags, finish_check_arg, finish_check } + { \ + GRPC_CLOSURE_LIST_INIT, NULL, NULL, flags, gpr_cpu_current_cpu(), \ + finish_check_arg, finish_check \ + } /* initialize an execution context at the top level of an API call into grpc (this is safe to use elsewhere, though possibly not as efficient) */ diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 2365d27307c..2f42726c7f0 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -32,6 +32,7 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/debug/stats.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -314,6 +315,11 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx, /* Always support no compression */ GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); call->is_client = args->server_transport_data == NULL; + if (call->is_client) { + GRPC_STATS_INC_CLIENT_CALLS_CREATED(exec_ctx); + } else { + GRPC_STATS_INC_SERVER_CALLS_CREATED(exec_ctx); + } call->stream_op_payload.context = call->context; grpc_slice path = grpc_empty_slice(); if (call->is_client) { diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index db111e597f6..822056af5a1 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -28,6 +28,7 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/combiner.h" @@ -117,6 +118,7 @@ void grpc_init(void) { gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { gpr_time_init(); + grpc_stats_init(); grpc_slice_intern_init(); grpc_mdctx_global_init(); grpc_channel_init_init(); @@ -184,6 +186,7 @@ void grpc_shutdown(void) { grpc_mdctx_global_shutdown(&exec_ctx); grpc_handshaker_factory_registry_shutdown(&exec_ctx); grpc_slice_intern_shutdown(); + grpc_stats_shutdown(); } gpr_mu_unlock(&g_init_mu); grpc_exec_ctx_finish(&exec_ctx); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 605044b65e0..1f3a8c8a63a 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -188,6 +188,8 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/lib/debug/trace.c', + 'src/core/lib/debug/stats.c', + 'src/core/lib/debug/stats_data.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c', diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index 7a81133dfa7..82ab0a1cfeb 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -27,6 +27,7 @@ #include #include #include +#include "src/core/lib/debug/stats.h" #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" @@ -102,6 +103,10 @@ static void simple_request_body(grpc_end2end_test_config config, grpc_slice details; int was_cancelled = 2; char *peer; + grpc_stats_data before; + grpc_stats_data after; + + grpc_stats_collect(&before); gpr_timespec deadline = five_seconds_from_now(); c = grpc_channel_create_call( @@ -208,6 +213,23 @@ static void simple_request_body(grpc_end2end_test_config config, grpc_call_unref(s); cq_verifier_destroy(cqv); + + grpc_stats_collect(&after); + + char *stats = grpc_stats_data_as_json(&after); + gpr_log(GPR_DEBUG, "%s", stats); + gpr_free(stats); + + int expected_calls = 1; + if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { + expected_calls *= 2; + } + GPR_ASSERT(after.counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] - + before.counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] == + expected_calls); + GPR_ASSERT(after.counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] - + before.counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] == + expected_calls); } static void test_invoke_simple_request(grpc_end2end_test_config config) { diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py new file mode 100755 index 00000000000..bc601a89a7f --- /dev/null +++ b/tools/codegen/core/gen_stats_data.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python2.7 + +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections +import sys +import yaml + +with open('src/core/lib/debug/stats_data.yaml') as f: + attrs = yaml.load(f.read()) + +Counter = collections.namedtuple('Counter', 'name') + +counters = [] + +for attr in attrs: + if 'counter' in attr: + counters.append(Counter(name=attr['counter'])) + else: + print 'Error: bad attr %r' % attr + +# utility: print a big comment block into a set of files +def put_banner(files, banner): + for f in files: + print >>f, '/*' + for line in banner: + print >>f, ' * %s' % line + print >>f, ' */' + print >>f + +with open('src/core/lib/debug/stats_data.h', 'w') as H: + # copy-paste copyright notice from this file + with open(sys.argv[0]) as my_source: + copyright = [] + for line in my_source: + if line[0] != '#': break + for line in my_source: + if line[0] == '#': + copyright.append(line) + break + for line in my_source: + if line[0] != '#': + break + copyright.append(line) + put_banner([H], [line[2:].rstrip() for line in copyright]) + + put_banner([H], ["Automatically generated by tools/codegen/core/gen_stats_data.py"]) + + print >>H, "#ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H" + print >>H, "#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H" + print >>H + + print >>H, "typedef enum {" + for ctr in counters: + print >>H, " GRPC_STATS_COUNTER_%s," % ctr.name.upper() + print >>H, " GRPC_STATS_COUNTER_COUNT" + print >>H, "} grpc_stats_counters;" + + for ctr in counters: + print >>H, "#define GRPC_STATS_INC_%s(exec_ctx) GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_%s)" % (ctr.name.upper(), ctr.name.upper()) + + print >>H, "extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT];" + + print >>H + print >>H, "#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */" + +with open('src/core/lib/debug/stats_data.c', 'w') as C: + # copy-paste copyright notice from this file + with open(sys.argv[0]) as my_source: + copyright = [] + for line in my_source: + if line[0] != '#': break + for line in my_source: + if line[0] == '#': + copyright.append(line) + break + for line in my_source: + if line[0] != '#': + break + copyright.append(line) + put_banner([C], [line[2:].rstrip() for line in copyright]) + + put_banner([C], ["Automatically generated by tools/codegen/core/gen_stats_data.py"]) + + print >>C, "#include \"src/core/lib/debug/stats_data.h\"" + + print >>C, "const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = {"; + for ctr in counters: + print >>C, " \"%s\"," % ctr.name + print >>C, "};" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 4ad8a0ddb46..2995145fe17 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1073,6 +1073,10 @@ src/core/lib/compression/message_compress.c \ src/core/lib/compression/message_compress.h \ src/core/lib/compression/stream_compression.c \ src/core/lib/compression/stream_compression.h \ +src/core/lib/debug/stats.c \ +src/core/lib/debug/stats.h \ +src/core/lib/debug/stats_data.c \ +src/core/lib/debug/stats_data.h \ src/core/lib/debug/trace.c \ src/core/lib/debug/trace.h \ src/core/lib/http/format_request.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8993e9340ac..bdad9e9d01d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7691,6 +7691,7 @@ "deps": [ "gpr", "grpc_codegen", + "grpc_stats", "grpc_trace" ], "headers": [ @@ -8551,6 +8552,26 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [ + "gpr" + ], + "headers": [ + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.h" + ], + "is_filegroup": true, + "language": "c", + "name": "grpc_stats", + "src": [ + "src/core/lib/debug/stats.c", + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.c", + "src/core/lib/debug/stats_data.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [ "gpr_test_util", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index 41fe1b222b7..6ffb0ac0849 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -412,6 +412,8 @@ + + @@ -776,6 +778,10 @@ + + + + diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index 00b8705826c..ea58322a651 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -382,6 +382,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + src\core\ext\transport\chttp2\server\secure @@ -1193,6 +1199,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + src\core\ext\transport\chttp2\transport diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 32809ca5899..4ba0ef78cf5 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -307,6 +307,8 @@ + + @@ -601,6 +603,10 @@ + + + + diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index def8de42028..fa2a6e3545f 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -439,6 +439,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + @@ -917,6 +923,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index ac98dc05401..7684ed42e2d 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -402,6 +402,8 @@ + + @@ -742,6 +744,10 @@ + + + + diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index fea68c51dc8..93f68e56987 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -385,6 +385,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + src\core\ext\transport\chttp2\server\insecure @@ -1100,6 +1106,12 @@ src\core\lib\debug + + src\core\lib\debug + + + src\core\lib\debug + src\core\ext\transport\chttp2\transport