Merge github.com:grpc/grpc into transport-refs-3

pull/36509/head
Craig Tiller 10 months ago
commit f36b308674
  1. 17
      BUILD
  2. 6
      CMakeLists.txt
  3. 1
      Makefile
  4. 1
      Package.swift
  5. 10
      bazel/experiments.bzl
  6. 7
      build_autogenerated.yaml
  7. 1
      gRPC-C++.podspec
  8. 1
      gRPC-Core.podspec
  9. 1
      grpc.gemspec
  10. 1
      include/grpc/module.modulemap
  11. 62
      include/grpc/passive_listener.h
  12. 6
      include/grpc/support/log.h
  13. 27
      include/grpcpp/passive_listener.h
  14. 1
      include/grpcpp/security/server_credentials.h
  15. 28
      include/grpcpp/server_builder.h
  16. 1
      package.xml
  17. 10
      src/core/BUILD
  18. 7
      src/core/ext/transport/binder/server/binder_server.cc
  19. 7
      src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc
  20. 4
      src/core/ext/transport/chaotic_good/server/chaotic_good_server.h
  21. 296
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  22. 33
      src/core/ext/transport/chttp2/server/chttp2_server.h
  23. 193
      src/core/lib/channel/metrics.cc
  24. 308
      src/core/lib/channel/metrics.h
  25. 7
      src/core/lib/event_engine/extensions/supports_fd.h
  26. 16
      src/core/lib/event_engine/posix_engine/posix_engine.cc
  27. 2
      src/core/lib/event_engine/posix_engine/posix_engine.h
  28. 20
      src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc
  29. 9
      src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h
  30. 2
      src/core/lib/experiments/experiments.cc
  31. 3
      src/core/lib/experiments/experiments.h
  32. 4
      src/core/lib/experiments/rollouts.yaml
  33. 19
      src/core/lib/gpr/android/log.cc
  34. 45
      src/core/lib/gpr/linux/log.cc
  35. 11
      src/core/lib/gpr/log.cc
  36. 42
      src/core/lib/gpr/posix/log.cc
  37. 43
      src/core/lib/gpr/windows/log.cc
  38. 12
      src/core/load_balancing/pick_first/pick_first.cc
  39. 49
      src/core/load_balancing/rls/rls.cc
  40. 31
      src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc
  41. 14
      src/core/server/server.h
  42. 34
      src/core/xds/grpc/xds_client_grpc.cc
  43. 251
      src/cpp/ext/otel/otel_plugin.cc
  44. 20
      src/cpp/ext/otel/otel_plugin.h
  45. 60
      src/cpp/server/server_builder.cc
  46. 28
      templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template
  47. 6
      test/core/address_utils/BUILD
  48. 14
      test/core/address_utils/parse_address_test.cc
  49. 13
      test/core/address_utils/parse_address_with_named_scope_id_test.cc
  50. 15
      test/core/bad_client/bad_client.cc
  51. 7
      test/core/bad_client/generate_tests.bzl
  52. 5
      test/core/bad_connection/BUILD
  53. 14
      test/core/bad_connection/close_fd_test.cc
  54. 1
      test/core/bad_ssl/generate_tests.bzl
  55. 4
      test/core/bad_ssl/server_common.cc
  56. 2
      test/core/channel/BUILD
  57. 6
      test/core/channel/channel_args_test.cc
  58. 547
      test/core/channel/metrics_test.cc
  59. 10
      test/core/compression/BUILD
  60. 10
      test/core/compression/compression_test.cc
  61. 1
      test/core/compression/message_compress_test.cc
  62. 3
      test/core/end2end/tests/http2_stats.cc
  63. 65
      test/core/event_engine/event_engine_test_utils.h
  64. 13
      test/core/load_balancing/pick_first_test.cc
  65. 23
      test/core/load_balancing/weighted_round_robin_test.cc
  66. 52
      test/core/test_util/fake_stats_plugin.cc
  67. 84
      test/core/test_util/fake_stats_plugin.h
  68. 2
      test/cpp/end2end/BUILD
  69. 164
      test/cpp/end2end/client_lb_end2end_test.cc
  70. 113
      test/cpp/end2end/grpclb_end2end_test.cc
  71. 32
      test/cpp/end2end/rls_end2end_test.cc
  72. 6
      test/cpp/end2end/xds/BUILD
  73. 48
      test/cpp/end2end/xds/xds_core_end2end_test.cc
  74. 33
      test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
  75. 84
      test/cpp/end2end/xds/xds_server.h
  76. 8
      test/cpp/end2end/xds/xds_wrr_end2end_test.cc
  77. 5
      test/cpp/ext/csm/metadata_exchange_test.cc
  78. 1
      test/cpp/ext/filters/census/BUILD
  79. 182
      test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
  80. 116
      test/cpp/ext/otel/otel_plugin_test.cc
  81. 2
      test/cpp/interop/BUILD
  82. 40
      test/cpp/interop/grpclb_fallback_test.cc
  83. 33
      test/cpp/interop/http2_client.cc
  84. 5
      test/cpp/qps/BUILD
  85. 55
      test/cpp/qps/driver.cc
  86. 69
      test/cpp/qps/report.cc
  87. 1
      test/cpp/server/BUILD
  88. 55
      test/cpp/server/server_builder_test.cc
  89. 3
      tools/bazelify_tests/dockerimage_current_versions.bzl
  90. 2
      tools/bazelify_tests/test/portability_tests.bzl
  91. 4
      tools/distrib/check_namespace_qualification.py
  92. 9
      tools/distrib/check_redundant_namespace_qualifiers.py
  93. 2
      tools/dockerfile/interoptest/grpc_interop_dart.current_version
  94. 1
      tools/dockerfile/test/cxx_gcc_7_x64.current_version
  95. 79
      tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile
  96. 2
      tools/doxygen/Doxyfile.c++
  97. 2
      tools/doxygen/Doxyfile.c++.internal
  98. 1
      tools/doxygen/Doxyfile.core
  99. 1
      tools/doxygen/Doxyfile.core.internal
  100. 4
      tools/run_tests/sanity/core_banned_functions.py

17
BUILD

@ -296,6 +296,7 @@ GRPC_PUBLIC_HDRS = [
"include/grpc/grpc_posix.h",
"include/grpc/grpc_security.h",
"include/grpc/grpc_security_constants.h",
"include/grpc/passive_listener.h",
"include/grpc/slice.h",
"include/grpc/slice_buffer.h",
"include/grpc/status.h",
@ -457,6 +458,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/impl/service_type.h",
"include/grpcpp/impl/status.h",
"include/grpcpp/impl/sync.h",
"include/grpcpp/passive_listener.h",
"include/grpcpp/resource_quota.h",
"include/grpcpp/security/audit_logging.h",
"include/grpcpp/security/tls_crl_provider.h",
@ -883,7 +885,7 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc_public_hdrs",
hdrs = GRPC_PUBLIC_HDRS,
hdrs = GRPC_PUBLIC_HDRS + GRPC_PUBLIC_EVENT_ENGINE_HDRS,
external_deps = [
"absl/status:statusor",
"absl/strings",
@ -1134,6 +1136,7 @@ grpc_cc_library(
"absl/functional:any_invocable",
"absl/hash",
"absl/log:check",
"absl/log:log",
"absl/memory",
"absl/meta:type_traits",
"absl/status",
@ -1643,6 +1646,7 @@ grpc_cc_library(
"absl/container:flat_hash_set",
"absl/functional:any_invocable",
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -2012,6 +2016,7 @@ grpc_cc_library(
"absl/functional:any_invocable",
"absl/functional:function_ref",
"absl/log:check",
"absl/log:log",
"absl/meta:type_traits",
"absl/status",
"absl/status:statusor",
@ -2508,6 +2513,7 @@ grpc_cc_library(
"//src/core:grpc_backend_metric_provider",
"//src/core:grpc_crl_provider",
"//src/core:grpc_service_config",
"//src/core:grpc_transport_chttp2_server",
"//src/core:grpc_transport_inproc",
"//src/core:json",
"//src/core:json_reader",
@ -2566,6 +2572,7 @@ grpc_cc_library(
"grpc_security_base",
"grpc_service_config_impl",
"grpc_trace",
"grpc_transport_chttp2",
"grpc_unsecure",
"grpcpp_backend_metric_recorder",
"grpcpp_call_metric_recorder",
@ -2587,6 +2594,7 @@ grpc_cc_library(
"//src/core:grpc_backend_metric_provider",
"//src/core:grpc_insecure_credentials",
"//src/core:grpc_service_config",
"//src/core:grpc_transport_chttp2_server",
"//src/core:grpc_transport_inproc",
"//src/core:ref_counted",
"//src/core:resource_quota",
@ -2689,6 +2697,7 @@ grpc_cc_library(
],
external_deps = [
"absl/base:core_headers",
"absl/log:log",
"absl/strings",
],
language = "c++",
@ -3667,6 +3676,7 @@ grpc_cc_library(
"absl/container:inlined_vector",
"absl/functional:any_invocable",
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -3990,6 +4000,7 @@ grpc_cc_library(
],
external_deps = [
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -4082,6 +4093,7 @@ grpc_cc_library(
],
external_deps = [
"absl/log:check",
"absl/log:log",
"absl/strings",
"@com_google_protobuf//upb:base",
"@com_google_protobuf//upb:mem",
@ -4204,6 +4216,7 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -4337,6 +4350,7 @@ grpc_cc_library(
"absl/base:core_headers",
"absl/cleanup",
"absl/log:check",
"absl/log:log",
"absl/memory",
"absl/status",
"absl/status:statusor",
@ -4714,6 +4728,7 @@ grpc_cc_library(
"absl/container:flat_hash_map",
"absl/hash",
"absl/log:check",
"absl/log:log",
"absl/meta:type_traits",
"absl/random",
"absl/random:bit_gen_ref",

6
CMakeLists.txt generated

@ -2747,6 +2747,7 @@ foreach(_hdr
include/grpc/impl/propagation_bits.h
include/grpc/impl/slice_type.h
include/grpc/load_reporting.h
include/grpc/passive_listener.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -3448,6 +3449,7 @@ foreach(_hdr
include/grpc/impl/propagation_bits.h
include/grpc/impl/slice_type.h
include/grpc/load_reporting.h
include/grpc/passive_listener.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -4316,6 +4318,7 @@ foreach(_hdr
include/grpcpp/impl/service_type.h
include/grpcpp/impl/status.h
include/grpcpp/impl/sync.h
include/grpcpp/passive_listener.h
include/grpcpp/resource_quota.h
include/grpcpp/security/audit_logging.h
include/grpcpp/security/auth_context.h
@ -5056,6 +5059,7 @@ foreach(_hdr
include/grpcpp/impl/service_type.h
include/grpcpp/impl/status.h
include/grpcpp/impl/sync.h
include/grpcpp/passive_listener.h
include/grpcpp/resource_quota.h
include/grpcpp/security/audit_logging.h
include/grpcpp/security/auth_context.h
@ -5507,6 +5511,7 @@ foreach(_hdr
include/grpc/impl/propagation_bits.h
include/grpc/impl/slice_type.h
include/grpc/load_reporting.h
include/grpc/passive_listener.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -26836,6 +26841,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h
test/core/event_engine/event_engine_test_utils.cc
test/core/test_util/cmdline.cc
test/core/test_util/fuzzer_util.cc
test/core/test_util/grpc_profiler.cc

1
Makefile generated

@ -1776,6 +1776,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/propagation_bits.h \
include/grpc/impl/slice_type.h \
include/grpc/load_reporting.h \
include/grpc/passive_listener.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \

1
Package.swift generated

@ -93,6 +93,7 @@ let package = Package(
"include/grpc/impl/propagation_bits.h",
"include/grpc/impl/slice_type.h",
"include/grpc/load_reporting.h",
"include/grpc/passive_listener.h",
"include/grpc/slice.h",
"include/grpc/slice_buffer.h",
"include/grpc/status.h",

@ -58,16 +58,10 @@ EXPERIMENTS = {
"dbg": {
},
"off": {
"core_end2end_test": [
"event_engine_client",
],
"endpoint_test": [
"tcp_frame_size_tuning",
"tcp_rcv_lowat",
],
"event_engine_client_test": [
"event_engine_client",
],
"flow_control_test": [
"multiping",
"peer_state_based_framing",
@ -82,11 +76,15 @@ EXPERIMENTS = {
},
"on": {
"core_end2end_test": [
"event_engine_client",
"event_engine_listener",
],
"cpp_lb_end2end_test": [
"pick_first_new",
],
"event_engine_client_test": [
"event_engine_client",
],
"event_engine_listener_test": [
"event_engine_listener",
],

@ -198,6 +198,7 @@ libs:
- include/grpc/impl/propagation_bits.h
- include/grpc/impl/slice_type.h
- include/grpc/load_reporting.h
- include/grpc/passive_listener.h
- include/grpc/slice.h
- include/grpc/slice_buffer.h
- include/grpc/status.h
@ -2185,6 +2186,7 @@ libs:
- include/grpc/impl/propagation_bits.h
- include/grpc/impl/slice_type.h
- include/grpc/load_reporting.h
- include/grpc/passive_listener.h
- include/grpc/slice.h
- include/grpc/slice_buffer.h
- include/grpc/status.h
@ -3792,6 +3794,7 @@ libs:
- include/grpcpp/impl/service_type.h
- include/grpcpp/impl/status.h
- include/grpcpp/impl/sync.h
- include/grpcpp/passive_listener.h
- include/grpcpp/resource_quota.h
- include/grpcpp/security/audit_logging.h
- include/grpcpp/security/auth_context.h
@ -4219,6 +4222,7 @@ libs:
- include/grpcpp/impl/service_type.h
- include/grpcpp/impl/status.h
- include/grpcpp/impl/sync.h
- include/grpcpp/passive_listener.h
- include/grpcpp/resource_quota.h
- include/grpcpp/security/audit_logging.h
- include/grpcpp/security/auth_context.h
@ -4367,6 +4371,7 @@ libs:
- include/grpc/impl/propagation_bits.h
- include/grpc/impl/slice_type.h
- include/grpc/load_reporting.h
- include/grpc/passive_listener.h
- include/grpc/slice.h
- include/grpc/slice_buffer.h
- include/grpc/status.h
@ -17793,6 +17798,7 @@ targets:
build: test
language: c++
headers:
- test/core/event_engine/event_engine_test_utils.h
- test/core/test_util/cmdline.h
- test/core/test_util/evaluate_args_test_util.h
- test/core/test_util/fuzzer_util.h
@ -17808,6 +17814,7 @@ targets:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- src/proto/grpc/testing/xds/v3/orca_load_report.proto
- test/core/event_engine/event_engine_test_utils.cc
- test/core/test_util/cmdline.cc
- test/core/test_util/fuzzer_util.cc
- test/core/test_util/grpc_profiler.cc

1
gRPC-C++.podspec generated

@ -176,6 +176,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/service_type.h',
'include/grpcpp/impl/status.h',
'include/grpcpp/impl/sync.h',
'include/grpcpp/passive_listener.h',
'include/grpcpp/resource_quota.h',
'include/grpcpp/security/audit_logging.h',
'include/grpcpp/security/auth_context.h',

1
gRPC-Core.podspec generated

@ -168,6 +168,7 @@ Pod::Spec.new do |s|
'include/grpc/impl/propagation_bits.h',
'include/grpc/impl/slice_type.h',
'include/grpc/load_reporting.h',
'include/grpc/passive_listener.h',
'include/grpc/slice.h',
'include/grpc/slice_buffer.h',
'include/grpc/status.h',

1
grpc.gemspec generated

@ -99,6 +99,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/propagation_bits.h )
s.files += %w( include/grpc/impl/slice_type.h )
s.files += %w( include/grpc/load_reporting.h )
s.files += %w( include/grpc/passive_listener.h )
s.files += %w( include/grpc/slice.h )
s.files += %w( include/grpc/slice_buffer.h )
s.files += %w( include/grpc/status.h )

@ -38,6 +38,7 @@ header "byte_buffer.h"
header "impl/propagation_bits.h"
header "impl/slice_type.h"
header "load_reporting.h"
header "passive_listener.h"
header "slice.h"
header "slice_buffer.h"
header "status.h"

@ -0,0 +1,62 @@
// Copyright 2024 The 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_PASSIVE_LISTENER_H
#define GRPC_PASSIVE_LISTENER_H
#include <memory>
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
// #include <grpc/support/port_platform.h>
namespace grpc_core {
class Server;
namespace experimental {
class PassiveListenerImpl;
/// -- EXPERIMENTAL API --
/// Interface for used for Server Endpoint injection.
class PassiveListener {
public:
virtual ~PassiveListener() = default;
/// -- EXPERIMENTAL API --
///
/// Takes an Endpoint for an established connection, and treats it as if the
/// connection had been accepted by the server.
///
/// The server must be started before endpoints can be accepted.
virtual absl::Status AcceptConnectedEndpoint(
std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
endpoint) = 0;
/// -- EXPERIMENTAL API --
///
/// Takes a connected file descriptor, and treats it as if the server had
/// accepted the connection itself.
///
/// Returns a failure status if the server's active EventEngine does not
/// support Endpoint creation from fds.
virtual absl::Status AcceptConnectedFd(int fd) = 0;
};
} // namespace experimental
} // namespace grpc_core
absl::Status grpc_server_add_passive_listener(
grpc_core::Server* server, grpc_server_credentials* credentials,
std::shared_ptr<grpc_core::experimental::PassiveListenerImpl>
passive_listener);
#endif /* GRPC_PASSIVE_LISTENER_H */

@ -99,12 +99,6 @@ GPRAPI void gpr_assertion_failed(const char* filename, int line,
} \
} while (0)
#ifndef NDEBUG
#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x)
#else
#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(true || (x))
#endif
#ifdef __cplusplus
}
#endif

@ -0,0 +1,27 @@
// Copyright 2024 The 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 GRPCPP_PASSIVE_LISTENER_H
#define GRPCPP_PASSIVE_LISTENER_H
#include <grpc/passive_listener.h>
namespace grpc {
namespace experimental {
using grpc_core::experimental::PassiveListener;
} // namespace experimental
} // namespace grpc
#endif // GRPCPP_PASSIVE_LISTENER_H

@ -84,6 +84,7 @@ class ServerCredentials : private grpc::internal::GrpcLibrary {
// Needed for access to AddPortToServer.
friend class Server;
// Needed for access to c_creds_.
friend class ServerBuilder;
friend std::shared_ptr<ServerCredentials> grpc::XdsServerCredentials(
const std::shared_ptr<ServerCredentials>& fallback_credentials);

@ -25,13 +25,17 @@
#include <vector>
#include <grpc/compression.h>
#include <grpc/event_engine/event_engine.h>
#include <grpc/passive_listener.h>
#include <grpc/support/cpu.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/workaround_list.h>
#include <grpcpp/impl/channel_argument_option.h>
#include <grpcpp/impl/server_builder_option.h>
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/passive_listener.h>
#include <grpcpp/security/authorization_policy_provider.h>
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/server.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/server_interceptor.h>
@ -291,6 +295,18 @@ class ServerBuilder {
void EnableCallMetricRecording(
experimental::ServerMetricRecorder* server_metric_recorder = nullptr);
// Creates a passive listener for Server Endpoint injection.
///
/// \a PasiveListener lets applications provide pre-established connections
/// to gRPC Servers. The server will behave as if it accepted the connection
/// itself on its own listening addresses.
///
/// This can be called multiple times to create passive listeners with
/// different server credentials.
ServerBuilder& AddPassiveListener(
std::shared_ptr<grpc::ServerCredentials> creds,
std::unique_ptr<grpc::experimental::PassiveListener>& passive_listener);
private:
ServerBuilder* builder_;
};
@ -364,6 +380,17 @@ class ServerBuilder {
private:
friend class grpc::testing::ServerBuilderPluginTest;
struct UnstartedPassiveListener {
std::weak_ptr<grpc_core::experimental::PassiveListenerImpl>
passive_listener;
std::shared_ptr<grpc::ServerCredentials> credentials;
UnstartedPassiveListener(
std::weak_ptr<grpc_core::experimental::PassiveListenerImpl> listener,
std::shared_ptr<grpc::ServerCredentials> creds)
: passive_listener(std::move(listener)),
credentials(std::move(creds)) {}
};
struct SyncServerSettings {
SyncServerSettings()
: num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {}
@ -388,6 +415,7 @@ class ServerBuilder {
std::vector<std::unique_ptr<grpc::ServerBuilderOption>> options_;
std::vector<std::unique_ptr<NamedService>> services_;
std::vector<Port> ports_;
std::vector<UnstartedPassiveListener> unstarted_passive_listeners_;
SyncServerSettings sync_server_settings_;

1
package.xml generated

@ -81,6 +81,7 @@
<file baseinstalldir="/" name="include/grpc/impl/propagation_bits.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/slice_type.h" role="src" />
<file baseinstalldir="/" name="include/grpc/load_reporting.h" role="src" />
<file baseinstalldir="/" name="include/grpc/passive_listener.h" role="src" />
<file baseinstalldir="/" name="include/grpc/slice.h" role="src" />
<file baseinstalldir="/" name="include/grpc/slice_buffer.h" role="src" />
<file baseinstalldir="/" name="include/grpc/status.h" role="src" />

@ -754,6 +754,7 @@ grpc_cc_library(
name = "join_state",
external_deps = [
"absl/log:check",
"absl/log:log",
],
language = "c++",
public_hdrs = [
@ -843,6 +844,7 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/log:check",
"absl/log:log",
"absl/strings",
],
language = "c++",
@ -4827,6 +4829,7 @@ grpc_cc_library(
"absl/container:inlined_vector",
"absl/functional:function_ref",
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -4944,6 +4947,7 @@ grpc_cc_library(
"absl/base:core_headers",
"absl/hash",
"absl/log:check",
"absl/log:log",
"absl/random",
"absl/status",
"absl/status:statusor",
@ -5646,6 +5650,7 @@ grpc_cc_library(
external_deps = [
"absl/algorithm:container",
"absl/log:check",
"absl/log:log",
"absl/random",
"absl/status",
"absl/status:statusor",
@ -5870,6 +5875,7 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/log:check",
"absl/log:log",
"absl/meta:type_traits",
"absl/random",
"absl/status",
@ -5940,6 +5946,7 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/log:check",
"absl/log:log",
"absl/meta:type_traits",
"absl/random",
"absl/status",
@ -6086,6 +6093,7 @@ grpc_cc_library(
"absl/base:core_headers",
"absl/functional:function_ref",
"absl/log:check",
"absl/log:log",
"absl/status",
"absl/status:statusor",
"absl/strings",
@ -6894,6 +6902,8 @@ grpc_cc_library(
"connection_quota",
"error",
"error_utils",
"event_engine_extensions",
"event_engine_query_extensions",
"grpc_insecure_credentials",
"handshaker_registry",
"iomgr_fwd",

@ -160,7 +160,7 @@ class BinderServerListener : public Server::ListenerInterface {
on_destroy_done_ = on_destroy_done;
}
void Orphan() override { delete this; }
void Orphan() override { Unref(); }
~BinderServerListener() override {
ExecCtx::Get()->Flush();
@ -240,9 +240,8 @@ bool AddBinderPort(const std::string& addr, grpc_server* server,
}
std::string conn_id = addr.substr(kBinderUriScheme.size());
Server* core_server = Server::FromC(server);
core_server->AddListener(
OrphanablePtr<Server::ListenerInterface>(new BinderServerListener(
core_server, conn_id, std::move(factory), security_policy)));
core_server->AddListener(MakeOrphanable<BinderServerListener>(
core_server, conn_id, std::move(factory), security_policy));
return true;
}

@ -103,8 +103,8 @@ absl::StatusOr<int> ChaoticGoodServerListener::Bind(
str.ok() ? str->c_str() : str.status().ToString().c_str());
}
EventEngine::Listener::AcceptCallback accept_cb =
[self = Ref()](std::unique_ptr<EventEngine::Endpoint> ep,
MemoryAllocator) {
[self = RefAsSubclass<ChaoticGoodServerListener>()](
std::unique_ptr<EventEngine::Endpoint> ep, MemoryAllocator) {
ExecCtx exec_ctx;
MutexLock lock(&self->mu_);
if (self->shutdown_) return;
@ -149,7 +149,8 @@ absl::Status ChaoticGoodServerListener::StartListening() {
ChaoticGoodServerListener::ActiveConnection::ActiveConnection(
RefCountedPtr<ChaoticGoodServerListener> listener,
std::unique_ptr<EventEngine::Endpoint> endpoint)
: memory_allocator_(listener->memory_allocator_), listener_(listener) {
: memory_allocator_(listener->memory_allocator_),
listener_(std::move(listener)) {
handshaking_state_ = MakeRefCounted<HandshakingState>(Ref());
handshaking_state_->Start(std::move(endpoint));
}

@ -49,9 +49,7 @@
namespace grpc_core {
namespace chaotic_good {
class ChaoticGoodServerListener final
: public Server::ListenerInterface,
public RefCounted<ChaoticGoodServerListener> {
class ChaoticGoodServerListener final : public Server::ListenerInterface {
public:
static absl::AnyInvocable<std::string()> DefaultConnectionIDGenerator() {
return [bitgen = absl::BitGen()]() mutable {

@ -42,6 +42,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_posix.h>
#include <grpc/impl/channel_arg_names.h>
#include <grpc/passive_listener.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -58,6 +59,8 @@
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/event_engine/channel_args_endpoint_config.h"
#include "src/core/lib/event_engine/extensions/supports_fd.h"
#include "src/core/lib/event_engine/query_extensions.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -67,6 +70,7 @@
#include "src/core/lib/gprpp/unique_type_name.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/event_engine_shims/endpoint.h"
#include "src/core/lib/iomgr/iomgr_fwd.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resolve_address.h"
@ -93,9 +97,11 @@
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
namespace grpc_core {
namespace {
using ::grpc_event_engine::experimental::EventEngine;
using grpc_event_engine::experimental::ChannelArgsEndpointConfig;
using grpc_event_engine::experimental::EventEngine;
using grpc_event_engine::experimental::EventEngineSupportsFdExtension;
using grpc_event_engine::experimental::QueryExtension;
const char kUnixUriPrefix[] = "unix:";
const char kUnixAbstractUriPrefix[] = "unix-abstract:";
@ -112,14 +118,23 @@ class Chttp2ServerListener : public Server::ListenerInterface {
Server* server, const char* name, const ChannelArgs& args,
Chttp2ServerArgsModifier args_modifier);
static Chttp2ServerListener* CreateForPassiveListener(
Server* server, const ChannelArgs& args,
std::shared_ptr<experimental::PassiveListenerImpl> passive_listener);
// Do not instantiate directly. Use one of the factory methods above.
Chttp2ServerListener(Server* server, const ChannelArgs& args,
Chttp2ServerArgsModifier args_modifier);
Chttp2ServerArgsModifier args_modifier,
grpc_server_config_fetcher* config_fetcher,
std::shared_ptr<experimental::PassiveListenerImpl>
passive_listener = nullptr);
~Chttp2ServerListener() override;
void Start(Server* server,
const std::vector<grpc_pollset*>* pollsets) override;
void AcceptConnectedEndpoint(std::unique_ptr<EventEngine::Endpoint> endpoint);
channelz::ListenSocketNode* channelz_listen_socket_node() const override {
return channelz_listen_socket_.get();
}
@ -129,6 +144,8 @@ class Chttp2ServerListener : public Server::ListenerInterface {
void Orphan() override;
private:
friend class experimental::PassiveListenerImpl;
class ConfigFetcherWatcher
: public grpc_server_config_fetcher::WatcherInterface {
public:
@ -235,34 +252,8 @@ class Chttp2ServerListener : public Server::ListenerInterface {
static void DestroyListener(Server* /*server*/, void* arg,
grpc_closure* destroy_done);
// The interface required by RefCountedPtr<> has been manually implemented
// here to take a ref on tcp_server_ instead. Note that, the handshaker
// needs tcp_server_ to exist for the lifetime of the handshake since it's
// needed by acceptor. Sharing refs between the listener and tcp_server_ is
// just an optimization to avoid taking additional refs on the listener,
// since TcpServerShutdownComplete already holds a ref to the listener.
void IncrementRefCount() { grpc_tcp_server_ref(tcp_server_); }
void IncrementRefCount(const DebugLocation& /* location */,
const char* /* reason */) {
IncrementRefCount();
}
GRPC_MUST_USE_RESULT RefCountedPtr<Chttp2ServerListener> Ref() {
IncrementRefCount();
return RefCountedPtr<Chttp2ServerListener>(this);
}
GRPC_MUST_USE_RESULT RefCountedPtr<Chttp2ServerListener> Ref(
const DebugLocation& /* location */, const char* /* reason */) {
return Ref();
}
void Unref() { grpc_tcp_server_unref(tcp_server_); }
void Unref(const DebugLocation& /* location */, const char* /* reason */) {
Unref();
}
Server* const server_;
grpc_tcp_server* tcp_server_;
Server* const server_ = nullptr;
grpc_tcp_server* tcp_server_ = nullptr;
grpc_resolved_address resolved_address_;
Chttp2ServerArgsModifier const args_modifier_;
ConfigFetcherWatcher* config_fetcher_watcher_ = nullptr;
@ -285,6 +276,10 @@ class Chttp2ServerListener : public Server::ListenerInterface {
RefCountedPtr<channelz::ListenSocketNode> channelz_listen_socket_;
MemoryQuotaRefPtr memory_quota_;
ConnectionQuotaRefPtr connection_quota_;
grpc_server_config_fetcher* config_fetcher_ = nullptr;
// TODO(yashykt): consider using absl::variant<> to minimize memory usage for
// disjoint cases where different fields are used.
std::shared_ptr<experimental::PassiveListenerImpl> passive_listener_;
};
//
@ -381,13 +376,17 @@ Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState(
handshake_mgr_(MakeRefCounted<HandshakeManager>()),
deadline_(GetConnectionDeadline(args)),
interested_parties_(grpc_pollset_set_create()) {
grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_);
if (accepting_pollset != nullptr) {
grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_);
}
CoreConfiguration::Get().handshaker_registry().AddHandshakers(
HANDSHAKER_SERVER, args, interested_parties_, handshake_mgr_.get());
}
Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() {
grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_);
if (accepting_pollset_ != nullptr) {
grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_);
}
grpc_pollset_set_destroy(interested_parties_);
gpr_free(acceptor_);
}
@ -589,7 +588,11 @@ Chttp2ServerListener::ActiveConnection::ActiveConnection(
grpc_schedule_on_exec_ctx);
}
Chttp2ServerListener::ActiveConnection::~ActiveConnection() {}
Chttp2ServerListener::ActiveConnection::~ActiveConnection() {
if (listener_ != nullptr && listener_->tcp_server_ != nullptr) {
grpc_tcp_server_unref(listener_->tcp_server_);
}
}
void Chttp2ServerListener::ActiveConnection::Orphan() {
OrphanablePtr<HandshakingState> handshaking_state;
@ -637,6 +640,9 @@ void Chttp2ServerListener::ActiveConnection::Start(
const ChannelArgs& args) {
RefCountedPtr<HandshakingState> handshaking_state_ref;
listener_ = std::move(listener);
if (listener_->tcp_server_ != nullptr) {
grpc_tcp_server_ref(listener_->tcp_server_);
}
{
ReleasableMutexLock lock(&mu_);
if (shutdown_) {
@ -709,83 +715,82 @@ void Chttp2ServerListener::ActiveConnection::OnDrainGraceTimeExpiry() {
grpc_error_handle Chttp2ServerListener::Create(
Server* server, grpc_resolved_address* addr, const ChannelArgs& args,
Chttp2ServerArgsModifier args_modifier, int* port_num) {
Chttp2ServerListener* listener = nullptr;
// The bulk of this method is inside of a lambda to make cleanup
// easier without using goto.
grpc_error_handle error = [&]() {
grpc_error_handle error;
// Create Chttp2ServerListener.
listener = new Chttp2ServerListener(server, args, args_modifier);
error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_,
grpc_event_engine::experimental::ChannelArgsEndpointConfig(args),
OnAccept, listener, &listener->tcp_server_);
// Create Chttp2ServerListener.
OrphanablePtr<Chttp2ServerListener> listener =
MakeOrphanable<Chttp2ServerListener>(server, args, args_modifier,
server->config_fetcher());
// The tcp_server will be unreffed when the listener is orphaned, which could
// be at the end of this function if the listener was not added to the
// server's set of listeners.
grpc_error_handle error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args),
OnAccept, listener.get(), &listener->tcp_server_);
if (!error.ok()) return error;
if (listener->config_fetcher_ != nullptr) {
listener->resolved_address_ = *addr;
// TODO(yashykt): Consider binding so as to be able to return the port
// number.
} else {
error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num);
if (!error.ok()) return error;
if (server->config_fetcher() != nullptr) {
listener->resolved_address_ = *addr;
// TODO(yashykt): Consider binding so as to be able to return the port
// number.
} else {
error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num);
if (!error.ok()) return error;
}
// Create channelz node.
if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
.value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) {
auto string_address = grpc_sockaddr_to_uri(addr);
if (!string_address.ok()) {
return GRPC_ERROR_CREATE(string_address.status().ToString());
}
listener->channelz_listen_socket_ =
MakeRefCounted<channelz::ListenSocketNode>(
*string_address,
absl::StrCat("chttp2 listener ", *string_address));
}
// Register with the server only upon success
server->AddListener(OrphanablePtr<Server::ListenerInterface>(listener));
return absl::OkStatus();
}();
if (!error.ok()) {
if (listener != nullptr) {
if (listener->tcp_server_ != nullptr) {
// listener is deleted when tcp_server_ is shutdown.
grpc_tcp_server_unref(listener->tcp_server_);
} else {
delete listener;
}
}
// Create channelz node.
if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
.value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) {
auto string_address = grpc_sockaddr_to_uri(addr);
if (!string_address.ok()) {
return GRPC_ERROR_CREATE(string_address.status().ToString());
}
listener->channelz_listen_socket_ =
MakeRefCounted<channelz::ListenSocketNode>(
*string_address, absl::StrCat("chttp2 listener ", *string_address));
}
return error;
// Register with the server only upon success
server->AddListener(std::move(listener));
return absl::OkStatus();
}
grpc_error_handle Chttp2ServerListener::CreateWithAcceptor(
Server* server, const char* name, const ChannelArgs& args,
Chttp2ServerArgsModifier args_modifier) {
Chttp2ServerListener* listener =
new Chttp2ServerListener(server, args, args_modifier);
auto listener = MakeOrphanable<Chttp2ServerListener>(
server, args, args_modifier, server->config_fetcher());
grpc_error_handle error = grpc_tcp_server_create(
&listener->tcp_server_shutdown_complete_,
grpc_event_engine::experimental::ChannelArgsEndpointConfig(args),
OnAccept, listener, &listener->tcp_server_);
if (!error.ok()) {
delete listener;
return error;
}
&listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args),
OnAccept, listener.get(), &listener->tcp_server_);
if (!error.ok()) return error;
// TODO(yangg) channelz
TcpServerFdHandler** arg_val = args.GetPointer<TcpServerFdHandler*>(name);
*arg_val = grpc_tcp_server_create_fd_handler(listener->tcp_server_);
server->AddListener(OrphanablePtr<Server::ListenerInterface>(listener));
server->AddListener(std::move(listener));
return absl::OkStatus();
}
Chttp2ServerListener* Chttp2ServerListener::CreateForPassiveListener(
Server* server, const ChannelArgs& args,
std::shared_ptr<experimental::PassiveListenerImpl> passive_listener) {
// TODO(hork): figure out how to handle channelz in this case
auto listener = MakeOrphanable<Chttp2ServerListener>(
server, args, /*args_modifier=*/
[](const ChannelArgs& args, grpc_error_handle*) { return args; }, nullptr,
std::move(passive_listener));
auto listener_ptr = listener.get();
server->AddListener(std::move(listener));
return listener_ptr;
}
Chttp2ServerListener::Chttp2ServerListener(
Server* server, const ChannelArgs& args,
Chttp2ServerArgsModifier args_modifier)
Chttp2ServerArgsModifier args_modifier,
grpc_server_config_fetcher* config_fetcher,
std::shared_ptr<experimental::PassiveListenerImpl> passive_listener)
: server_(server),
args_modifier_(args_modifier),
args_(args),
memory_quota_(args.GetObject<ResourceQuota>()->memory_quota()),
connection_quota_(MakeRefCounted<ConnectionQuota>()) {
connection_quota_(MakeRefCounted<ConnectionQuota>()),
config_fetcher_(config_fetcher),
passive_listener_(std::move(passive_listener)) {
auto max_allowed_incoming_connections =
args.GetInt(GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS);
if (max_allowed_incoming_connections.has_value()) {
@ -800,6 +805,9 @@ Chttp2ServerListener::~Chttp2ServerListener() {
// Flush queued work before destroying handshaker factory, since that
// may do a synchronous unref.
ExecCtx::Get()->Flush();
if (passive_listener_ != nullptr) {
passive_listener_->ListenerDestroyed();
}
if (on_destroy_done_ != nullptr) {
ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, absl::OkStatus());
ExecCtx::Get()->Flush();
@ -809,10 +817,11 @@ Chttp2ServerListener::~Chttp2ServerListener() {
// Server callback: start listening on our ports
void Chttp2ServerListener::Start(
Server* /*server*/, const std::vector<grpc_pollset*>* /* pollsets */) {
if (server_->config_fetcher() != nullptr) {
auto watcher = std::make_unique<ConfigFetcherWatcher>(Ref());
if (config_fetcher_ != nullptr) {
auto watcher = std::make_unique<ConfigFetcherWatcher>(
RefAsSubclass<Chttp2ServerListener>());
config_fetcher_watcher_ = watcher.get();
server_->config_fetcher()->StartWatch(
config_fetcher_->StartWatch(
grpc_sockaddr_to_string(&resolved_address_, false).value(),
std::move(watcher));
} else {
@ -826,7 +835,9 @@ void Chttp2ServerListener::Start(
}
void Chttp2ServerListener::StartListening() {
grpc_tcp_server_start(tcp_server_, &server_->pollsets());
if (tcp_server_ != nullptr) {
grpc_tcp_server_start(tcp_server_, &server_->pollsets());
}
}
void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
@ -834,6 +845,12 @@ void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
on_destroy_done_ = on_destroy_done;
}
void Chttp2ServerListener::AcceptConnectedEndpoint(
std::unique_ptr<EventEngine::Endpoint> endpoint) {
OnAccept(this, grpc_event_engine_endpoint_create(std::move(endpoint)),
/*accepting_pollset=*/nullptr, /*acceptor=*/nullptr);
}
void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor) {
@ -858,7 +875,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
endpoint_cleanup(error);
return;
}
if (self->server_->config_fetcher() != nullptr) {
if (self->config_fetcher_ != nullptr) {
if (connection_manager == nullptr) {
grpc_error_handle error = GRPC_ERROR_CREATE(
"No ConnectionManager configured. Closing connection.");
@ -899,7 +916,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
// heap-use-after-free issues where `Ref()` is invoked when the ref of
// tcp_server_ has already reached 0. (Ref() implementation of
// Chttp2ServerListener is grpc_tcp_server_ref().)
listener_ref = self->Ref();
listener_ref = self->RefAsSubclass<Chttp2ServerListener>();
self->connections_.emplace(connection.get(), std::move(connection));
}
}
@ -914,7 +931,7 @@ void Chttp2ServerListener::TcpServerShutdownComplete(
void* arg, grpc_error_handle /*error*/) {
Chttp2ServerListener* self = static_cast<Chttp2ServerListener*>(arg);
self->channelz_listen_socket_.reset();
delete self;
self->Unref();
}
// Server callback: destroy the tcp listener (so we don't generate further
@ -923,7 +940,8 @@ void Chttp2ServerListener::Orphan() {
// Cancel the watch before shutting down so as to avoid holding a ref to the
// listener in the watcher.
if (config_fetcher_watcher_ != nullptr) {
server_->config_fetcher()->CancelWatch(config_fetcher_watcher_);
CHECK_NE(config_fetcher_, nullptr);
config_fetcher_->CancelWatch(config_fetcher_watcher_);
}
std::map<ActiveConnection*, OrphanablePtr<ActiveConnection>> connections;
grpc_tcp_server* tcp_server;
@ -941,12 +959,14 @@ void Chttp2ServerListener::Orphan() {
}
tcp_server = tcp_server_;
}
grpc_tcp_server_shutdown_listeners(tcp_server);
grpc_tcp_server_unref(tcp_server);
if (tcp_server != nullptr) {
grpc_tcp_server_shutdown_listeners(tcp_server);
grpc_tcp_server_unref(tcp_server);
} else {
Unref();
}
}
} // namespace
//
// Chttp2ServerAddPort()
//
@ -1047,6 +1067,50 @@ ChannelArgs ModifyArgsForConnection(const ChannelArgs& args,
}
} // namespace
namespace experimental {
absl::Status PassiveListenerImpl::AcceptConnectedEndpoint(
std::unique_ptr<EventEngine::Endpoint> endpoint) {
CHECK_NE(server_.get(), nullptr);
RefCountedPtr<Chttp2ServerListener> listener;
{
MutexLock lock(&mu_);
if (listener_ != nullptr) {
listener =
listener_->RefIfNonZero().TakeAsSubclass<Chttp2ServerListener>();
}
}
if (listener == nullptr) {
return absl::UnavailableError("passive listener already shut down");
}
ExecCtx exec_ctx;
listener->AcceptConnectedEndpoint(std::move(endpoint));
return absl::OkStatus();
}
absl::Status PassiveListenerImpl::AcceptConnectedFd(int fd) {
CHECK_NE(server_.get(), nullptr);
ExecCtx exec_ctx;
auto& args = server_->channel_args();
auto* supports_fd = QueryExtension<EventEngineSupportsFdExtension>(
/*engine=*/args.GetObjectRef<EventEngine>().get());
if (supports_fd == nullptr) {
return absl::UnimplementedError(
"The server's EventEngine does not support adding endpoints from "
"connected file descriptors.");
}
auto endpoint =
supports_fd->CreateEndpointFromFd(fd, ChannelArgsEndpointConfig(args));
return AcceptConnectedEndpoint(std::move(endpoint));
}
void PassiveListenerImpl::ListenerDestroyed() {
MutexLock lock(&mu_);
listener_ = nullptr;
}
} // namespace experimental
} // namespace grpc_core
int grpc_server_add_http2_port(grpc_server* server, const char* addr,
@ -1144,3 +1208,31 @@ void grpc_server_add_channel_from_fd(grpc_server* /* server */, int /* fd */,
}
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
absl::Status grpc_server_add_passive_listener(
grpc_core::Server* server, grpc_server_credentials* credentials,
std::shared_ptr<grpc_core::experimental::PassiveListenerImpl>
passive_listener) {
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_server_add_passive_listener(server=%p, credentials=%p)",
2, (server, credentials));
// Create security context.
if (credentials == nullptr) {
return absl::UnavailableError(
"No credentials specified for passive listener");
}
auto sc = credentials->create_security_connector(grpc_core::ChannelArgs());
if (sc == nullptr) {
return absl::UnavailableError(
absl::StrCat("Unable to create secure server with credentials of type ",
credentials->type().name()));
}
auto args = server->channel_args()
.SetObject(credentials->Ref())
.SetObject(std::move(sc));
passive_listener->listener_ =
grpc_core::Chttp2ServerListener::CreateForPassiveListener(
server, args, passive_listener);
passive_listener->server_ = server->Ref();
return absl::OkStatus();
}

@ -21,6 +21,7 @@
#include <functional>
#include <grpc/passive_listener.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/channel/channel_args.h"
@ -42,6 +43,38 @@ grpc_error_handle Chttp2ServerAddPort(
Server* server, const char* addr, const ChannelArgs& args,
Chttp2ServerArgsModifier connection_args_modifier, int* port_num);
class Chttp2ServerListener;
namespace experimental {
// An implementation of the public C++ passive listener interface.
// The server builder holds a weak_ptr to one of these objects, and the
// application owns the instance.
class PassiveListenerImpl final : public PassiveListener {
public:
absl::Status AcceptConnectedEndpoint(
std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
endpoint) override ABSL_LOCKS_EXCLUDED(mu_);
absl::Status AcceptConnectedFd(GRPC_UNUSED int fd) override
ABSL_LOCKS_EXCLUDED(mu_);
void ListenerDestroyed() ABSL_LOCKS_EXCLUDED(mu_);
private:
// note: the grpc_core::Server redundant namespace qualification is
// required for older gcc versions.
friend absl::Status(::grpc_server_add_passive_listener)(
grpc_core::Server* server, grpc_server_credentials* credentials,
std::shared_ptr<grpc_core::experimental::PassiveListenerImpl>
passive_listener);
Mutex mu_;
// Data members will be populated when initialized.
RefCountedPtr<Server> server_;
Chttp2ServerListener* listener_;
};
} // namespace experimental
} // namespace grpc_core
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H

@ -34,12 +34,14 @@ GlobalInstrumentsRegistry::GetInstrumentList() {
return *instruments;
}
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle
GlobalInstrumentsRegistry::RegisterUInt64Counter(
GlobalInstrumentsRegistry::InstrumentID
GlobalInstrumentsRegistry::RegisterInstrument(
GlobalInstrumentsRegistry::ValueType value_type,
GlobalInstrumentsRegistry::InstrumentType instrument_type,
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
absl::string_view unit, bool enable_by_default,
absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
@ -47,11 +49,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
InstrumentID index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kUInt64;
descriptor.instrument_type = InstrumentType::kCounter;
descriptor.value_type = value_type;
descriptor.instrument_type = instrument_type;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
@ -61,169 +63,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalUInt64CounterHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle
GlobalInstrumentsRegistry::RegisterDoubleCounter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kCounter;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalDoubleCounterHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle
GlobalInstrumentsRegistry::RegisterUInt64Histogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kUInt64;
descriptor.instrument_type = InstrumentType::kHistogram;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalUInt64HistogramHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kHistogram;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalDoubleHistogramHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kInt64;
descriptor.instrument_type = InstrumentType::kCallbackGauge;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalCallbackInt64GaugeHandle handle;
handle.index = index;
return handle;
}
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default) {
auto& instruments = GetInstrumentList();
for (const auto& descriptor : instruments) {
if (descriptor.name == name) {
Crash(
absl::StrFormat("Metric name %s has already been registered.", name));
}
}
uint32_t index = instruments.size();
CHECK_LT(index, std::numeric_limits<uint32_t>::max());
GlobalInstrumentDescriptor descriptor;
descriptor.value_type = ValueType::kDouble;
descriptor.instrument_type = InstrumentType::kCallbackGauge;
descriptor.index = index;
descriptor.enable_by_default = enable_by_default;
descriptor.name = name;
descriptor.description = description;
descriptor.unit = unit;
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
descriptor.optional_label_keys = {optional_label_keys.begin(),
optional_label_keys.end()};
instruments.push_back(std::move(descriptor));
GlobalCallbackDoubleGaugeHandle handle;
handle.index = index;
return handle;
return index;
}
void GlobalInstrumentsRegistry::ForEach(
@ -242,7 +82,7 @@ GlobalInstrumentsRegistry::GetInstrumentDescriptor(
RegisteredMetricCallback::RegisteredMetricCallback(
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group,
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics,
Duration min_interval)
: stats_plugin_group_(stats_plugin_group),
callback_(std::move(callback)),
@ -259,15 +99,6 @@ RegisteredMetricCallback::~RegisteredMetricCallback() {
}
}
std::unique_ptr<RegisteredMetricCallback>
GlobalStatsPluginRegistry::StatsPluginGroup::RegisterCallback(
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
Duration min_interval) {
return std::make_unique<RegisteredMetricCallback>(
*this, std::move(callback), std::move(metrics), min_interval);
}
void GlobalStatsPluginRegistry::StatsPluginGroup::AddClientCallTracers(
const Slice& path, bool registered_method,
grpc_call_context_element* call_context) {

@ -17,6 +17,7 @@
#include <cstdint>
#include <memory>
#include <type_traits>
#include <vector>
#include "absl/functional/any_invocable.h"
@ -45,6 +46,27 @@ constexpr absl::string_view kMetricLabelTarget = "grpc.target";
// startup, before the execution of the main function (during dynamic
// initialization time). Using this API after the main function begins may
// result into missing instruments. This API is thread-unsafe.
//
// The registration of instruments is done through the templated
// RegistrationBuilder API and gets back a handle with an opaque type. At
// runtime, the handle should be used with the StatsPluginGroup API to record
// metrics for the instruments.
//
// At dynamic initialization time:
// const auto kMetricHandle =
// GlobalInstrumentsRegistry::RegisterUInt64Counter(
// "name",
// "description",
// "unit", /*enable_by_default=*/false)
// .Labels(kLabel1, kLabel2, kLabel3)
// .OptionalLabels(kOptionalLabel1, kOptionalLabel2)
// .Build();
//
// At runtime time:
// stats_plugin_group.AddCounter(kMetricHandle, 1,
// {"label_value_1", "label_value_2", "label_value_3"},
// {"optional_label_value_1", "optional_label_value_2"});
//
class GlobalInstrumentsRegistry {
public:
enum class ValueType {
@ -78,46 +100,113 @@ class GlobalInstrumentsRegistry {
// runs or between different versions.
InstrumentID index;
};
struct GlobalUInt64CounterHandle : public GlobalInstrumentHandle {};
struct GlobalDoubleCounterHandle : public GlobalInstrumentHandle {};
struct GlobalUInt64HistogramHandle : public GlobalInstrumentHandle {};
struct GlobalDoubleHistogramHandle : public GlobalInstrumentHandle {};
struct GlobalCallbackInt64GaugeHandle : public GlobalInstrumentHandle {};
struct GlobalCallbackDoubleGaugeHandle : public GlobalInstrumentHandle {};
using GlobalCallbackHandle = absl::variant<GlobalCallbackInt64GaugeHandle,
GlobalCallbackDoubleGaugeHandle>;
template <ValueType V, InstrumentType I, size_t M, size_t N>
struct TypedGlobalInstrumentHandle : public GlobalInstrumentHandle {};
template <ValueType V, InstrumentType I, std::size_t M, std::size_t N>
class RegistrationBuilder {
public:
template <typename... Args>
RegistrationBuilder<V, I, sizeof...(Args), N> Labels(Args&&... args) {
return RegistrationBuilder<V, I, sizeof...(Args), N>(
name_, description_, unit_, enable_by_default_,
std::array<absl::string_view, sizeof...(Args)>({args...}),
optional_label_keys_);
}
template <typename... Args>
RegistrationBuilder<V, I, M, sizeof...(Args)> OptionalLabels(
Args&&... args) {
return RegistrationBuilder<V, I, M, sizeof...(Args)>(
name_, description_, unit_, enable_by_default_, label_keys_,
std::array<absl::string_view, sizeof...(Args)>({args...}));
}
TypedGlobalInstrumentHandle<V, I, M, N> Build() {
TypedGlobalInstrumentHandle<V, I, M, N> handle;
handle.index = RegisterInstrument(V, I, name_, description_, unit_,
enable_by_default_, label_keys_,
optional_label_keys_);
return handle;
}
private:
friend class GlobalInstrumentsRegistry;
RegistrationBuilder(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default)
: name_(name),
description_(description),
unit_(unit),
enable_by_default_(enable_by_default) {}
RegistrationBuilder(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default,
std::array<absl::string_view, M> label_keys,
std::array<absl::string_view, N> optional_label_keys)
: name_(name),
description_(description),
unit_(unit),
enable_by_default_(enable_by_default),
label_keys_(std::move(label_keys)),
optional_label_keys_(std::move(optional_label_keys)) {}
absl::string_view name_;
absl::string_view description_;
absl::string_view unit_;
bool enable_by_default_;
std::array<absl::string_view, M> label_keys_;
std::array<absl::string_view, N> optional_label_keys_;
};
// Creates instrument in the GlobalInstrumentsRegistry.
static GlobalUInt64CounterHandle RegisterUInt64Counter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalDoubleCounterHandle RegisterDoubleCounter(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalUInt64HistogramHandle RegisterUInt64Histogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalDoubleHistogramHandle RegisterDoubleHistogram(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalCallbackInt64GaugeHandle RegisterCallbackInt64Gauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static GlobalCallbackDoubleGaugeHandle RegisterCallbackDoubleGauge(
absl::string_view name, absl::string_view description,
absl::string_view unit, absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys,
bool enable_by_default);
static RegistrationBuilder<ValueType::kUInt64, InstrumentType::kCounter, 0, 0>
RegisterUInt64Counter(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kUInt64, InstrumentType::kCounter, 0,
0>(name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kCounter, 0, 0>
RegisterDoubleCounter(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble, InstrumentType::kCounter, 0,
0>(name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kUInt64, InstrumentType::kHistogram, 0,
0>
RegisterUInt64Histogram(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kUInt64, InstrumentType::kHistogram,
0, 0>(name, description, unit,
enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kHistogram, 0,
0>
RegisterDoubleHistogram(absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble, InstrumentType::kHistogram,
0, 0>(name, description, unit,
enable_by_default);
}
static RegistrationBuilder<ValueType::kInt64, InstrumentType::kCallbackGauge,
0, 0>
RegisterCallbackInt64Gauge(absl::string_view name,
absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kInt64,
InstrumentType::kCallbackGauge, 0, 0>(
name, description, unit, enable_by_default);
}
static RegistrationBuilder<ValueType::kDouble, InstrumentType::kCallbackGauge,
0, 0>
RegisterCallbackDoubleGauge(absl::string_view name,
absl::string_view description,
absl::string_view unit, bool enable_by_default) {
return RegistrationBuilder<ValueType::kDouble,
InstrumentType::kCallbackGauge, 0, 0>(
name, description, unit, enable_by_default);
}
static void ForEach(
absl::FunctionRef<void(const GlobalInstrumentDescriptor&)> f);
@ -131,6 +220,12 @@ class GlobalInstrumentsRegistry {
static std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
GetInstrumentList();
static InstrumentID RegisterInstrument(
ValueType value_type, InstrumentType instrument_type,
absl::string_view name, absl::string_view description,
absl::string_view unit, bool enable_by_default,
absl::Span<const absl::string_view> label_keys,
absl::Span<const absl::string_view> optional_label_keys);
};
// An interface for implementing callback-style metrics.
@ -139,13 +234,35 @@ class CallbackMetricReporter {
public:
virtual ~CallbackMetricReporter() = default;
virtual void Report(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
template <std::size_t M, std::size_t N>
void Report(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kInt64,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N>
handle,
int64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
ReportInt64(handle, value, label_values, optional_values);
}
template <std::size_t M, std::size_t N>
void Report(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
ReportDouble(handle, value, label_values, optional_values);
}
private:
virtual void ReportInt64(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) = 0;
virtual void Report(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
double value, absl::Span<const absl::string_view> label_values,
virtual void ReportDouble(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) = 0;
};
@ -179,15 +296,15 @@ class StatsPlugin {
// this measurement and must match with their corresponding keys in
// GlobalInstrumentsRegistry::RegisterUInt64Counter().
virtual void AddCounter(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Adds \a value to the double counter specified by \a handle. \a label_values
// and \a optional_label_values specify attributes that are associated with
// this measurement and must match with their corresponding keys in
// GlobalInstrumentsRegistry::RegisterDoubleCounter().
virtual void AddCounter(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Records a uint64 \a value to the histogram specified by \a handle. \a
@ -195,16 +312,16 @@ class StatsPlugin {
// associated with this measurement and must match with their corresponding
// keys in GlobalInstrumentsRegistry::RegisterUInt64Histogram().
virtual void RecordHistogram(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Records a double \a value to the histogram specified by \a handle. \a
// label_values and \a optional_label_values specify attributes that are
// associated with this measurement and must match with their corresponding
// keys in GlobalInstrumentsRegistry::RegisterDoubleHistogram().
virtual void RecordHistogram(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
double value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_label_values) = 0;
// Adds a callback to be invoked when the stats plugin wants to
// populate the corresponding metrics (see callback->metrics() for list).
@ -255,20 +372,53 @@ class GlobalStatsPluginRegistry {
}
// Adds a counter in all stats plugins within the group. See the StatsPlugin
// interface for more documentation and valid types.
template <class HandleType, class ValueType>
void AddCounter(HandleType handle, ValueType value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
template <std::size_t M, std::size_t N>
void AddCounter(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N>
handle,
uint64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->AddCounter(handle, value, label_values, optional_values);
}
}
template <std::size_t M, std::size_t N>
void AddCounter(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->AddCounter(handle, value, label_values, optional_values);
}
}
// Records a value to a histogram in all stats plugins within the group. See
// the StatsPlugin interface for more documentation and valid types.
template <class HandleType, class ValueType>
void RecordHistogram(HandleType handle, ValueType value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
template <std::size_t M, std::size_t N>
void RecordHistogram(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N>
handle,
uint64_t value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->RecordHistogram(handle, value, label_values,
optional_values);
}
}
template <std::size_t M, std::size_t N>
void RecordHistogram(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N>
handle,
double value, std::array<absl::string_view, M> label_values,
std::array<absl::string_view, N> optional_values) {
for (auto& state : plugins_state_) {
state.plugin->RecordHistogram(handle, value, label_values,
optional_values);
@ -285,11 +435,17 @@ class GlobalStatsPluginRegistry {
// the lifetime of the callback; when the returned object is
// destroyed, the callback is de-registered. The returned object
// must not outlive the StatsPluginGroup object that created it.
template <typename... Args>
GRPC_MUST_USE_RESULT std::unique_ptr<RegisteredMetricCallback>
RegisterCallback(
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
Duration min_interval = Duration::Seconds(5));
RegisterCallback(absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
Duration min_interval, Args... args) {
AssertIsCallbackGaugeHandle(args...);
return std::make_unique<RegisteredMetricCallback>(
*this, std::move(callback),
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle>{
args...},
min_interval);
}
// Adds all available client call tracers associated with the stats plugins
// within the group to \a call_context.
@ -307,6 +463,24 @@ class GlobalStatsPluginRegistry {
std::shared_ptr<StatsPlugin> plugin;
};
// C++17 has fold expression that may simplify this.
template <GlobalInstrumentsRegistry::ValueType V,
GlobalInstrumentsRegistry::InstrumentType I, size_t M, size_t N>
static constexpr void AssertIsCallbackGaugeHandle(
GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle<V, I, M, N>) {
static_assert(V == GlobalInstrumentsRegistry::ValueType::kInt64 ||
V == GlobalInstrumentsRegistry::ValueType::kDouble,
"ValueType must be kInt64 or kDouble");
static_assert(
I == GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge,
"InstrumentType must be kCallbackGauge");
}
template <typename T, typename... Args>
static constexpr void AssertIsCallbackGaugeHandle(T t, Args&&... args) {
AssertIsCallbackGaugeHandle(t);
AssertIsCallbackGaugeHandle(args...);
}
std::vector<PluginState> plugins_state_;
};
@ -335,7 +509,7 @@ class RegisteredMetricCallback {
RegisteredMetricCallback(
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group,
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics,
Duration min_interval);
~RegisteredMetricCallback();
@ -344,8 +518,8 @@ class RegisteredMetricCallback {
void Run(CallbackMetricReporter& reporter) { callback_(reporter); }
// Returns the set of metrics that this callback will modify.
const std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle>& metrics()
const {
const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle>&
metrics() const {
return metrics_;
}
@ -356,7 +530,7 @@ class RegisteredMetricCallback {
private:
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group_;
absl::AnyInvocable<void(CallbackMetricReporter&)> callback_;
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics_;
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentHandle> metrics_;
Duration min_interval_;
};

@ -112,6 +112,13 @@ class EventEngineSupportsFdExtension {
int fd, const EndpointConfig& config,
MemoryAllocator memory_allocator) = 0;
/// Creates an EventEngine::Endpoint from an fd which is already assumed to be
/// connected to a remote peer. See \a CreatePosixEndpointFromFd for details.
/// This has the same behavior, but the \a memory_allocator is taken from the
/// EndpointConfig's resource quota.
virtual std::unique_ptr<EventEngine::Endpoint> CreateEndpointFromFd(
int fd, const EndpointConfig& config) = 0;
/// Called when the posix listener has accepted a new client connection.
/// \a listener_fd - The listening socket fd that accepted the new client
/// connection.

@ -677,6 +677,22 @@ PosixEventEngine::CreatePosixEndpointFromFd(int fd,
#endif // GRPC_PLATFORM_SUPPORTS_POSIX_POLLING
}
std::unique_ptr<EventEngine::Endpoint> PosixEventEngine::CreateEndpointFromFd(
int fd, const EndpointConfig& config) {
auto options = TcpOptionsFromEndpointConfig(config);
MemoryAllocator allocator;
if (options.memory_allocator_factory != nullptr) {
return CreatePosixEndpointFromFd(
fd, config,
options.memory_allocator_factory->CreateMemoryAllocator(
absl::StrCat("allocator:", fd)));
}
return CreatePosixEndpointFromFd(
fd, config,
options.resource_quota->memory_quota()->CreateMemoryAllocator(
absl::StrCat("allocator:", fd)));
}
absl::StatusOr<std::unique_ptr<EventEngine::Listener>>
PosixEventEngine::CreateListener(
Listener::AcceptCallback on_accept,

@ -172,6 +172,8 @@ class PosixEventEngine final : public PosixEventEngineWithFdSupport,
std::unique_ptr<EventEngine::Endpoint> CreatePosixEndpointFromFd(
int fd, const EndpointConfig& config,
MemoryAllocator memory_allocator) override;
std::unique_ptr<EventEngine::Endpoint> CreateEndpointFromFd(
int fd, const EndpointConfig& config) override;
absl::StatusOr<std::unique_ptr<Listener>> CreateListener(
Listener::AcceptCallback on_accept,

@ -227,18 +227,19 @@ void WorkStealingThreadPool::PostforkChild() { pool_->Postfork(); }
WorkStealingThreadPool::WorkStealingThreadPoolImpl::WorkStealingThreadPoolImpl(
size_t reserve_threads)
: reserve_threads_(reserve_threads), queue_(this), lifeguard_(this) {}
: reserve_threads_(reserve_threads), queue_(this) {}
void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Start() {
for (size_t i = 0; i < reserve_threads_; i++) {
StartThread();
}
lifeguard_.Start();
grpc_core::MutexLock lock(&lifeguard_ptr_mu_);
lifeguard_ = std::make_unique<Lifeguard>(this);
}
void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Run(
EventEngine::Closure* closure) {
DCHECK(quiesced_.load(std::memory_order_relaxed) == false);
CHECK(!IsQuiesced());
if (g_local_queue != nullptr && g_local_queue->owner() == this) {
g_local_queue->Add(closure);
} else {
@ -283,7 +284,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Quiesce() {
}
CHECK(queue_.Empty());
quiesced_.store(true, std::memory_order_relaxed);
lifeguard_.BlockUntilShutdownAndReset();
grpc_core::MutexLock lock(&lifeguard_ptr_mu_);
lifeguard_.reset();
}
bool WorkStealingThreadPool::WorkStealingThreadPoolImpl::SetThrottled(
@ -325,7 +327,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::PrepareFork() {
if (!threads_were_shut_down.ok() && g_log_verbose_failures) {
DumpStacksAndCrash();
}
lifeguard_.BlockUntilShutdownAndReset();
grpc_core::MutexLock lock(&lifeguard_ptr_mu_);
lifeguard_.reset();
}
void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Postfork() {
@ -374,9 +377,7 @@ WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Lifeguard(
.set_max_backoff(kLifeguardMaxSleepBetweenChecks)
.set_multiplier(1.3)),
lifeguard_should_shut_down_(std::make_unique<grpc_core::Notification>()),
lifeguard_is_shut_down_(std::make_unique<grpc_core::Notification>()) {}
void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Start() {
lifeguard_is_shut_down_(std::make_unique<grpc_core::Notification>()) {
// lifeguard_running_ is set early to avoid a quiesce race while the
// lifeguard is still starting up.
lifeguard_running_.store(true);
@ -411,8 +412,7 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::
lifeguard_is_shut_down_->Notify();
}
void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::
BlockUntilShutdownAndReset() {
WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::~Lifeguard() {
lifeguard_should_shut_down_->Notify();
while (lifeguard_running_.load(std::memory_order_relaxed)) {
GRPC_LOG_EVERY_N_SEC_DELAYED(kBlockingQuiesceLogRateSeconds, GPR_DEBUG,

@ -155,11 +155,7 @@ class WorkStealingThreadPool final : public ThreadPool {
class Lifeguard {
public:
explicit Lifeguard(WorkStealingThreadPoolImpl* pool);
// Start the lifeguard thread.
void Start();
// Block until the lifeguard thread is shut down.
// Afterwards, reset the lifeguard state so it can start again cleanly.
void BlockUntilShutdownAndReset();
~Lifeguard();
private:
// The main body of the lifeguard thread.
@ -194,7 +190,8 @@ class WorkStealingThreadPool final : public ThreadPool {
// at a time.
std::atomic<bool> throttled_{false};
WorkSignal work_signal_;
Lifeguard lifeguard_;
grpc_core::Mutex lifeguard_ptr_mu_;
std::unique_ptr<Lifeguard> lifeguard_ ABSL_GUARDED_BY(lifeguard_ptr_mu_);
// Set of threads for verbose failure debugging
grpc_core::Mutex thd_set_mu_;
absl::flat_hash_set<gpr_thd_id> thds_ ABSL_GUARDED_BY(thd_set_mu_);

@ -344,7 +344,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"client_privacy", description_client_privacy,
additional_constraints_client_privacy, nullptr, 0, false, false},
{"event_engine_client", description_event_engine_client,
additional_constraints_event_engine_client, nullptr, 0, false, true},
additional_constraints_event_engine_client, nullptr, 0, true, true},
{"event_engine_dns", description_event_engine_dns,
additional_constraints_event_engine_dns, nullptr, 0, false, false},
{"event_engine_listener", description_event_engine_listener,

@ -99,7 +99,8 @@ inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; }
inline bool IsCallV3Enabled() { return false; }
inline bool IsCanaryClientPrivacyEnabled() { return false; }
inline bool IsClientPrivacyEnabled() { return false; }
inline bool IsEventEngineClientEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_CLIENT
inline bool IsEventEngineClientEnabled() { return true; }
inline bool IsEventEngineDnsEnabled() { return false; }
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_LISTENER
inline bool IsEventEngineListenerEnabled() { return true; }

@ -58,9 +58,7 @@
# not tested on iOS at all
ios: broken
posix: false
# TODO(hork): resolve when the client end2end test flake rate reduces to
# a tolerable amount.
windows: false
windows: true
- name: event_engine_dns
default:
# not tested on iOS at all

@ -57,23 +57,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity,
free(message);
}
void gpr_platform_log(gpr_log_func_args* args) {
const char* final_slash;
const char* display_file;
char* output = NULL;
final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
asprintf(&output, "%s:%d] %s", display_file, args->line, args->message);
__android_log_write(severity_to_log_priority(args->severity), "GRPC", output);
// allocated by asprintf => use free, not gpr_free
free(output);
}
#endif // GPR_ANDROID

@ -47,10 +47,6 @@
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/examine_stack.h"
int gpr_should_log_stacktrace(gpr_log_severity severity);
static long sys_gettid(void) { return syscall(__NR_gettid); }
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
// Avoid message construction if gpr_log_message won't log
@ -70,45 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity,
free(message);
}
void gpr_platform_log(gpr_log_func_args* args) {
const char* final_slash;
const char* display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
static thread_local long tid(0);
if (tid == 0) tid = sys_gettid();
timer = static_cast<time_t>(now.tv_sec);
final_slash = strrchr(args->file, '/');
if (final_slash == nullptr) {
display_file = args->file;
} else {
display_file = final_slash + 1;
}
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {
strcpy(time_buffer, "error:strftime");
}
std::string prefix = absl::StrFormat(
"%s%s.%09" PRId32 " %7ld %s:%d]", gpr_log_severity_string(args->severity),
time_buffer, now.tv_nsec, tid, display_file, args->line);
absl::optional<std::string> stack_trace =
gpr_should_log_stacktrace(args->severity)
? grpc_core::GetCurrentStackTrace()
: absl::nullopt;
if (stack_trace) {
fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message,
stack_trace->c_str());
} else {
fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message);
}
}
#endif // GPR_LINUX_LOG

@ -77,10 +77,6 @@ int gpr_should_log(gpr_log_severity severity) {
}
void gpr_default_log(gpr_log_func_args* args) {
if (!grpc_core::ConfigVars::Get().AbslLogging()) {
gpr_platform_log(args);
return;
}
switch (args->severity) {
case GPR_LOG_SEVERITY_DEBUG:
// Log DEBUG messages as VLOG(2).
@ -99,13 +95,6 @@ void gpr_default_log(gpr_log_func_args* args) {
}
}
int gpr_should_log_stacktrace(gpr_log_severity severity) {
return static_cast<gpr_atm>(severity) >=
gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace)
? 1
: 0;
}
void gpr_log_message(const char* file, int line, gpr_log_severity severity,
const char* message) {
if (gpr_should_log(severity) == 0) {

@ -38,10 +38,6 @@
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/examine_stack.h"
int gpr_should_log_stacktrace(gpr_log_severity severity);
static intptr_t sys_gettid(void) { return (intptr_t)pthread_self(); }
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
// Avoid message construction if gpr_log_message won't log
@ -70,42 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity,
gpr_free(allocated);
}
void gpr_platform_log(gpr_log_func_args* args) {
const char* final_slash;
const char* display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '/');
if (final_slash == nullptr)
display_file = args->file;
else
display_file = final_slash + 1;
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {
strcpy(time_buffer, "error:strftime");
}
std::string prefix = absl::StrFormat(
"%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity),
time_buffer, (int)(now.tv_nsec), sys_gettid(), display_file, args->line);
absl::optional<std::string> stack_trace =
gpr_should_log_stacktrace(args->severity)
? grpc_core::GetCurrentStackTrace()
: absl::nullopt;
if (stack_trace) {
fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message,
stack_trace->c_str());
} else {
fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message);
}
}
#endif // defined(GPR_POSIX_LOG)

@ -33,8 +33,6 @@
#include "src/core/lib/gprpp/crash.h"
#include "src/core/lib/gprpp/examine_stack.h"
int gpr_should_log_stacktrace(gpr_log_severity severity);
void gpr_log(const char* file, int line, gpr_log_severity severity,
const char* format, ...) {
// Avoid message construction if gpr_log_message won't log
@ -72,45 +70,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity,
gpr_free(message);
}
// Simple starter implementation
void gpr_platform_log(gpr_log_func_args* args) {
const char* final_slash;
const char* display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '\\');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (localtime_s(&tm, &timer)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {
strcpy(time_buffer, "error:strftime");
}
absl::optional<std::string> stack_trace =
gpr_should_log_stacktrace(args->severity)
? grpc_core::GetCurrentStackTrace()
: absl::nullopt;
if (stack_trace) {
fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n%s\n",
gpr_log_severity_string(args->severity), time_buffer,
(int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line,
args->message, stack_trace->c_str());
} else {
fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n",
gpr_log_severity_string(args->severity), time_buffer,
(int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line,
args->message);
}
fflush(stderr);
}
#endif // GPR_WINDOWS_LOG

@ -84,19 +84,25 @@ const auto kMetricDisconnections =
"grpc.lb.pick_first.disconnections",
"EXPERIMENTAL. Number of times the selected subchannel becomes "
"disconnected.",
"{disconnection}", {kMetricLabelTarget}, {}, false);
"{disconnection}", false)
.Labels(kMetricLabelTarget)
.Build();
const auto kMetricConnectionAttemptsSucceeded =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.pick_first.connection_attempts_succeeded",
"EXPERIMENTAL. Number of successful connection attempts.", "{attempt}",
{kMetricLabelTarget}, {}, false);
false)
.Labels(kMetricLabelTarget)
.Build();
const auto kMetricConnectionAttemptsFailed =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.pick_first.connection_attempts_failed",
"EXPERIMENTAL. Number of failed connection attempts.", "{attempt}",
{kMetricLabelTarget}, {}, false);
false)
.Labels(kMetricLabelTarget)
.Build();
class PickFirstConfig final : public LoadBalancingPolicy::Config {
public:

@ -128,26 +128,27 @@ constexpr absl::string_view kMetricLabelPickResult = "grpc.lb.pick_result";
const auto kMetricCacheSize =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.lb.rls.cache_size", "EXPERIMENTAL. Size of the RLS cache.", "By",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid},
{}, false);
false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid)
.Build();
const auto kMetricCacheEntries =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.lb.rls.cache_entries",
"EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid},
{}, false);
"EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricLabelRlsInstanceUuid)
.Build();
const auto kMetricDefaultTargetPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.rls.default_target_picks",
"EXPERIMENTAL. Number of LB picks sent to the default target.",
"{pick}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult},
{}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult)
.Build();
const auto kMetricTargetPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -156,17 +157,19 @@ const auto kMetricTargetPicks =
"if the default target is also returned by the RLS server, RPCs sent "
"to that target from the cache will be counted in this metric, not "
"in grpc.rls.default_target_picks.",
"{pick}",
{kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult},
{}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget,
kMetricRlsDataPlaneTarget, kMetricLabelPickResult)
.Build();
const auto kMetricFailedPicks =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.rls.failed_picks",
"EXPERIMENTAL. Number of LB picks failed due to either a failed RLS "
"request or the RLS channel being throttled.",
"{pick}", {kMetricLabelTarget, kMetricLabelRlsServerTarget}, {}, false);
"{pick}", false)
.Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget)
.Build();
constexpr absl::string_view kRls = "rls_experimental";
const char kGrpc[] = "grpc";
@ -754,9 +757,9 @@ class RlsLb final : public LoadBalancingPolicy {
// Updates the picker in the work serializer.
void UpdatePickerLocked() ABSL_LOCKS_EXCLUDED(&mu_);
void MaybeExportPickCount(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::string_view target, const PickResult& pick_result);
template <typename HandleType>
void MaybeExportPickCount(HandleType handle, absl::string_view target,
const PickResult& pick_result);
const std::string instance_uuid_;
@ -1961,7 +1964,7 @@ RlsLb::RlsLb(Args args)
MutexLock lock(&mu_);
cache_.ReportMetricsLocked(reporter);
},
{kMetricCacheSize, kMetricCacheEntries})) {
Duration::Seconds(5), kMetricCacheSize, kMetricCacheEntries)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_rls_trace)) {
gpr_log(GPR_INFO, "[rlslb %p] policy created", this);
}
@ -2230,9 +2233,9 @@ void RlsLb::UpdatePickerLocked() {
MakeRefCounted<Picker>(RefAsSubclass<RlsLb>(DEBUG_LOCATION, "Picker")));
}
void RlsLb::MaybeExportPickCount(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::string_view target, const PickResult& pick_result) {
template <typename HandleType>
void RlsLb::MaybeExportPickCount(HandleType handle, absl::string_view target,
const PickResult& pick_result) {
absl::string_view pick_result_string = Match(
pick_result.result,
[](const LoadBalancingPolicy::PickResult::Complete&) {

@ -85,12 +85,16 @@ constexpr absl::string_view kWeightedRoundRobin = "weighted_round_robin";
constexpr absl::string_view kMetricLabelLocality = "grpc.lb.locality";
const auto kMetricRrFallback = GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.rr_fallback",
"EXPERIMENTAL. Number of scheduler updates in which there were not "
"enough endpoints with valid weight, which caused the WRR policy to "
"fall back to RR behavior.",
"{update}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
const auto kMetricRrFallback =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.rr_fallback",
"EXPERIMENTAL. Number of scheduler updates in which there were not "
"enough endpoints with valid weight, which caused the WRR policy to "
"fall back to RR behavior.",
"{update}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeightNotYetUsable =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -99,14 +103,20 @@ const auto kMetricEndpointWeightNotYetUsable =
"don't yet have usable weight information (i.e., either the load "
"report has not yet been received, or it is within the blackout "
"period).",
"{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{endpoint}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeightStale =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.lb.wrr.endpoint_weight_stale",
"EXPERIMENTAL. Number of endpoints from each scheduler update whose "
"latest weight is older than the expiration period.",
"{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{endpoint}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
const auto kMetricEndpointWeights =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
@ -115,7 +125,10 @@ const auto kMetricEndpointWeights =
"Each bucket will be a counter that is incremented once for every "
"endpoint whose weight is within that range. Note that endpoints "
"without usable weights will have weight 0.",
"{weight}", {kMetricLabelTarget}, {kMetricLabelLocality}, false);
"{weight}", false)
.Labels(kMetricLabelTarget)
.OptionalLabels(kMetricLabelLocality)
.Build();
// Config for WRR policy.
class WeightedRoundRobinConfig final : public LoadBalancingPolicy::Config {

@ -40,6 +40,7 @@
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/passive_listener.h>
#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
@ -75,6 +76,9 @@
"grpc.server.max_pending_requests_hard_limit"
namespace grpc_core {
namespace experimental {
class PassiveListenerImpl;
} // namespace experimental
extern TraceFlag grpc_server_channel_trace;
@ -113,7 +117,7 @@ class Server : public ServerInterface,
/// Interface for listeners.
/// Implementations must override the Orphan() method, which should stop
/// listening and initiate destruction of the listener.
class ListenerInterface : public Orphanable {
class ListenerInterface : public InternallyRefCounted<ListenerInterface> {
public:
~ListenerInterface() override = default;
@ -217,6 +221,14 @@ class Server : public ServerInterface,
}
private:
// note: the grpc_core::Server redundant namespace qualification is
// required for older gcc versions.
// TODO(yashykt): eliminate this friend statement as part of your upcoming
// server listener refactoring.
friend absl::Status(::grpc_server_add_passive_listener)(
grpc_core::Server* server, grpc_server_credentials* credentials,
std::shared_ptr<grpc_core::experimental::PassiveListenerImpl>
passive_listener);
struct RequestedCall;
class RequestMatcherInterface;

@ -99,20 +99,20 @@ const auto kMetricResourceUpdatesValid =
"EXPERIMENTAL. A counter of resources received that were considered "
"valid. The counter will be incremented even for resources that "
"have not changed.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType)
.Build();
const auto kMetricResourceUpdatesInvalid =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"grpc.xds_client.resource_updates_invalid",
"EXPERIMENTAL. A counter of resources received that were considered "
"invalid.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer,
kMetricLabelXdsResourceType)
.Build();
const auto kMetricServerFailure =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
@ -121,7 +121,9 @@ const auto kMetricServerFailure =
"unhealthy. A server goes unhealthy when we have a connectivity "
"failure or when the ADS stream fails without seeing a response "
"message, as per gRFC A57.",
"{failure}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false);
"{failure}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer)
.Build();
const auto kMetricConnected =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
@ -132,15 +134,17 @@ const auto kMetricConnected =
"ADS stream fails without seeing a response message, as per gRFC "
"A57. It will be set to 1 when we receive the first response on "
"an ADS stream.",
"{bool}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false);
"{bool}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsServer)
.Build();
const auto kMetricResources =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"grpc.xds_client.resources", "EXPERIMENTAL. Number of xDS resources.",
"{resource}",
{kMetricLabelTarget, kMetricLabelXdsAuthority,
kMetricLabelXdsResourceType, kMetricLabelXdsCacheState},
{}, false);
"{resource}", false)
.Labels(kMetricLabelTarget, kMetricLabelXdsAuthority,
kMetricLabelXdsResourceType, kMetricLabelXdsCacheState)
.Build();
} // namespace
@ -316,7 +320,7 @@ GrpcXdsClient::GrpcXdsClient(
[this](CallbackMetricReporter& reporter) {
ReportCallbackMetrics(reporter);
},
{kMetricConnected, kMetricResources})) {}
Duration::Seconds(5), kMetricConnected, kMetricResources)) {}
void GrpcXdsClient::Orphaned() {
registered_metric_callback_.reset();

@ -249,27 +249,35 @@ OpenTelemetryPlugin::CallbackMetricReporter::CallbackMetricReporter(
// that if a particular combination of labels was previously present but
// is no longer present, we won't continue to report it.
for (const auto& handle : key->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<int64_t>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<double>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<int64_t>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
auto& callback_gauge_state =
absl::get<std::unique_ptr<CallbackGaugeState<double>>>(
ot_plugin_->instruments_data_.at(handle.index).instrument);
callback_gauge_state->caches[key].clear();
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
void OpenTelemetryPlugin::CallbackMetricReporter::Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
void OpenTelemetryPlugin::CallbackMetricReporter::ReportInt64(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index);
@ -296,9 +304,8 @@ void OpenTelemetryPlugin::CallbackMetricReporter::Report(
cell.insert_or_assign(std::move(key), value);
}
void OpenTelemetryPlugin::CallbackMetricReporter::Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
handle,
void OpenTelemetryPlugin::CallbackMetricReporter::ReportDouble(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index);
@ -574,8 +581,8 @@ OpenTelemetryPlugin::IsEnabledForChannel(
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
OpenTelemetryPlugin::IsEnabledForServer(
const grpc_core::ChannelArgs& args) const {
// Return true only if there is no server selector registered or if the server
// selector returns true.
// Return true only if there is no server selector registered or if the
// server selector returns true.
if (server_selector_ == nullptr || server_selector_(args)) {
return {true, std::make_shared<ServerScopeConfig>(this, args)};
}
@ -583,7 +590,7 @@ OpenTelemetryPlugin::IsEnabledForServer(
}
void OpenTelemetryPlugin::AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -607,7 +614,7 @@ void OpenTelemetryPlugin::AddCounter(
}
void OpenTelemetryPlugin::AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -631,7 +638,7 @@ void OpenTelemetryPlugin::AddCounter(
}
void OpenTelemetryPlugin::RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -657,7 +664,7 @@ void OpenTelemetryPlugin::RecordHistogram(
}
void OpenTelemetryPlugin::RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
const auto& instrument_data = instruments_data_.at(handle.index);
@ -691,51 +698,59 @@ void OpenTelemetryPlugin::AddCallback(
grpc_core::MutexLock lock(&mu_);
callback_timestamps_.emplace(callback, grpc_core::Timestamp::InfPast());
for (const auto& handle : callback->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback,
CallbackGaugeState<int64_t>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<double>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<int64_t>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
(*callback_gauge_state)
->caches.emplace(callback, CallbackGaugeState<double>::Cache{});
if (!std::exchange((*callback_gauge_state)->ot_callback_registered,
true)) {
gauges_that_need_to_add_callback.push_back(
callback_gauge_state->get());
}
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
// AddCallback internally grabs OpenTelemetry's observable_registry's lock. So
// we need to call it without our plugin lock otherwise we may deadlock.
// AddCallback internally grabs OpenTelemetry's observable_registry's
// lock. So we need to call it without our plugin lock otherwise we may
// deadlock.
for (const auto& gauge : gauges_that_need_to_add_callback) {
grpc_core::Match(
gauge,
@ -759,50 +774,59 @@ void OpenTelemetryPlugin::RemoveCallback(
grpc_core::MutexLock lock(&mu_);
callback_timestamps_.erase(callback);
for (const auto& handle : callback->metrics()) {
grpc_core::Match(
handle,
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackInt64GaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
},
[&](const grpc_core::GlobalInstrumentsRegistry::
GlobalCallbackDoubleGaugeHandle& handle) {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
return;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
});
const auto& descriptor =
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
GPR_ASSERT(
descriptor.instrument_type ==
grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
switch (descriptor.value_type) {
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<int64_t>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
break;
}
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: {
const auto& instrument_data = instruments_data_.at(handle.index);
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
// This instrument is disabled.
continue;
}
auto* callback_gauge_state =
absl::get_if<std::unique_ptr<CallbackGaugeState<double>>>(
&instrument_data.instrument);
CHECK_NE(callback_gauge_state, nullptr);
CHECK((*callback_gauge_state)->ot_callback_registered);
CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u);
if ((*callback_gauge_state)->caches.empty()) {
gauges_that_need_to_remove_callback.push_back(
callback_gauge_state->get());
(*callback_gauge_state)->ot_callback_registered = false;
}
break;
}
default:
grpc_core::Crash(absl::StrFormat(
"Unknown or unsupported value type: %d", descriptor.value_type));
}
}
}
// RemoveCallback internally grabs OpenTelemetry's observable_registry's lock.
// So we need to call it without our plugin lock otherwise we may deadlock.
// RemoveCallback internally grabs OpenTelemetry's observable_registry's
// lock. So we need to call it without our plugin lock otherwise we may
// deadlock.
for (const auto& gauge : gauges_that_need_to_remove_callback) {
grpc_core::Match(
gauge,
@ -842,7 +866,8 @@ void OpenTelemetryPlugin::CallbackGaugeState<ValueType>::Observe(
}
}
// OpenTelemetry calls our callback with its observable_registry's lock held.
// OpenTelemetry calls our callback with its observable_registry's lock
// held.
template <typename ValueType>
void OpenTelemetryPlugin::CallbackGaugeState<ValueType>::CallbackGaugeCallback(
opentelemetry::metrics::ObserverResult result, void* arg) {

@ -343,22 +343,20 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin {
grpc_core::RegisteredMetricCallback* key)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(ot_plugin->mu_);
void Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle
handle,
private:
void ReportInt64(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(
CallbackGaugeState<int64_t>::ot_plugin->mu_) override;
void Report(
grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle
handle,
void ReportDouble(
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(
CallbackGaugeState<double>::ot_plugin->mu_) override;
private:
OpenTelemetryPlugin* ot_plugin_;
grpc_core::RegisteredMetricCallback* key_;
};
@ -380,19 +378,19 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin {
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
IsEnabledForServer(const grpc_core::ChannelArgs& args) const override;
void AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void AddCounter(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void RecordHistogram(
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
double value, absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override;
void AddCallback(grpc_core::RegisteredMetricCallback* callback)

@ -31,6 +31,7 @@
#include <grpc/impl/channel_arg_names.h>
#include <grpc/impl/compression_types.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
#include <grpc/support/workaround_list.h>
#include <grpcpp/completion_queue.h>
@ -47,11 +48,38 @@
#include <grpcpp/support/channel_arguments.h>
#include <grpcpp/support/server_interceptor.h>
#include "src/core/ext/transport/chttp2/server/chttp2_server.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/server/server.h"
#include "src/cpp/server/external_connection_acceptor_impl.h"
namespace grpc {
namespace {
// A PIMPL wrapper class that owns the only ref to the passive listener
// implementation. This is returned to the application.
class PassiveListenerOwner final
: public grpc_core::experimental::PassiveListener {
public:
explicit PassiveListenerOwner(std::shared_ptr<PassiveListener> listener)
: listener_(std::move(listener)) {}
absl::Status AcceptConnectedEndpoint(
std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
endpoint) override {
return listener_->AcceptConnectedEndpoint(std::move(endpoint));
}
absl::Status AcceptConnectedFd(int fd) override {
return listener_->AcceptConnectedFd(fd);
}
private:
std::shared_ptr<PassiveListener> listener_;
};
} // namespace
static std::vector<std::unique_ptr<ServerBuilderPlugin> (*)()>*
g_plugin_factory_list;
@ -225,6 +253,18 @@ ServerBuilder& ServerBuilder::SetResourceQuota(
return *this;
}
ServerBuilder& ServerBuilder::experimental_type::AddPassiveListener(
std::shared_ptr<grpc::ServerCredentials> creds,
std::unique_ptr<experimental::PassiveListener>& passive_listener) {
auto core_passive_listener =
std::make_shared<grpc_core::experimental::PassiveListenerImpl>();
builder_->unstarted_passive_listeners_.emplace_back(core_passive_listener,
std::move(creds));
passive_listener =
std::make_unique<PassiveListenerOwner>(std::move(core_passive_listener));
return *builder_;
}
ServerBuilder& ServerBuilder::AddListeningPort(
const std::string& addr_uri, std::shared_ptr<ServerCredentials> creds,
int* selected_port) {
@ -398,6 +438,26 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
cq->RegisterServer(server.get());
}
for (auto& unstarted_listener : unstarted_passive_listeners_) {
has_frequently_polled_cqs = true;
auto passive_listener = unstarted_listener.passive_listener.lock();
auto* core_server = grpc_core::Server::FromC(server->c_server());
if (passive_listener != nullptr) {
auto* creds = unstarted_listener.credentials->c_creds();
if (creds == nullptr) {
gpr_log(GPR_ERROR, "Credentials missing for PassiveListener");
return nullptr;
}
auto success = grpc_server_add_passive_listener(
core_server, creds, std::move(passive_listener));
if (!success.ok()) {
gpr_log(GPR_ERROR, "Failed to create a passive listener: %s",
success.ToString().c_str());
return nullptr;
}
}
}
if (!has_frequently_polled_cqs) {
gpr_log(GPR_ERROR,
"At least one of the completion queues must be frequently polled");

@ -0,0 +1,28 @@
%YAML 1.2
--- |
# Copyright 2021 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.
FROM gcc:7
RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean
<%include file="../../git_avoid_dubious_ownership_error.include"/>
<%include file="../../run_tests_python_deps.include"/>
<%include file="../../cxx_test_deps.include"/>
<%include file="../../cmake.include"/>
<%include file="../../ccache_old.include"/>
<%include file="../../run_tests_addons.include"/>
# Define the default command.
CMD ["bash"]

@ -41,6 +41,7 @@ grpc_cc_test(
name = "parse_address_test",
srcs = ["parse_address_test.cc"],
external_deps = [
"absl/log:log",
"absl/strings",
"gtest",
],
@ -69,7 +70,10 @@ grpc_fuzzer(
grpc_cc_test(
name = "parse_address_with_named_scope_id_test",
srcs = ["parse_address_with_named_scope_id_test.cc"],
external_deps = ["gtest"],
external_deps = [
"absl/log:log",
"gtest",
],
language = "C++",
tags = ["no_windows"],
uses_event_engine = False,

@ -34,12 +34,12 @@
#include <string>
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/port.h"
@ -53,7 +53,7 @@ static void test_grpc_parse_unix(const char* uri_text, const char* pathname) {
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;
@ -70,7 +70,7 @@ static void test_grpc_parse_unix_abstract(const char* uri_text,
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;
@ -98,7 +98,7 @@ static void test_grpc_parse_vsock(const char* uri_text, uint32_t cid,
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;
@ -122,7 +122,7 @@ static void test_grpc_parse_ipv4(const char* uri_text, const char* host,
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;
@ -142,7 +142,7 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host,
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;
@ -162,7 +162,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) {
grpc_core::ExecCtx exec_ctx;
absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
LOG(ERROR) << uri.status();
ASSERT_TRUE(uri.ok());
}
grpc_resolved_address addr;

@ -28,13 +28,13 @@
#include <string>
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/gprpp/crash.h"
@ -114,10 +114,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) {
// system recognizes, and then use that for the test.
for (size_t i = 1; i < 65536; i++) {
if (if_indextoname(i, arbitrary_interface_name) != nullptr) {
gpr_log(GPR_DEBUG,
"Found interface at index %" PRIuPTR
" named %s. Will use this for the test",
i, arbitrary_interface_name);
VLOG(2) << "Found interface at index " << i << " named "
<< arbitrary_interface_name << ". Will use this for the test";
break;
}
}
@ -127,9 +125,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) {
struct sockaddr_in6 result_from_getaddrinfo =
resolve_with_gettaddrinfo(target.c_str());
// Run the test
gpr_log(GPR_DEBUG,
"Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s",
target.c_str());
VLOG(2) << "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: "
<< target;
test_grpc_parse_ipv6_parity_with_getaddrinfo(target.c_str(),
result_from_getaddrinfo);
// Cleanup

@ -22,11 +22,11 @@
#include <limits.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include <grpc/impl/channel_arg_names.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
@ -111,11 +111,11 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags,
hex = gpr_dump(arg->client_payload, arg->client_payload_length,
GPR_DUMP_HEX | GPR_DUMP_ASCII);
// Add a debug log
gpr_log(GPR_INFO, "TEST: %s", hex);
LOG(INFO) << "TEST: " << hex;
gpr_free(hex);
} else {
gpr_log(GPR_INFO, "TEST: (%" PRIdPTR " byte long string)",
arg->client_payload_length);
LOG(INFO) << "TEST: (" << arg->client_payload_length
<< " byte long string)";
}
grpc_slice slice = grpc_slice_from_copied_buffer(arg->client_payload,
@ -171,9 +171,8 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags,
.type == GRPC_QUEUE_TIMEOUT);
} while (!gpr_event_get(&read_done_event));
if (arg->client_validator(&incoming, arg->client_validator_arg)) break;
gpr_log(GPR_INFO,
"client validator failed; trying additional read "
"in case we didn't get all the data");
LOG(INFO) << "client validator failed; trying additional read "
"in case we didn't get all the data";
}
grpc_slice_buffer_destroy(&incoming);
}
@ -317,7 +316,7 @@ bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* /*arg*/) {
*p++ == 0 || *p++ == 0 || *p++ == 0 || *p == 0 || *p == 11;
if (!success) {
gpr_log(GPR_INFO, "client expected RST_STREAM frame, not found");
LOG(INFO) << "client expected RST_STREAM frame, not found";
}
grpc_slice_buffer_destroy(&last_frame_buffer);

@ -44,6 +44,10 @@ def grpc_bad_client_tests():
hdrs = ["bad_client.h"],
language = "C++",
testonly = 1,
external_deps = [
"absl/log:check",
"absl/log:log",
],
deps = [
"//test/core/test_util:grpc_test_util",
"//:grpc",
@ -51,9 +55,6 @@ def grpc_bad_client_tests():
"//test/core/end2end:cq_verifier",
"//:grpc_http_filters",
],
external_deps = [
"absl/log:check",
],
)
for t, topt in BAD_CLIENT_TESTS.items():
grpc_cc_test(

@ -23,7 +23,10 @@ grpc_cc_binary(
srcs = [
"close_fd_test.cc",
],
external_deps = ["absl/log:check"],
external_deps = [
"absl/log:check",
"absl/log:log",
],
language = "C++",
tags = ["no_windows"],
deps = [

@ -24,6 +24,7 @@
#include <stdint.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_format.h"
@ -53,7 +54,6 @@
#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/gprpp/crash.h"
@ -225,8 +225,8 @@ static void _test_close_before_server_recv(fd_type fdtype) {
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer* response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_recv",
fd_type_str(fdtype));
LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype)
<< "_before_server_recv";
test_init();
grpc_op ops[6];
@ -399,8 +399,8 @@ static void _test_close_before_server_send(fd_type fdtype) {
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer* response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_send",
fd_type_str(fdtype));
LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype)
<< "_before_server_send";
test_init();
grpc_op ops[6];
@ -596,8 +596,8 @@ static void _test_close_before_client_send(fd_type fdtype) {
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer* response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_log(GPR_INFO, "Running test: test_close_%s_before_client_send",
fd_type_str(fdtype));
LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype)
<< "_before_client_send";
test_init();
grpc_op ops[6];

@ -35,6 +35,7 @@ def grpc_bad_ssl_tests():
hdrs = ["server_common.h"],
external_deps = [
"absl/log:check",
"absl/log:log",
],
deps = [
"//test/core/test_util:grpc_test_util",

@ -21,8 +21,8 @@
#include <signal.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "test/core/test_util/cmdline.h"
@ -74,7 +74,7 @@ void bad_ssl_run(grpc_server* server) {
signal(SIGINT, sigint_handler);
while (!shutdown_finished) {
if (got_sigint && !shutdown_started) {
gpr_log(GPR_INFO, "Shutting down due to SIGINT");
LOG(INFO) << "Shutting down due to SIGINT";
shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
grpc_server_shutdown_and_notify(server, shutdown_cq, nullptr);
CHECK(grpc_completion_queue_pluck(shutdown_cq, nullptr,

@ -37,6 +37,7 @@ grpc_cc_test(
srcs = ["channel_args_test.cc"],
external_deps = [
"absl/log:check",
"absl/log:log",
"gtest",
],
language = "C++",
@ -149,6 +150,7 @@ grpc_cc_test(
name = "metrics_test",
srcs = ["metrics_test.cc"],
external_deps = [
"absl/log:log",
"gtest",
],
language = "C++",

@ -21,6 +21,7 @@
#include <string.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "gtest/gtest.h"
#include <grpc/credentials.h>
@ -28,7 +29,6 @@
#include <grpc/grpc_security.h>
#include <grpc/impl/channel_arg_names.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/notification.h"
@ -272,7 +272,7 @@ struct fake_class {
};
static void* fake_pointer_arg_copy(void* arg) {
gpr_log(GPR_DEBUG, "fake_pointer_arg_copy");
VLOG(2) << "fake_pointer_arg_copy";
fake_class* fc = static_cast<fake_class*>(arg);
fake_class* new_fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
new_fc->foo = fc->foo;
@ -280,7 +280,7 @@ static void* fake_pointer_arg_copy(void* arg) {
}
static void fake_pointer_arg_destroy(void* arg) {
gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy");
VLOG(2) << "fake_pointer_arg_destroy";
fake_class* fc = static_cast<fake_class*>(arg);
gpr_free(fc);
}

@ -16,10 +16,7 @@
#include <memory>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/log/log.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -40,15 +37,15 @@ class MetricsTest : public ::testing::Test {
};
TEST_F(MetricsTest, UInt64Counter) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto uint64_counter_handle = GlobalInstrumentsRegistry::RegisterUInt64Counter(
"uint64_counter", "A simple uint64 counter.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
auto uint64_counter_handle =
GlobalInstrumentsRegistry::RegisterUInt64Counter(
"uint64_counter", "A simple uint64 counter.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -58,34 +55,37 @@ TEST_F(MetricsTest, UInt64Counter) {
auto plugin3 = MakeStatsPluginForTarget(kDomain3To4);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""))
.AddCounter(uint64_counter_handle, 1, kLabelValues, kOptionalLabelValues);
.AddCounter(uint64_counter_handle, uint64_t(1), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""))
.AddCounter(uint64_counter_handle, 2, kLabelValues, kOptionalLabelValues);
.AddCounter(uint64_counter_handle, uint64_t(2), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""))
.AddCounter(uint64_counter_handle, 3, kLabelValues, kOptionalLabelValues);
EXPECT_THAT(plugin1->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
.AddCounter(uint64_counter_handle, uint64_t(3), kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin2->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin3->GetCounterValue(uint64_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetUInt64CounterValue(
uint64_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(6));
}
TEST_F(MetricsTest, DoubleCounter) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_counter_handle = GlobalInstrumentsRegistry::RegisterDoubleCounter(
"double_counter", "A simple double counter.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
auto double_counter_handle =
GlobalInstrumentsRegistry::RegisterDoubleCounter(
"double_counter", "A simple double counter.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -105,28 +105,27 @@ TEST_F(MetricsTest, DoubleCounter) {
StatsPluginChannelScope(kDomain3To4, ""))
.AddCounter(double_counter_handle, 3.45, kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin2->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.57));
EXPECT_THAT(plugin3->GetCounterValue(double_counter_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCounterValue(
double_counter_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(7.02));
}
TEST_F(MetricsTest, UInt64Histogram) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto uint64_histogram_handle =
GlobalInstrumentsRegistry::RegisterUInt64Histogram(
"uint64_histogram", "A simple uint64 histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"uint64_histogram", "A simple uint64 histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -136,38 +135,37 @@ TEST_F(MetricsTest, UInt64Histogram) {
auto plugin3 = MakeStatsPluginForTarget(kDomain3To4);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""))
.RecordHistogram(uint64_histogram_handle, 1, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(1), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""))
.RecordHistogram(uint64_histogram_handle, 2, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(2), kLabelValues,
kOptionalLabelValues);
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""))
.RecordHistogram(uint64_histogram_handle, 3, kLabelValues,
.RecordHistogram(uint64_histogram_handle, uint64_t(3), kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1)));
EXPECT_THAT(plugin2->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1, 2)));
EXPECT_THAT(plugin3->GetHistogramValue(uint64_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetUInt64HistogramValue(
uint64_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1, 2, 3)));
}
TEST_F(MetricsTest, DoubleHistogram) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_histogram_handle =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -187,31 +185,30 @@ TEST_F(MetricsTest, DoubleHistogram) {
StatsPluginChannelScope(kDomain3To4, ""))
.RecordHistogram(double_histogram_handle, 3.45, kLabelValues,
kOptionalLabelValues);
EXPECT_THAT(plugin1->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleHistogramValue(
double_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23)));
EXPECT_THAT(plugin2->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleHistogramValue(
double_histogram_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34)));
EXPECT_THAT(
plugin3->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
plugin3->GetDoubleHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34, 3.45)));
}
TEST_F(MetricsTest, Int64CallbackGauge) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto int64_gauge_handle =
GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
"int64_gauge", "A simple int64 gauge.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kLabelValues2[] = {"label_value_3",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"int64_gauge", "A simple int64 gauge.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kLabelValues2 = {"label_value_3",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -221,184 +218,184 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
auto plugin3 = MakeStatsPluginForTarget(kDomain1To4);
// Register two callbacks that set the same metric but with different
// label values. The callbacks get used only by plugin1.
gpr_log(GPR_INFO, "testing callbacks for: plugin1");
LOG(INFO) << "testing callbacks for: plugin1";
auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""));
auto callback1 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 1, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(1), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
auto callback2 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 2, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(2), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// No plugins have data yet.
EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 should have data, but the others should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
callback2.reset();
// Now register callbacks that hit both plugin1 and plugin2.
gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2");
LOG(INFO) << "testing callbacks for: plugin1, plugin2";
auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""));
callback1 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 3, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(3), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
callback2 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 4, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(4), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// Plugin1 still has data from before, but the others have none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
callback2.reset();
// Now register callbacks that hit all three plugins.
gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3");
LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3";
auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""));
callback1 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 5, kLabelValues,
reporter.Report(int64_gauge_handle, int64_t(5), kLabelValues,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
callback2 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(int64_gauge_handle, 6, kLabelValues2,
reporter.Report(int64_gauge_handle, int64_t(6), kLabelValues2,
kOptionalLabelValues);
},
{int64_gauge_handle});
Duration::Seconds(5), int64_gauge_handle);
// Plugin1 and plugin2 still has data from before, but plugin3 has none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue(
int64_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6));
// Need to destroy callbacks before the plugin group that created them.
callback1.reset();
@ -406,18 +403,17 @@ TEST_F(MetricsTest, Int64CallbackGauge) {
}
TEST_F(MetricsTest, DoubleCallbackGauge) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_gauge_handle =
GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
"double_gauge", "A simple double gauge.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kLabelValues2[] = {"label_value_3",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_gauge", "A simple double gauge.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kLabelValues2 = {"label_value_3",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4";
@ -427,7 +423,7 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
auto plugin3 = MakeStatsPluginForTarget(kDomain1To4);
// Register two callbacks that set the same metric but with different
// label values. The callbacks get used only by plugin1.
gpr_log(GPR_INFO, "testing callbacks for: plugin1");
LOG(INFO) << "testing callbacks for: plugin1";
auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain3To4, ""));
auto callback1 = group1.RegisterCallback(
@ -435,60 +431,60 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 1.23, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
auto callback2 = group1.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 2.34, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// No plugins have data yet.
EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 should have data, but the others should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2.34));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
callback2.reset();
// Now register callbacks that hit both plugin1 and plugin2.
gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2");
LOG(INFO) << "testing callbacks for: plugin1, plugin2";
auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain2To4, ""));
callback1 = group2.RegisterCallback(
@ -496,60 +492,60 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 3.45, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
callback2 = group2.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 4.56, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// Plugin1 still has data from before, but the others have none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(1.23));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(2.34));
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// De-register the callbacks.
callback1.reset();
callback2.reset();
// Now register callbacks that hit all three plugins.
gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3");
LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3";
auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
StatsPluginChannelScope(kDomain1To4, ""));
callback1 = group3.RegisterCallback(
@ -557,54 +553,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
reporter.Report(double_gauge_handle, 5.67, kLabelValues,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
callback2 = group3.RegisterCallback(
[&](CallbackMetricReporter& reporter) {
reporter.Report(double_gauge_handle, 6.78, kLabelValues2,
kOptionalLabelValues);
},
{double_gauge_handle});
Duration::Seconds(5), double_gauge_handle);
// Plugin1 and plugin2 still has data from before, but plugin3 has none.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(3.45));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(4.56));
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
absl::nullopt);
EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
absl::nullopt);
// Now invoke the callbacks.
plugin1->TriggerCallbacks();
plugin2->TriggerCallbacks();
plugin3->TriggerCallbacks();
// Now plugin1 and plugin2 should have data, but plugin3 should not.
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues, kOptionalLabelValues),
::testing::Optional(5.67));
EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2,
kOptionalLabelValues),
EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue(
double_gauge_handle, kLabelValues2, kOptionalLabelValues),
::testing::Optional(6.78));
// Need to destroy callbacks before the plugin group that created them.
callback1.reset();
@ -612,16 +608,15 @@ TEST_F(MetricsTest, DoubleCallbackGauge) {
}
TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
auto double_histogram_handle =
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/false);
constexpr absl::string_view kLabelValues[] = {"label_value_1",
"label_value_2"};
constexpr absl::string_view kOptionalLabelValues[] = {
"double_histogram", "A simple double histogram.", "unit", false)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
"label_value_2"};
std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4";
auto plugin = MakeStatsPluginForTarget(kDomain1To4);
@ -629,24 +624,26 @@ TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) {
StatsPluginChannelScope(kDomain1To4, ""))
.RecordHistogram(double_histogram_handle, 1.23, kLabelValues,
kOptionalLabelValues);
EXPECT_EQ(plugin->GetHistogramValue(double_histogram_handle, kLabelValues,
kOptionalLabelValues),
EXPECT_EQ(plugin->GetDoubleHistogramValue(double_histogram_handle,
kLabelValues, kOptionalLabelValues),
absl::nullopt);
}
using MetricsDeathTest = MetricsTest;
TEST_F(MetricsDeathTest, RegisterTheSameMetricNameWouldCrash) {
const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"};
const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1",
"optional_label_key_2"};
(void)GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, true);
EXPECT_DEATH(GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit",
kLabelKeys, kOptionalLabelKeys, true),
"Metric name double_histogram has already been registered.");
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build();
EXPECT_DEATH(
GlobalInstrumentsRegistry::RegisterDoubleHistogram(
"double_histogram", "A simple double histogram.", "unit", true)
.Labels("label_key_1", "label_key_2")
.OptionalLabels("optional_label_key_1", "optional_label_key_2")
.Build(),
"Metric name double_histogram has already been registered.");
}
} // namespace

@ -26,7 +26,10 @@ licenses(["notice"])
grpc_cc_test(
name = "compression_test",
srcs = ["compression_test.cc"],
external_deps = ["gtest"],
external_deps = [
"absl/log:log",
"gtest",
],
language = "C++",
uses_event_engine = False,
uses_polling = False,
@ -67,7 +70,10 @@ grpc_fuzzer(
grpc_cc_test(
name = "message_compress_test",
srcs = ["message_compress_test.cc"],
external_deps = ["gtest"],
external_deps = [
"absl/log:log",
"gtest",
],
language = "C++",
uses_event_engine = False,
uses_polling = False,

@ -21,11 +21,11 @@
#include <memory>
#include "absl/log/log.h"
#include "gtest/gtest.h"
#include <grpc/compression.h>
#include <grpc/slice.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "test/core/test_util/test_config.h"
@ -40,7 +40,7 @@ TEST(CompressionTest, CompressionAlgorithmParse) {
};
const char* invalid_names[] = {"gzip2", "foo", "", "2gzip"};
gpr_log(GPR_DEBUG, "test_compression_algorithm_parse");
VLOG(2) << "test_compression_algorithm_parse";
for (i = 0; i < GPR_ARRAY_SIZE(valid_names); i++) {
const char* valid_name = valid_names[i];
@ -73,7 +73,7 @@ TEST(CompressionTest, CompressionAlgorithmName) {
GRPC_COMPRESS_DEFLATE,
};
gpr_log(GPR_DEBUG, "test_compression_algorithm_name");
VLOG(2) << "test_compression_algorithm_name";
for (i = 0; i < GPR_ARRAY_SIZE(valid_algorithms); i++) {
success = grpc_compression_algorithm_name(valid_algorithms[i], &name);
@ -88,7 +88,7 @@ TEST(CompressionTest, CompressionAlgorithmName) {
}
TEST(CompressionTest, CompressionAlgorithmForLevel) {
gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level");
VLOG(2) << "test_compression_algorithm_for_level";
{
// accept only identity (aka none)
@ -211,7 +211,7 @@ TEST(CompressionTest, CompressionEnableDisableAlgorithm) {
grpc_compression_options options;
grpc_compression_algorithm algorithm;
gpr_log(GPR_DEBUG, "test_compression_enable_disable_algorithm");
VLOG(2) << "test_compression_enable_disable_algorithm";
grpc_compression_options_init(&options);
for (algorithm = GRPC_COMPRESS_NONE;

@ -28,7 +28,6 @@
#include <grpc/compression.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"

@ -199,6 +199,7 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) {
g_mu = new Mutex();
g_client_call_ended_notify = new CoreEnd2endTest::TestNotification(this);
g_server_call_ended_notify = new CoreEnd2endTest::TestNotification(this);
GlobalStatsPluginRegistryTestPeer::ResetGlobalStatsPluginRegistry();
GlobalStatsPluginRegistry::RegisterStatsPlugin(
std::make_shared<NewFakeStatsPlugin>());
auto send_from_client = RandomSlice(10);
@ -265,8 +266,6 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) {
EXPECT_GE(server_transport_stats.incoming.framing_bytes, 32);
EXPECT_LE(server_transport_stats.incoming.framing_bytes, 58);
delete ServerCallTracerFactory::Get(ChannelArgs());
ServerCallTracerFactory::RegisterGlobal(nullptr);
delete g_client_call_ended_notify;
g_client_call_ended_notify = nullptr;
delete g_server_call_ended_notify;

@ -19,6 +19,7 @@
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <tuple>
#include <utility>
#include <vector>
@ -159,6 +160,70 @@ class NotifyOnDelete {
grpc_core::Notification* signal_;
};
// An endpoint implementation that supports Read and Write via std::threads.
// Passing a grpc_core::Notification will allow owners to know when all
// in-flight callbacks have been run, and all endpoint state has been destroyed.
class ThreadedNoopEndpoint : public EventEngine::Endpoint {
public:
explicit ThreadedNoopEndpoint(grpc_core::Notification* destroyed)
: state_(std::make_shared<EndpointState>(destroyed)) {}
~ThreadedNoopEndpoint() override {
std::thread deleter([state = state_]() {
CleanupThread(state->read);
CleanupThread(state->write);
});
deleter.detach();
}
bool Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer,
const ReadArgs* /* args */) override {
buffer->Clear();
CleanupThread(state_->read);
state_->read = new std::thread([cb = std::move(on_read)]() mutable {
cb(absl::UnknownError("test"));
});
return false;
}
bool Write(absl::AnyInvocable<void(absl::Status)> on_writable,
SliceBuffer* data, const WriteArgs* /* args */) override {
data->Clear();
CleanupThread(state_->write);
state_->write = new std::thread([cb = std::move(on_writable)]() mutable {
cb(absl::UnknownError("test"));
});
return false;
}
const EventEngine::ResolvedAddress& GetPeerAddress() const override {
return peer_;
}
const EventEngine::ResolvedAddress& GetLocalAddress() const override {
return local_;
}
private:
struct EndpointState {
explicit EndpointState(grpc_core::Notification* deleter)
: delete_notifier_(deleter) {}
std::thread* read = nullptr;
std::thread* write = nullptr;
NotifyOnDelete delete_notifier_;
};
static void CleanupThread(std::thread* thd) {
if (thd != nullptr) {
thd->join();
delete thd;
}
}
std::shared_ptr<EndpointState> state_;
EventEngine::ResolvedAddress peer_;
EventEngine::ResolvedAddress local_;
};
} // namespace experimental
} // namespace grpc_event_engine

@ -1307,8 +1307,8 @@ TEST_F(PickFirstTest, MetricValues) {
// The first subchannel's connection attempt fails.
subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::UnavailableError("failed to connect"));
EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsFailed,
kLabelValues, {}),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsFailed,
kLabelValues, {}),
::testing::Optional(1));
// The LB policy will start a connection attempt on the second subchannel.
EXPECT_TRUE(subchannel2->ConnectionRequested());
@ -1317,8 +1317,8 @@ TEST_F(PickFirstTest, MetricValues) {
subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING);
// The connection attempt succeeds.
subchannel2->SetConnectivityState(GRPC_CHANNEL_READY);
EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsSucceeded,
kLabelValues, {}),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsSucceeded,
kLabelValues, {}),
::testing::Optional(1));
// The LB policy will report CONNECTING some number of times (doesn't
// matter how many) and then report READY.
@ -1332,8 +1332,9 @@ TEST_F(PickFirstTest, MetricValues) {
subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE);
ExpectReresolutionRequest();
ExpectState(GRPC_CHANNEL_IDLE);
EXPECT_THAT(stats_plugin->GetCounterValue(kDisconnections, kLabelValues, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin->GetUInt64CounterValue(kDisconnections, kLabelValues, {}),
::testing::Optional(1));
}
class PickFirstHealthCheckingEnabledTest : public PickFirstTest {

@ -1113,8 +1113,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
/*qps=*/100.0, /*eps=*/0.0)}},
{{kAddresses[0], 1}, {kAddresses[1], 3}, {kAddresses[2], 3}});
// Check endpoint weights.
EXPECT_THAT(stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetDoubleHistogramValue(
kEndpointWeights, kLabelValues, kOptionalLabelValues),
::testing::Optional(::testing::ElementsAre(
// Picker created for first endpoint becoming READY.
0,
@ -1135,17 +1135,18 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
::testing::DoubleNear(333.333344, 0.000001))));
// RR fallback should trigger for the first 5 updates above, because
// there are less than two endpoints with valid weights.
EXPECT_THAT(stats_plugin->GetCounterValue(kRrFallback, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kRrFallback, kLabelValues,
kOptionalLabelValues),
::testing::Optional(5));
// Endpoint-not-yet-usable will be incremented once for every endpoint
// with weight 0 above.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightNotYetUsable,
kLabelValues, kOptionalLabelValues),
::testing::Optional(10));
EXPECT_THAT(
stats_plugin->GetUInt64CounterValue(kEndpointWeightNotYetUsable,
kLabelValues, kOptionalLabelValues),
::testing::Optional(10));
// There are no stale endpoint weights so far.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(
kEndpointWeightStale, kLabelValues, kOptionalLabelValues),
::testing::Optional(0));
// Advance time to make weights stale and trigger the timer callback
// to recompute weights.
@ -1156,8 +1157,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
picker.get(), {},
{{kAddresses[0], 3}, {kAddresses[1], 3}, {kAddresses[2], 3}});
// All three endpoints should now have stale weights.
EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues,
kOptionalLabelValues),
EXPECT_THAT(stats_plugin->GetUInt64CounterValue(
kEndpointWeightStale, kLabelValues, kOptionalLabelValues),
::testing::Optional(3));
}

@ -125,8 +125,8 @@ void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() {
namespace {
template <typename HandleType>
absl::optional<HandleType> FindInstrument(
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindInstrument(
const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
instruments,
absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type,
@ -134,7 +134,7 @@ absl::optional<HandleType> FindInstrument(
for (const auto& descriptor : instruments) {
if (descriptor.name == name && descriptor.value_type == value_type &&
descriptor.instrument_type == instrument_type) {
HandleType handle;
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle;
handle.index = descriptor.index;
return handle;
}
@ -144,57 +144,51 @@ absl::optional<HandleType> FindInstrument(
} // namespace
absl::optional<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
}
absl::optional<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCounter);
}
absl::optional<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kUInt64,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
}
absl::optional<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName(
absl::string_view name) {
return FindInstrument<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kHistogram);
}
absl::optional<GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName(
absl::string_view name) {
return FindInstrument<
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>(
return FindInstrument(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kInt64,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);
}
absl::optional<GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>
absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName(
absl::string_view name) {
return FindInstrument<
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>(
return FindInstrument(
GlobalInstrumentsRegistry::GetInstrumentList(), name,
GlobalInstrumentsRegistry::ValueType::kDouble,
GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge);

@ -17,6 +17,7 @@
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include "absl/container/flat_hash_map.h"
@ -270,8 +271,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
void AddCounter(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
// The problem with this approach is that we initialize uint64_counters_ in
// BuildAndRegister by querying the GlobalInstrumentsRegistry at the time.
@ -283,7 +284,8 @@ class FakeStatsPlugin : public StatsPlugin {
// GlobalInstrumentsRegistry everytime a metric is recorded. But this is not
// a concern for now.
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%lu, "
"FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%" PRIu64
", "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
@ -294,7 +296,7 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Add(value, label_values, optional_values);
}
void AddCounter(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
@ -309,23 +311,24 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Add(value, label_values, optional_values);
}
void RecordHistogram(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
uint64_t value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%lu, "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
absl::StrJoin(optional_values, ", ").c_str());
gpr_log(
GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%" PRIu64
", "
"label_values={%s}, optional_label_values={%s}",
this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(),
absl::StrJoin(optional_values, ", ").c_str());
MutexLock lock(&mu_);
auto iter = uint64_histograms_.find(handle.index);
if (iter == uint64_histograms_.end()) return;
iter->second.Record(value, label_values, optional_values);
}
void RecordHistogram(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
double value, absl::Span<const absl::string_view> label_values,
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(double)%f, "
@ -358,8 +361,8 @@ class FakeStatsPlugin : public StatsPlugin {
return nullptr;
}
absl::optional<uint64_t> GetCounterValue(
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
absl::optional<uint64_t> GetUInt64CounterValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -369,8 +372,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<double> GetCounterValue(
GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
absl::optional<double> GetDoubleCounterValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -380,8 +383,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<std::vector<uint64_t>> GetHistogramValue(
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
absl::optional<std::vector<uint64_t>> GetUInt64HistogramValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -391,8 +394,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValues(label_values, optional_values);
}
absl::optional<std::vector<double>> GetHistogramValue(
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
absl::optional<std::vector<double>> GetDoubleHistogramValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&mu_);
@ -410,8 +413,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::TriggerCallbacks(): END", this);
}
absl::optional<int64_t> GetCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
absl::optional<int64_t> GetInt64CallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&callback_mu_);
@ -421,8 +424,8 @@ class FakeStatsPlugin : public StatsPlugin {
}
return iter->second.GetValue(label_values, optional_values);
}
absl::optional<double> GetCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
absl::optional<double> GetDoubleCallbackGaugeValue(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) {
MutexLock lock(&callback_mu_);
@ -438,13 +441,14 @@ class FakeStatsPlugin : public StatsPlugin {
public:
explicit Reporter(FakeStatsPlugin& plugin) : plugin_(plugin) {}
void Report(
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle,
int64_t value, absl::Span<const absl::string_view> label_values,
void ReportInt64(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::Reporter::Report(index=%u, "
"value=(uint64)%ld, label_values={%s}, "
"value=(int64_t)%" PRId64
", label_values={%s}, "
"optional_label_values={%s}",
this, handle.index, value,
absl::StrJoin(label_values, ", ").c_str(),
@ -455,9 +459,9 @@ class FakeStatsPlugin : public StatsPlugin {
iter->second.Set(value, label_values, optional_values);
}
void Report(
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle,
double value, absl::Span<const absl::string_view> label_values,
void ReportDouble(
GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value,
absl::Span<const absl::string_view> label_values,
absl::Span<const absl::string_view> optional_values) override {
gpr_log(GPR_INFO,
"FakeStatsPlugin[%p]::Reporter::Report(index=%u, "
@ -654,19 +658,17 @@ class GlobalInstrumentsRegistryTestPeer {
public:
static void ResetGlobalInstrumentsRegistry();
static absl::optional<GlobalInstrumentsRegistry::GlobalUInt64CounterHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64CounterHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalDoubleCounterHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleCounterHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindUInt64HistogramHandleByName(absl::string_view name);
static absl::optional<GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindDoubleHistogramHandleByName(absl::string_view name);
static absl::optional<
GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackInt64GaugeHandleByName(absl::string_view name);
static absl::optional<
GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>
static absl::optional<GlobalInstrumentsRegistry::GlobalInstrumentHandle>
FindCallbackDoubleGaugeHandleByName(absl::string_view name);
static GlobalInstrumentsRegistry::GlobalInstrumentDescriptor*

@ -529,6 +529,7 @@ grpc_cc_test(
srcs = ["client_lb_end2end_test.cc"],
external_deps = [
"absl/log:check",
"absl/log:log",
"gtest",
],
flaky = True, # TODO(b/151315347)
@ -620,6 +621,7 @@ grpc_cc_test(
srcs = ["grpclb_end2end_test.cc"],
external_deps = [
"absl/log:check",
"absl/log:log",
"gtest",
],
flaky = True, # TODO(b/150567713)

@ -26,6 +26,7 @@
#include <gtest/gtest.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
@ -424,7 +425,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
absl::Seconds(0.1))) {}
void Start(const std::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
LOG(INFO) << "starting server on port " << port_;
grpc_core::MutexLock lock(&mu_);
started_ = true;
thread_ = std::make_unique<std::thread>(
@ -433,7 +434,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
cond_.Wait(&mu_);
}
server_ready_ = false;
gpr_log(GPR_INFO, "server startup complete");
LOG(INFO) << "server startup complete";
}
void Serve(const std::string& server_host) {
@ -498,10 +499,8 @@ class ClientLbEnd2endTest : public ::testing::Test {
absl::Duration timeout = absl::Seconds(30)) {
if (stop_index == 0) stop_index = servers_.size();
auto deadline = absl::Now() + (timeout * grpc_test_slowdown_factor());
gpr_log(GPR_INFO,
"========= WAITING FOR BACKENDS [%" PRIuPTR ", %" PRIuPTR
") ==========",
start_index, stop_index);
LOG(INFO) << "========= WAITING FOR BACKENDS [" << start_index << ", "
<< stop_index << ") ==========";
while (!SeenAllServers(start_index, stop_index)) {
Status status = SendRpc(stub);
if (status_check != nullptr) {
@ -636,17 +635,17 @@ TEST_F(ClientLbEnd2endTest, ChannelIdleness) {
// The initial channel state should be IDLE.
EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
// After sending RPC, channel state should be READY.
gpr_log(GPR_INFO, "*** SENDING RPC, CHANNEL SHOULD CONNECT ***");
LOG(INFO) << "*** SENDING RPC, CHANNEL SHOULD CONNECT ***";
response_generator.SetNextResolution(GetServersPorts());
CheckRpcSendOk(DEBUG_LOCATION, stub);
EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
// After a period time not using the channel, the channel state should switch
// to IDLE.
gpr_log(GPR_INFO, "*** WAITING FOR CHANNEL TO GO IDLE ***");
LOG(INFO) << "*** WAITING FOR CHANNEL TO GO IDLE ***";
gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1200));
EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
// Sending a new RPC should awake the IDLE channel.
gpr_log(GPR_INFO, "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***");
LOG(INFO) << "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***";
response_generator.SetNextResolution(GetServersPorts());
CheckRpcSendOk(DEBUG_LOCATION, stub);
EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
@ -830,7 +829,7 @@ TEST_F(PickFirstTest, BackOffInitialReconnect) {
ASSERT_TRUE(WaitForChannelReady(channel.get()));
// Check how long it took.
const grpc_core::Duration waited = grpc_core::Timestamp::Now() - t0;
gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis());
VLOG(2) << "Waited " << waited.millis() << " milliseconds";
// We should have waited at least kInitialBackOffMs. We substract one to
// account for test and precision accuracy drift.
EXPECT_GE(waited.millis(),
@ -861,7 +860,7 @@ TEST_F(PickFirstTest, BackOffMinReconnect) {
const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC);
const grpc_core::Duration waited =
grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0));
gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis());
VLOG(2) << "Waited " << waited.millis() << " milliseconds";
// We should have waited at least kMinReconnectBackOffMs. We substract one to
// account for test and precision accuracy drift.
EXPECT_GE(waited.millis(),
@ -898,7 +897,7 @@ TEST_F(PickFirstTest, ResetConnectionBackoff) {
const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC);
const grpc_core::Duration waited =
grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0));
gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis());
VLOG(2) << "Waited " << waited.millis() << " milliseconds";
// We should have waited less than kInitialBackOffMs.
EXPECT_LT(waited.millis(), kInitialBackOffMs * grpc_test_slowdown_factor());
}
@ -919,33 +918,33 @@ TEST_F(ClientLbEnd2endTest,
response_generator.SetNextResolution({port});
// Intercept initial connection attempt.
auto hold1 = injector.AddHold(port);
gpr_log(GPR_INFO, "=== TRIGGERING INITIAL CONNECTION ATTEMPT");
LOG(INFO) << "=== TRIGGERING INITIAL CONNECTION ATTEMPT";
EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(/*try_to_connect=*/true));
hold1->Wait();
EXPECT_EQ(GRPC_CHANNEL_CONNECTING,
channel->GetState(/*try_to_connect=*/false));
// Reset backoff.
gpr_log(GPR_INFO, "=== RESETTING BACKOFF");
LOG(INFO) << "=== RESETTING BACKOFF";
experimental::ChannelResetConnectionBackoff(channel.get());
// Intercept next attempt. Do this before resuming the first attempt,
// just in case the client makes progress faster than this thread.
auto hold2 = injector.AddHold(port);
// Fail current attempt and wait for next one to start.
gpr_log(GPR_INFO, "=== RESUMING INITIAL ATTEMPT");
LOG(INFO) << "=== RESUMING INITIAL ATTEMPT";
const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC);
hold1->Resume();
gpr_log(GPR_INFO, "=== WAITING FOR SECOND ATTEMPT");
LOG(INFO) << "=== WAITING FOR SECOND ATTEMPT";
// This WaitForStateChange() call just makes sure we're doing some polling.
EXPECT_TRUE(channel->WaitForStateChange(GRPC_CHANNEL_CONNECTING,
grpc_timeout_seconds_to_deadline(1)));
hold2->Wait();
const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_log(GPR_INFO, "=== RESUMING SECOND ATTEMPT");
LOG(INFO) << "=== RESUMING SECOND ATTEMPT";
hold2->Resume();
// Elapsed time should be very short, much less than kInitialBackOffMs.
const grpc_core::Duration waited =
grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0));
gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis());
VLOG(2) << "Waited " << waited.millis() << " milliseconds";
EXPECT_LT(waited.millis(), 1000 * grpc_test_slowdown_factor());
}
@ -958,21 +957,21 @@ TEST_F(PickFirstTest, Updates) {
auto stub = BuildStub(channel);
// Perform one RPC against the first server.
response_generator.SetNextResolution(GetServersPorts(0, 1));
gpr_log(GPR_INFO, "****** SET [0] *******");
LOG(INFO) << "****** SET [0] *******";
CheckRpcSendOk(DEBUG_LOCATION, stub);
EXPECT_EQ(servers_[0]->service_.request_count(), 1);
// An empty update will result in the channel going into TRANSIENT_FAILURE.
response_generator.SetNextResolution({});
gpr_log(GPR_INFO, "****** SET none *******");
LOG(INFO) << "****** SET none *******";
WaitForChannelNotReady(channel.get());
// Next update introduces servers_[1], making the channel recover.
response_generator.SetNextResolution(GetServersPorts(1, 2));
gpr_log(GPR_INFO, "****** SET [1] *******");
LOG(INFO) << "****** SET [1] *******";
WaitForChannelReady(channel.get());
WaitForServer(DEBUG_LOCATION, stub, 1);
// And again for servers_[2]
response_generator.SetNextResolution(GetServersPorts(2, 3));
gpr_log(GPR_INFO, "****** SET [2] *******");
LOG(INFO) << "****** SET [2] *******";
WaitForServer(DEBUG_LOCATION, stub, 2);
// Check LB policy name for the channel.
EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName());
@ -991,7 +990,7 @@ TEST_F(PickFirstTest, UpdateSuperset) {
// Perform one RPC against the first server.
ports.emplace_back(servers_[0]->port_);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** SET [0] *******");
LOG(INFO) << "****** SET [0] *******";
CheckRpcSendOk(DEBUG_LOCATION, stub);
EXPECT_EQ(servers_[0]->service_.request_count(), 1);
servers_[0]->service_.ResetCounters();
@ -1001,7 +1000,7 @@ TEST_F(PickFirstTest, UpdateSuperset) {
ports.emplace_back(servers_[1]->port_);
ports.emplace_back(servers_[0]->port_);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** SET superset *******");
LOG(INFO) << "****** SET superset *******";
CheckRpcSendOk(DEBUG_LOCATION, stub);
// We stick to the previously connected server.
WaitForServer(DEBUG_LOCATION, stub, 0);
@ -1024,7 +1023,7 @@ TEST_F(PickFirstTest, UpdateToUnconnected) {
// Try to send rpcs against a list where the server is available.
ports.emplace_back(servers_[0]->port_);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** SET [0] *******");
LOG(INFO) << "****** SET [0] *******";
CheckRpcSendOk(DEBUG_LOCATION, stub);
// Send resolution for which all servers are currently unavailable. Eventually
@ -1034,12 +1033,12 @@ TEST_F(PickFirstTest, UpdateToUnconnected) {
ports.emplace_back(grpc_pick_unused_port_or_die());
ports.emplace_back(servers_[1]->port_);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** SET [unavailable] *******");
LOG(INFO) << "****** SET [unavailable] *******";
EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
// Ensure that the last resolution was installed correctly by verifying that
// the channel becomes ready once one of if its endpoints becomes available.
gpr_log(GPR_INFO, "****** StartServer(1) *******");
LOG(INFO) << "****** StartServer(1) *******";
StartServer(1);
EXPECT_TRUE(WaitForChannelReady(channel.get()));
}
@ -1135,21 +1134,21 @@ TEST_F(PickFirstTest, ReresolutionNoSelected) {
// The initial resolution only contains dead ports. There won't be any
// selected subchannel. Re-resolution will return the same result.
response_generator.SetNextResolution(dead_ports);
gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******");
LOG(INFO) << "****** INITIAL RESOLUTION SET *******";
for (size_t i = 0; i < 10; ++i) {
CheckRpcSendFailure(
DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE,
MakeConnectionFailureRegex("failed to connect to all addresses"));
}
// PF should request re-resolution.
gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION *******");
LOG(INFO) << "****** WAITING FOR RE-RESOLUTION *******";
EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest(
absl::Seconds(5 * grpc_test_slowdown_factor())));
gpr_log(GPR_INFO, "****** RE-RESOLUTION SEEN *******");
LOG(INFO) << "****** RE-RESOLUTION SEEN *******";
// Send a resolver result that contains reachable ports, so that the
// pick_first LB policy can recover soon.
response_generator.SetNextResolution(alive_ports);
gpr_log(GPR_INFO, "****** RE-RESOLUTION SENT *******");
LOG(INFO) << "****** RE-RESOLUTION SENT *******";
WaitForServer(DEBUG_LOCATION, stub, 0, [](const Status& status) {
EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code());
EXPECT_THAT(status.error_message(),
@ -1169,12 +1168,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResult) {
auto channel = BuildChannel("pick_first", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******");
LOG(INFO) << "****** INITIAL CONNECTION *******";
WaitForServer(DEBUG_LOCATION, stub, 0);
gpr_log(GPR_INFO, "****** STOPPING SERVER ******");
LOG(INFO) << "****** STOPPING SERVER ******";
servers_[0]->Shutdown();
EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
gpr_log(GPR_INFO, "****** RESTARTING SERVER ******");
LOG(INFO) << "****** RESTARTING SERVER ******";
StartServers(1, ports);
WaitForServer(DEBUG_LOCATION, stub, 0);
}
@ -1188,12 +1187,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResultStartsFromTopOfList) {
auto channel = BuildChannel("pick_first", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******");
LOG(INFO) << "****** INITIAL CONNECTION *******";
WaitForServer(DEBUG_LOCATION, stub, 1);
gpr_log(GPR_INFO, "****** STOPPING SERVER ******");
LOG(INFO) << "****** STOPPING SERVER ******";
servers_[1]->Shutdown();
EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******");
LOG(INFO) << "****** STARTING BOTH SERVERS ******";
StartServers(2, ports);
WaitForServer(DEBUG_LOCATION, stub, 0);
}
@ -1202,21 +1201,21 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) {
FakeResolverResponseGeneratorWrapper response_generator;
auto channel = BuildChannel("pick_first", response_generator);
auto stub = BuildStub(channel);
gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******");
LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******";
// Send a resolver result with an empty address list and a callback
// that triggers a notification.
grpc_core::Notification notification;
grpc_core::Resolver::Result result;
result.addresses.emplace();
result.result_health_callback = [&](absl::Status status) {
gpr_log(GPR_INFO, "****** RESULT HEALTH CALLBACK *******");
LOG(INFO) << "****** RESULT HEALTH CALLBACK *******";
EXPECT_EQ(absl::StatusCode::kUnavailable, status.code());
EXPECT_EQ("address list must not be empty", status.message()) << status;
notification.Notify();
};
response_generator.SetResponse(std::move(result));
// Wait for channel to report TRANSIENT_FAILURE.
gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******");
LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******";
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_TRANSIENT_FAILURE;
};
@ -1225,10 +1224,10 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) {
// Callback should run.
notification.WaitForNotification();
// Return a valid address.
gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******");
LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******";
StartServers(1);
response_generator.SetNextResolution(GetServersPorts());
gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******");
LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******";
CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true);
}
@ -1239,22 +1238,22 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) {
auto channel_1 = BuildChannel("pick_first", response_generator);
auto stub_1 = BuildStub(channel_1);
response_generator.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******");
LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 1 *******";
WaitForServer(DEBUG_LOCATION, stub_1, 0);
gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******");
LOG(INFO) << "****** CHANNEL 1 CONNECTED *******";
servers_[0]->Shutdown();
EXPECT_TRUE(WaitForChannelNotReady(channel_1.get()));
// Channel 1 will receive a re-resolution containing the same server. It will
// create a new subchannel and hold a ref to it.
StartServers(1, ports);
gpr_log(GPR_INFO, "****** SERVER RESTARTED *******");
LOG(INFO) << "****** SERVER RESTARTED *******";
FakeResolverResponseGeneratorWrapper response_generator_2;
auto channel_2 = BuildChannel("pick_first", response_generator_2);
auto stub_2 = BuildStub(channel_2);
response_generator_2.SetNextResolution(ports);
gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******");
LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 2 *******";
WaitForServer(DEBUG_LOCATION, stub_2, 0);
gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******");
LOG(INFO) << "****** CHANNEL 2 CONNECTED *******";
servers_[0]->Shutdown();
// Wait until the disconnection has triggered the connectivity notification.
// Otherwise, the subchannel may be picked for next call but will fail soon.
@ -1262,11 +1261,11 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) {
// Channel 2 will also receive a re-resolution containing the same server.
// Both channels will ref the same subchannel that failed.
StartServers(1, ports);
gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******");
gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******");
LOG(INFO) << "****** SERVER RESTARTED AGAIN *******";
LOG(INFO) << "****** CHANNEL 2 STARTING A CALL *******";
// The first call after the server restart will succeed.
CheckRpcSendOk(DEBUG_LOCATION, stub_2);
gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******");
LOG(INFO) << "****** CHANNEL 2 FINISHED A CALL *******";
// Check LB policy name for the channel.
EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName());
// Check LB policy name for the channel.
@ -1411,7 +1410,7 @@ TEST_F(RoundRobinTest, Updates) {
auto channel = BuildChannel("round_robin", response_generator);
auto stub = BuildStub(channel);
// Start with a single server.
gpr_log(GPR_INFO, "*** FIRST BACKEND ***");
LOG(INFO) << "*** FIRST BACKEND ***";
std::vector<int> ports = {servers_[0]->port_};
response_generator.SetNextResolution(ports);
WaitForServer(DEBUG_LOCATION, stub, 0);
@ -1422,7 +1421,7 @@ TEST_F(RoundRobinTest, Updates) {
EXPECT_EQ(0, servers_[2]->service_.request_count());
ResetCounters();
// And now for the second server.
gpr_log(GPR_INFO, "*** SECOND BACKEND ***");
LOG(INFO) << "*** SECOND BACKEND ***";
ports.clear();
ports.emplace_back(servers_[1]->port_);
response_generator.SetNextResolution(ports);
@ -1436,7 +1435,7 @@ TEST_F(RoundRobinTest, Updates) {
EXPECT_EQ(0, servers_[2]->service_.request_count());
ResetCounters();
// ... and for the last server.
gpr_log(GPR_INFO, "*** THIRD BACKEND ***");
LOG(INFO) << "*** THIRD BACKEND ***";
ports.clear();
ports.emplace_back(servers_[2]->port_);
response_generator.SetNextResolution(ports);
@ -1447,7 +1446,7 @@ TEST_F(RoundRobinTest, Updates) {
EXPECT_EQ(10, servers_[2]->service_.request_count());
ResetCounters();
// Back to all servers.
gpr_log(GPR_INFO, "*** ALL BACKENDS ***");
LOG(INFO) << "*** ALL BACKENDS ***";
ports.clear();
ports.emplace_back(servers_[0]->port_);
ports.emplace_back(servers_[1]->port_);
@ -1461,7 +1460,7 @@ TEST_F(RoundRobinTest, Updates) {
EXPECT_EQ(1, servers_[2]->service_.request_count());
ResetCounters();
// An empty update will result in the channel going into TRANSIENT_FAILURE.
gpr_log(GPR_INFO, "*** NO BACKENDS ***");
LOG(INFO) << "*** NO BACKENDS ***";
ports.clear();
response_generator.SetNextResolution(ports);
WaitForChannelNotReady(channel.get());
@ -1469,7 +1468,7 @@ TEST_F(RoundRobinTest, Updates) {
"empty address list: fake resolver empty address list");
servers_[0]->service_.ResetCounters();
// Next update introduces servers_[1], making the channel recover.
gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***");
LOG(INFO) << "*** BACK TO SECOND BACKEND ***";
ports.clear();
ports.emplace_back(servers_[1]->port_);
response_generator.SetNextResolution(ports);
@ -1550,15 +1549,15 @@ TEST_F(RoundRobinTest, ReresolveOnSubchannelConnectionFailure) {
// Wait for both servers to be seen.
WaitForServers(DEBUG_LOCATION, stub, 0, 2);
// Have server 0 send a GOAWAY. This should trigger a re-resolution.
gpr_log(GPR_INFO, "****** SENDING GOAWAY FROM SERVER 0 *******");
LOG(INFO) << "****** SENDING GOAWAY FROM SERVER 0 *******";
{
grpc_core::ExecCtx exec_ctx;
grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways();
}
gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION REQUEST *******");
LOG(INFO) << "****** WAITING FOR RE-RESOLUTION REQUEST *******";
EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest(
absl::Seconds(5 * grpc_test_slowdown_factor())));
gpr_log(GPR_INFO, "****** RE-RESOLUTION REQUEST SEEN *******");
LOG(INFO) << "****** RE-RESOLUTION REQUEST SEEN *******";
// Tell the fake resolver to send an update that adds the last server, but
// only when the LB policy requests re-resolution.
ports.push_back(servers_[2]->port_);
@ -1571,7 +1570,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) {
FakeResolverResponseGeneratorWrapper response_generator;
auto channel = BuildChannel("round_robin", response_generator);
auto stub = BuildStub(channel);
gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******");
LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******";
// Send a resolver result with an empty address list and a callback
// that triggers a notification.
grpc_core::Notification notification;
@ -1585,7 +1584,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) {
};
response_generator.SetResponse(std::move(result));
// Wait for channel to report TRANSIENT_FAILURE.
gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******");
LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******";
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_TRANSIENT_FAILURE;
};
@ -1594,10 +1593,10 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) {
// Callback should have been run.
notification.WaitForNotification();
// Return a valid address.
gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******");
LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******";
StartServers(1);
response_generator.SetNextResolution(GetServersPorts());
gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******");
LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******";
CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true);
}
@ -1658,7 +1657,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) {
response_generator.SetNextResolution({port});
// Allow first connection attempt to fail normally, and wait for
// channel to report TRANSIENT_FAILURE.
gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO REPORT TF ===");
LOG(INFO) << "=== WAITING FOR CHANNEL TO REPORT TF ===";
auto predicate = [](grpc_connectivity_state state) {
return state == GRPC_CHANNEL_TRANSIENT_FAILURE;
};
@ -1673,7 +1672,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) {
EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel->GetState(false));
// Send a few RPCs, just to give the channel a chance to propagate a
// new picker, in case it was going to incorrectly do so.
gpr_log(GPR_INFO, "=== EXPECTING RPCs TO FAIL ===");
LOG(INFO) << "=== EXPECTING RPCs TO FAIL ===";
for (size_t i = 0; i < 5; ++i) {
CheckRpcSendFailure(
DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE,
@ -1718,7 +1717,7 @@ TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) {
"Survey says... Bzzzzt!"))(status.error_message())) {
break;
}
gpr_log(GPR_INFO, "STATUS MESSAGE: %s", status.error_message().c_str());
LOG(INFO) << "STATUS MESSAGE: " << status.error_message();
EXPECT_THAT(status.error_message(),
::testing::MatchesRegex(MakeConnectionFailureRegex(
"connections to all backends failing")));
@ -1740,21 +1739,21 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) {
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
// Start a thread constantly sending RPCs in a loop.
gpr_log(GPR_INFO, "=== STARTING CLIENT THREAD ===");
LOG(INFO) << "=== STARTING CLIENT THREAD ===";
std::atomic<bool> shutdown{false};
gpr_event ev;
gpr_event_init(&ev);
std::thread thd([&]() {
gpr_log(GPR_INFO, "sending first RPC");
LOG(INFO) << "sending first RPC";
CheckRpcSendOk(DEBUG_LOCATION, stub);
gpr_event_set(&ev, reinterpret_cast<void*>(1));
while (!shutdown.load()) {
gpr_log(GPR_INFO, "sending RPC");
LOG(INFO) << "sending RPC";
CheckRpcSendOk(DEBUG_LOCATION, stub);
}
});
// Wait for first RPC to complete.
gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO COMPLETE ===");
LOG(INFO) << "=== WAITING FOR FIRST RPC TO COMPLETE ===";
ASSERT_EQ(reinterpret_cast<void*>(1),
gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(1)));
// Channel should now be READY.
@ -1765,7 +1764,7 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) {
// Now kill the server. The subchannel should report IDLE and be
// immediately reconnected to, but this should not cause any test
// failures.
gpr_log(GPR_INFO, "=== SHUTTING DOWN SERVER ===");
LOG(INFO) << "=== SHUTTING DOWN SERVER ===";
{
grpc_core::ExecCtx exec_ctx;
grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways();
@ -1773,17 +1772,17 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) {
gpr_sleep_until(grpc_timeout_seconds_to_deadline(1));
servers_[0]->Shutdown();
// Wait for next attempt to start.
gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT ===");
LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT ===";
hold1->Wait();
// Start server and allow attempt to continue.
gpr_log(GPR_INFO, "=== RESTARTING SERVER ===");
LOG(INFO) << "=== RESTARTING SERVER ===";
StartServer(0);
hold1->Resume();
// Wait for next attempt to complete.
gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ===");
LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ===";
hold1->WaitForCompletion();
// Now shut down the thread.
gpr_log(GPR_INFO, "=== SHUTTING DOWN CLIENT THREAD ===");
LOG(INFO) << "=== SHUTTING DOWN CLIENT THREAD ===";
shutdown.store(true);
thd.join();
}
@ -1871,14 +1870,13 @@ TEST_F(RoundRobinTest, HealthChecking) {
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
// Channel should not become READY, because health checks should be failing.
gpr_log(GPR_INFO,
"*** initial state: unknown health check service name for "
"all servers");
LOG(INFO)
<< "*** initial state: unknown health check service name for all servers";
EXPECT_FALSE(WaitForChannelReady(channel.get(), 1));
// Now set one of the servers to be healthy.
// The channel should become healthy and all requests should go to
// the healthy server.
gpr_log(GPR_INFO, "*** server 0 healthy");
LOG(INFO) << "*** server 0 healthy";
servers_[0]->SetServingStatus("health_check_service_name", true);
EXPECT_TRUE(WaitForChannelReady(channel.get()));
// New channel state may be reported before the picker is updated, so
@ -1891,7 +1889,7 @@ TEST_F(RoundRobinTest, HealthChecking) {
EXPECT_EQ(0, servers_[1]->service_.request_count());
EXPECT_EQ(0, servers_[2]->service_.request_count());
// Now set a second server to be healthy.
gpr_log(GPR_INFO, "*** server 2 healthy");
LOG(INFO) << "*** server 2 healthy";
servers_[2]->SetServingStatus("health_check_service_name", true);
WaitForServer(DEBUG_LOCATION, stub, 2);
for (int i = 0; i < 10; ++i) {
@ -1901,7 +1899,7 @@ TEST_F(RoundRobinTest, HealthChecking) {
EXPECT_EQ(0, servers_[1]->service_.request_count());
EXPECT_EQ(5, servers_[2]->service_.request_count());
// Now set the remaining server to be healthy.
gpr_log(GPR_INFO, "*** server 1 healthy");
LOG(INFO) << "*** server 1 healthy";
servers_[1]->SetServingStatus("health_check_service_name", true);
WaitForServer(DEBUG_LOCATION, stub, 1);
for (int i = 0; i < 9; ++i) {
@ -1914,7 +1912,7 @@ TEST_F(RoundRobinTest, HealthChecking) {
// unhealthiness has hit the client. We know that the client will see
// this when we send kNumServers requests and one of the remaining servers
// sees two of the requests.
gpr_log(GPR_INFO, "*** server 0 unhealthy");
LOG(INFO) << "*** server 0 unhealthy";
servers_[0]->SetServingStatus("health_check_service_name", false);
do {
ResetCounters();
@ -1925,7 +1923,7 @@ TEST_F(RoundRobinTest, HealthChecking) {
servers_[2]->service_.request_count() != 2);
// Now set the remaining two servers to be unhealthy. Make sure the
// channel leaves READY state and that RPCs fail.
gpr_log(GPR_INFO, "*** all servers unhealthy");
LOG(INFO) << "*** all servers unhealthy";
servers_[1]->SetServingStatus("health_check_service_name", false);
servers_[2]->SetServingStatus("health_check_service_name", false);
EXPECT_TRUE(WaitForChannelNotReady(channel.get()));

@ -27,6 +27,7 @@
#include "absl/cleanup/cleanup.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
@ -225,7 +226,7 @@ class BalancerServiceImpl : public BalancerService {
shutdown_ = true;
}
ShutdownStream();
gpr_log(GPR_INFO, "LB[%p]: shut down", this);
LOG(INFO) << "LB[" << this << "]: shut down";
}
void set_client_load_reporting_interval_seconds(int seconds) {
@ -285,11 +286,11 @@ class BalancerServiceImpl : public BalancerService {
private:
// Request handler.
Status BalanceLoad(ServerContext* context, Stream* stream) override {
gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this);
LOG(INFO) << "LB[" << this << "]: BalanceLoad";
{
grpc_core::MutexLock lock(&mu_);
if (shutdown_) {
gpr_log(GPR_INFO, "LB[%p]: shutdown at stream start", this);
LOG(INFO) << "LB[" << this << "]: shutdown at stream start";
return Status::OK;
}
}
@ -310,7 +311,7 @@ class BalancerServiceImpl : public BalancerService {
// Read initial request.
LoadBalanceRequest request;
if (!stream->Read(&request)) {
gpr_log(GPR_INFO, "LB[%p]: stream read returned false", this);
LOG(INFO) << "LB[" << this << "]: stream read returned false";
return Status::OK;
}
EXPECT_TRUE(request.has_initial_request());
@ -319,8 +320,8 @@ class BalancerServiceImpl : public BalancerService {
service_names_.push_back(request.initial_request().name());
}
IncreaseRequestCount();
gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this,
request.DebugString().c_str());
LOG(INFO) << "LB[" << this << "]: received initial message '"
<< request.DebugString() << "'";
// Send initial response.
LoadBalanceResponse response;
auto* initial_response = response.mutable_initial_response();
@ -334,11 +335,11 @@ class BalancerServiceImpl : public BalancerService {
std::thread reader(std::bind(&BalancerServiceImpl::ReadThread, this, stream,
&reader_shutdown));
auto thread_cleanup = absl::MakeCleanup([&]() {
gpr_log(GPR_INFO, "shutting down reader thread");
LOG(INFO) << "shutting down reader thread";
reader_shutdown.Notify();
gpr_log(GPR_INFO, "joining reader thread");
LOG(INFO) << "joining reader thread";
reader.join();
gpr_log(GPR_INFO, "joining reader thread complete");
LOG(INFO) << "joining reader thread complete";
});
// Send responses as instructed by the test.
while (true) {
@ -347,12 +348,12 @@ class BalancerServiceImpl : public BalancerService {
context->TryCancel();
break;
}
gpr_log(GPR_INFO, "LB[%p]: Sending response: %s", this,
response->DebugString().c_str());
LOG(INFO) << "LB[" << this
<< "]: Sending response: " << response->DebugString();
IncreaseResponseCount();
stream->Write(*response);
}
gpr_log(GPR_INFO, "LB[%p]: done", this);
LOG(INFO) << "LB[" << this << "]: done";
return Status::OK;
}
@ -360,8 +361,8 @@ class BalancerServiceImpl : public BalancerService {
void ReadThread(Stream* stream, absl::Notification* shutdown) {
LoadBalanceRequest request;
while (!shutdown->HasBeenNotified() && stream->Read(&request)) {
gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'",
this, request.DebugString().c_str());
LOG(INFO) << "LB[" << this << "]: received client load report message '"
<< request.DebugString() << "'";
EXPECT_GT(client_load_reporting_interval_seconds_, 0);
EXPECT_TRUE(request.has_client_stats());
ClientStats load_report;
@ -451,7 +452,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
~ServerThread() { Shutdown(); }
void Start() {
gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_);
LOG(INFO) << "starting " << type_ << " server on port " << port_;
CHECK(!running_);
running_ = true;
service_.Start();
@ -463,7 +464,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
thread_ = std::make_unique<std::thread>(
std::bind(&ServerThread::Serve, this, &mu, &cond));
cond.Wait(&mu);
gpr_log(GPR_INFO, "%s server startup complete", type_.c_str());
LOG(INFO) << type_ << " server startup complete";
}
void Serve(grpc_core::Mutex* mu, grpc_core::CondVar* cond) {
@ -481,11 +482,11 @@ class GrpclbEnd2endTest : public ::testing::Test {
void Shutdown() {
if (!running_) return;
gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str());
LOG(INFO) << type_ << " about to shutdown";
service_.Shutdown();
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
thread_->join();
gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str());
LOG(INFO) << type_ << " shutdown completed";
running_ = false;
}
@ -667,8 +668,8 @@ class GrpclbEnd2endTest : public ::testing::Test {
size_t start_index = 0, size_t stop_index = 0,
WaitForBackendOptions options = WaitForBackendOptions(),
SourceLocation location = SourceLocation()) {
gpr_log(GPR_INFO, "Waiting for backends [%" PRIuPTR ", %" PRIuPTR ")",
start_index, stop_index);
LOG(INFO) << "Waiting for backends [" << start_index << ", " << stop_index
<< ")";
const absl::Time deadline =
absl::Now() +
absl::Seconds(options.timeout_seconds * grpc_test_slowdown_factor());
@ -689,11 +690,11 @@ class GrpclbEnd2endTest : public ::testing::Test {
SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops);
}
ResetBackendCounters();
gpr_log(GPR_INFO,
"Performed %d warm up requests (a multiple of %d) against the "
"backends. %d succeeded, %d failed, %d dropped.",
num_total, options.num_requests_multiple_of, num_ok, num_failure,
num_drops);
LOG(INFO) << "Performed " << num_total
<< " warm up requests (a multiple of "
<< options.num_requests_multiple_of << ") against the backends. "
<< num_ok << " succeeded, " << num_failure << " failed, "
<< num_drops << " dropped.";
return std::make_tuple(num_ok, num_failure, num_drops);
}
@ -1299,9 +1300,9 @@ TEST_F(GrpclbEnd2endTest,
SetNextResolutionDefaultBalancer();
WaitForBackend(0);
// Send 10 requests.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
LOG(INFO) << "========= BEFORE FIRST BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
LOG(INFO) << "========= DONE WITH FIRST BATCH ==========";
// All 10 requests should have gone to the first backend.
EXPECT_EQ(10U, backends_[0]->service().request_count());
EXPECT_EQ(0U, backends_[1]->service().request_count());
@ -1314,9 +1315,9 @@ TEST_F(GrpclbEnd2endTest,
// Now tell the channel to use balancer 2. However, the stream to the
// default balancer is not terminated, so the client will continue to
// use it.
gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 ==========");
LOG(INFO) << "========= ABOUT TO UPDATE 1 ==========";
SetNextResolution({balancer2->port()});
gpr_log(GPR_INFO, "========= UPDATE 1 DONE ==========");
LOG(INFO) << "========= UPDATE 1 DONE ==========";
// Now the default balancer sends backend 2.
SendBalancerResponse(BuildResponseForBackends({backends_[2]->port()}, {}));
WaitForBackend(2);
@ -1339,9 +1340,9 @@ TEST_F(GrpclbEnd2endTest,
// Wait until the first backend is ready.
WaitForBackend(0);
// Send 10 requests.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
LOG(INFO) << "========= BEFORE FIRST BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
LOG(INFO) << "========= DONE WITH FIRST BATCH ==========";
// All 10 requests should have gone to the first backend.
EXPECT_EQ(10U, backends_[0]->service().request_count());
EXPECT_EQ(0U, backends_[1]->service().request_count());
@ -1351,15 +1352,15 @@ TEST_F(GrpclbEnd2endTest,
EXPECT_EQ(0U, balancer2->service().request_count());
EXPECT_EQ(0U, balancer2->service().response_count());
// Send another address list with the same list of balancers.
gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 ==========");
LOG(INFO) << "========= ABOUT TO UPDATE 1 ==========";
SetNextResolution({balancer_->port(), balancer2->port()});
gpr_log(GPR_INFO, "========= UPDATE 1 DONE ==========");
LOG(INFO) << "========= UPDATE 1 DONE ==========";
// Shut down the balancer stream to force the client to create a new one.
// The new stream should go to the default balancer, since the
// underlying connection should not have been broken.
gpr_log(GPR_INFO, "========= SHUTTING DOWN BALANCER CALL ==========");
LOG(INFO) << "========= SHUTTING DOWN BALANCER CALL ==========";
balancer_->service().ShutdownStream();
gpr_log(GPR_INFO, "========= DONE SHUTTING DOWN BALANCER CALL ==========");
LOG(INFO) << "========= DONE SHUTTING DOWN BALANCER CALL ==========";
// Wait until client has created a new balancer stream.
EXPECT_TRUE(balancer_->service().WaitForNewStream(1));
// Make sure there was only one client connection seen by the balancer.
@ -1383,34 +1384,34 @@ TEST_F(GrpclbEnd2endTest, BalancerDiesThenSwitchToNewBalancer) {
EXPECT_EQ(0U, balancer2->service().request_count());
EXPECT_EQ(0U, balancer2->service().response_count());
// Send 10 RPCs.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
LOG(INFO) << "========= BEFORE FIRST BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
LOG(INFO) << "========= DONE WITH FIRST BATCH ==========";
// All 10 requests should have gone to the first backend.
EXPECT_EQ(10U, backends_[0]->service().request_count());
EXPECT_EQ(0U, backends_[1]->service().request_count());
// Kill default balancer.
gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER *************");
LOG(INFO) << "********** ABOUT TO KILL BALANCER *************";
balancer_->Shutdown();
gpr_log(GPR_INFO, "********** KILLED BALANCER *************");
LOG(INFO) << "********** KILLED BALANCER *************";
// Channel should continue using the last backend it saw from the
// balancer before the balancer died.
gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
LOG(INFO) << "========= BEFORE SECOND BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
LOG(INFO) << "========= DONE WITH SECOND BATCH ==========";
// All 10 requests should again have gone to the first backend.
EXPECT_EQ(20U, backends_[0]->service().request_count());
EXPECT_EQ(0U, backends_[1]->service().request_count());
// Tell channel to start using balancer 2.
gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 ==========");
LOG(INFO) << "========= ABOUT TO UPDATE 1 ==========";
SetNextResolution({balancer2->port()});
gpr_log(GPR_INFO, "========= UPDATE 1 DONE ==========");
LOG(INFO) << "========= UPDATE 1 DONE ==========";
// Channel should start using backend 1.
WaitForBackend(1);
// This is serviced by the updated RR policy
gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH ==========");
LOG(INFO) << "========= BEFORE THIRD BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH ==========");
LOG(INFO) << "========= DONE WITH THIRD BATCH ==========";
// All 10 requests should have gone to the second backend.
EXPECT_EQ(0U, backends_[0]->service().request_count());
EXPECT_EQ(10U, backends_[1]->service().request_count());
@ -1428,15 +1429,15 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) {
// responds, and a fallback backend.
SetNextResolution({balancer_->port()}, {backends_[0]->port()});
// Start servers and send 10 RPCs per server.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
LOG(INFO) << "========= BEFORE FIRST BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
LOG(INFO) << "========= DONE WITH FIRST BATCH ==========";
// All 10 requests should have gone to the fallback backend.
EXPECT_EQ(10U, backends_[0]->service().request_count());
// Kill backend 0.
gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************");
LOG(INFO) << "********** ABOUT TO KILL BACKEND 0 *************";
backends_[0]->Shutdown();
gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************");
LOG(INFO) << "********** KILLED BACKEND 0 *************";
// This should trigger re-resolution.
EXPECT_TRUE(response_generator_->WaitForReresolutionRequest(
absl::Seconds(5 * grpc_test_slowdown_factor())));
@ -1446,9 +1447,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) {
// Wait until re-resolution has been seen, as signaled by the second backend
// receiving a request.
WaitForBackend(1);
gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
LOG(INFO) << "========= BEFORE SECOND BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
LOG(INFO) << "========= DONE WITH SECOND BATCH ==========";
// All 10 requests should have gone to the second backend.
EXPECT_EQ(10U, backends_[1]->service().request_count());
EXPECT_EQ(1U, balancer_->service().request_count());
@ -1467,9 +1468,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) {
SetNextResolutionDefaultBalancer();
WaitForBackend(0);
// Send 10 RPCs.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
LOG(INFO) << "========= BEFORE FIRST BATCH ==========";
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
LOG(INFO) << "========= DONE WITH FIRST BATCH ==========";
// All 10 requests should have gone to the first backend.
EXPECT_EQ(10U, backends_[0]->service().request_count());
// Balancer 0 got a single request and sent a single request.
@ -1478,13 +1479,13 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) {
EXPECT_EQ(0U, balancer2->service().request_count());
EXPECT_EQ(0U, balancer2->service().response_count());
// Kill balancer 0.
gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************");
LOG(INFO) << "********** ABOUT TO KILL BALANCER 0 *************";
balancer_->Shutdown();
gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************");
LOG(INFO) << "********** KILLED BALANCER 0 *************";
// This should trigger a re-resolution.
EXPECT_TRUE(response_generator_->WaitForReresolutionRequest(
absl::Seconds(5 * grpc_test_slowdown_factor())));
gpr_log(GPR_INFO, "********** SAW RE-RESOLUTION REQUEST *************");
LOG(INFO) << "********** SAW RE-RESOLUTION REQUEST *************";
// Re-resolution result switches to balancer 2.
SetNextResolution({balancer2->port()});
// Client should start using backend 1.

@ -1535,24 +1535,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 0);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
absl::nullopt);
EXPECT_EQ(stats_plugin_->GetCounterValue(
EXPECT_EQ(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
absl::nullopt);
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(1));
auto cache_size = stats_plugin_->GetCallbackGaugeValue(
auto cache_size = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size, ::testing::Optional(::testing::Ge(1)));
@ -1567,24 +1567,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 1);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
::testing::Optional(1));
EXPECT_EQ(stats_plugin_->GetCounterValue(
EXPECT_EQ(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
absl::nullopt);
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(2));
auto cache_size2 = stats_plugin_->GetCallbackGaugeValue(
auto cache_size2 = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size2, ::testing::Optional(::testing::Ge(2)));
@ -1611,24 +1611,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) {
EXPECT_EQ(backends_[1]->service_.request_count(), 1);
// Check exported metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target0, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricTargetPicks,
{target_uri_, rls_server_target_, rls_target1, "complete"}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(
kMetricFailedPicks, {target_uri_, rls_server_target_}, {}),
::testing::Optional(1));
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheEntries,
{target_uri_, rls_server_target_, kRlsInstanceUuid}, {}),
::testing::Optional(3));
auto cache_size3 = stats_plugin_->GetCallbackGaugeValue(
auto cache_size3 = stats_plugin_->GetInt64CallbackGaugeValue(
kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid},
{});
EXPECT_THAT(cache_size3, ::testing::Optional(::testing::Ge(3)));
@ -1678,7 +1678,7 @@ TEST_F(RlsMetricsEnd2endTest, MetricValuesDefaultTargetRpcs) {
EXPECT_EQ(backends_[0]->service_.request_count(), 1);
// Check expected metrics.
EXPECT_THAT(
stats_plugin_->GetCounterValue(
stats_plugin_->GetUInt64CounterValue(
kMetricDefaultTargetPicks,
{target_uri_, rls_server_target_, default_target, "complete"}, {}),
::testing::Optional(1));

@ -25,7 +25,10 @@ grpc_cc_library(
name = "xds_server",
srcs = ["xds_server.cc"],
hdrs = ["xds_server.h"],
external_deps = ["absl/log:check"],
external_deps = [
"absl/log:check",
"absl/log:log",
],
visibility = ["@grpc:xds_end2end_test_utils"],
deps = [
"//:gpr",
@ -349,6 +352,7 @@ grpc_cc_test(
srcs = ["xds_ring_hash_end2end_test.cc"],
external_deps = [
"absl/log:check",
"absl/log:log",
"gtest",
],
flaky = True, # TODO(b/144705388)

@ -1217,11 +1217,11 @@ TEST_P(XdsMetricsTest, MetricValues) {
CheckRpcSendOk(DEBUG_LOCATION);
stats_plugin_->TriggerCallbacks();
// Check client metrics.
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{kTarget, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {kTarget, kXdsServer}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure,
{kTarget, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure,
{kTarget, kXdsServer}, {}),
absl::nullopt);
for (absl::string_view type_url :
{"envoy.config.listener.v3.Listener",
@ -1229,37 +1229,37 @@ TEST_P(XdsMetricsTest, MetricValues) {
"envoy.config.cluster.v3.Cluster",
"envoy.config.endpoint.v3.ClusterLoadAssignment"}) {
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid,
{kTarget, kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesValid, {kTarget, kXdsServer, type_url}, {}),
::testing::Optional(1));
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid,
{kTarget, kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesInvalid, {kTarget, kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricResources, {kTarget, "#old", type_url, "acked"}, {}),
::testing::Optional(1));
}
// Check server metrics.
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{"#server", kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {"#server", kXdsServer}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure,
{"#server", kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure,
{"#server", kXdsServer}, {}),
absl::nullopt);
for (absl::string_view type_url :
{"envoy.config.listener.v3.Listener",
"envoy.config.route.v3.RouteConfiguration"}) {
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid,
{"#server", kXdsServer, type_url}, {}),
stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesValid, {"#server", kXdsServer, type_url}, {}),
::testing::Optional(1));
EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(
kMetricResourceUpdatesInvalid,
{"#server", kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(
stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid,
{"#server", kXdsServer, type_url}, {}),
::testing::Optional(0));
EXPECT_THAT(
stats_plugin_->GetCallbackGaugeValue(
stats_plugin_->GetInt64CallbackGaugeValue(
kMetricResources, {"#server", "#old", type_url, "acked"}, {}),
::testing::Optional(1));
}
@ -1269,8 +1269,8 @@ TEST_P(XdsMetricsTest, MetricValues) {
const absl::Time deadline =
absl::Now() + absl::Seconds(5 * grpc_test_slowdown_factor());
while (true) {
auto value = stats_plugin_->GetCounterValue(kMetricServerFailure,
{target, kXdsServer}, {});
auto value = stats_plugin_->GetUInt64CounterValue(
kMetricServerFailure, {target, kXdsServer}, {});
if (value.has_value()) {
EXPECT_EQ(1, *value);
break;
@ -1279,8 +1279,8 @@ TEST_P(XdsMetricsTest, MetricValues) {
absl::SleepFor(absl::Seconds(1));
}
stats_plugin_->TriggerCallbacks();
EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected,
{target, kXdsServer}, {}),
EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue(
kMetricConnected, {target, kXdsServer}, {}),
::testing::Optional(0));
}
}

@ -20,6 +20,7 @@
#include <gtest/gtest.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
@ -313,14 +314,14 @@ TEST_P(RingHashTest,
// Allow the connection attempt to complete.
hold->Resume();
// Now the RPCs should complete successfully.
gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO FINISH ===");
LOG(INFO) << "=== WAITING FOR FIRST RPC TO FINISH ===";
Status status = rpc.GetStatus();
gpr_log(GPR_INFO, "=== FIRST RPC FINISHED ===");
LOG(INFO) << "=== FIRST RPC FINISHED ===";
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
gpr_log(GPR_INFO, "=== WAITING FOR SECOND RPC TO FINISH ===");
LOG(INFO) << "=== WAITING FOR SECOND RPC TO FINISH ===";
status = rpc2.GetStatus();
gpr_log(GPR_INFO, "=== SECOND RPC FINISHED ===");
LOG(INFO) << "=== SECOND RPC FINISHED ===";
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
}
@ -1033,24 +1034,24 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) {
.set_metadata(std::move(metadata))
.set_timeout_ms(kConnectionTimeoutMilliseconds);
EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
gpr_log(GPR_INFO, "=== SENDING FIRST RPC ===");
LOG(INFO) << "=== SENDING FIRST RPC ===";
CheckRpcSendFailure(
DEBUG_LOCATION, StatusCode::UNAVAILABLE,
MakeConnectionFailureRegex(
"ring hash cannot find a connected endpoint; first failure: "),
rpc_options);
gpr_log(GPR_INFO, "=== DONE WITH FIRST RPC ===");
LOG(INFO) << "=== DONE WITH FIRST RPC ===";
EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false));
// Bring up backend 0. The channel should become connected without
// any picks, because in TF, we are always trying to connect to at
// least one backend at all times.
gpr_log(GPR_INFO, "=== STARTING BACKEND 0 ===");
LOG(INFO) << "=== STARTING BACKEND 0 ===";
StartBackend(0);
gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ===");
LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ===";
EXPECT_TRUE(channel_->WaitForConnected(
grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds)));
// RPCs should go to backend 0.
gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 0 ===");
LOG(INFO) << "=== WAITING FOR BACKEND 0 ===";
WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
WaitForBackendOptions(), rpc_options);
EXPECT_EQ(GRPC_CHANNEL_READY, channel_->GetState(false));
@ -1062,28 +1063,28 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) {
// Since the the entries in the ring are pretty distributed and we have
// unused ports to fill the ring, it is almost guaranteed that the Picker
// will go through some non-READY entries and skip them as per design.
gpr_log(GPR_INFO, "=== SHUTTING DOWN BACKEND 0 ===");
LOG(INFO) << "=== SHUTTING DOWN BACKEND 0 ===";
ShutdownBackend(0);
gpr_log(GPR_INFO, "=== WAITING FOR STATE CHANGE ===");
LOG(INFO) << "=== WAITING FOR STATE CHANGE ===";
EXPECT_TRUE(channel_->WaitForStateChange(
GRPC_CHANNEL_READY,
grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds)));
EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false));
gpr_log(GPR_INFO, "=== SENDING SECOND RPC ===");
LOG(INFO) << "=== SENDING SECOND RPC ===";
CheckRpcSendFailure(
DEBUG_LOCATION, StatusCode::UNAVAILABLE,
MakeConnectionFailureRegex(
"ring hash cannot find a connected endpoint; first failure: "),
rpc_options);
gpr_log(GPR_INFO, "=== STARTING BACKEND 1 ===");
LOG(INFO) << "=== STARTING BACKEND 1 ===";
StartBackend(1);
gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ===");
LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ===";
EXPECT_TRUE(channel_->WaitForConnected(
grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds)));
gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 1 ===");
LOG(INFO) << "=== WAITING FOR BACKEND 1 ===";
WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
WaitForBackendOptions(), rpc_options);
gpr_log(GPR_INFO, "=== DONE ===");
LOG(INFO) << "=== DONE ===";
}
// This tests a bug seen in the wild where ring_hash started with no

@ -24,6 +24,7 @@
#include <vector>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/types/optional.h"
#include <grpc/support/log.h>
@ -233,16 +234,16 @@ class AdsServiceImpl
Status StreamAggregatedResources(ServerContext* context,
Stream* stream) override {
gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources starts",
debug_label_.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: StreamAggregatedResources starts";
{
grpc_core::MutexLock lock(&ads_mu_);
if (forced_ads_failure_.has_value()) {
gpr_log(GPR_INFO,
"ADS[%s]: StreamAggregatedResources forcing early failure "
"with status code: %d, message: %s",
debug_label_.c_str(), forced_ads_failure_.value().error_code(),
forced_ads_failure_.value().error_message().c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: StreamAggregatedResources forcing early failure "
"with status code: "
<< forced_ads_failure_.value().error_code() << ", message: "
<< forced_ads_failure_.value().error_message();
return forced_ads_failure_.value();
}
}
@ -283,10 +284,9 @@ class AdsServiceImpl
DiscoveryRequest request = std::move(requests.front());
requests.pop_front();
did_work = true;
gpr_log(GPR_INFO,
"ADS[%s]: Received request for type %s with content %s",
debug_label_.c_str(), request.type_url().c_str(),
request.DebugString().c_str());
LOG(INFO) << "ADS[" << debug_label_ << "]: Received request for type "
<< request.type_url() << " with content "
<< request.DebugString();
SentState& sent_state = sent_state_map[request.type_url()];
// Process request.
ProcessRequest(request, &update_queue, &subscription_map, &sent_state,
@ -294,8 +294,8 @@ class AdsServiceImpl
}
}
if (response.has_value()) {
gpr_log(GPR_INFO, "ADS[%s]: Sending response: %s", debug_label_.c_str(),
response->DebugString().c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: Sending response: " << response->DebugString();
stream->Write(response.value());
}
response.reset();
@ -315,8 +315,8 @@ class AdsServiceImpl
}
}
if (response.has_value()) {
gpr_log(GPR_INFO, "ADS[%s]: Sending update response: %s",
debug_label_.c_str(), response->DebugString().c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: Sending update response: " << response->DebugString();
stream->Write(response.value());
}
{
@ -350,8 +350,7 @@ class AdsServiceImpl
}
}
}
gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources done",
debug_label_.c_str());
LOG(INFO) << "ADS[" << debug_label_ << "]: StreamAggregatedResources done";
RemoveClient(context->peer());
return Status::OK;
}
@ -382,9 +381,9 @@ class AdsServiceImpl
ResponseState response_state;
if (!request.has_error_detail()) {
response_state.state = ResponseState::ACKED;
gpr_log(GPR_INFO, "ADS[%s]: client ACKed resource_type=%s version=%s",
debug_label_.c_str(), request.type_url().c_str(),
request.version_info().c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: client ACKed resource_type=" << request.type_url()
<< " version=" << request.version_info();
} else {
response_state.state = ResponseState::NACKED;
if (check_nack_status_code_ != nullptr) {
@ -392,11 +391,10 @@ class AdsServiceImpl
static_cast<absl::StatusCode>(request.error_detail().code()));
}
response_state.error_message = request.error_detail().message();
gpr_log(GPR_INFO,
"ADS[%s]: client NACKed resource_type=%s version=%s: %s",
debug_label_.c_str(), request.type_url().c_str(),
request.version_info().c_str(),
response_state.error_message.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: client NACKed resource_type=" << request.type_url()
<< " version=" << request.version_info() << ": "
<< response_state.error_message;
}
resource_type_response_state_[request.type_url()].emplace_back(
std::move(response_state));
@ -426,9 +424,9 @@ class AdsServiceImpl
&resource_state, update_queue) ||
ClientNeedsResourceUpdate(resource_type_state, resource_state,
sent_state->resource_type_version)) {
gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s",
debug_label_.c_str(), request.type_url().c_str(),
resource_name.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: Sending update for type=" << request.type_url()
<< " name=" << resource_name;
resources_added_to_response.emplace(resource_name);
if (!response->has_value()) response->emplace();
if (resource_state.resource.has_value()) {
@ -441,10 +439,9 @@ class AdsServiceImpl
}
}
} else {
gpr_log(GPR_INFO,
"ADS[%s]: client does not need update for type=%s name=%s",
debug_label_.c_str(), request.type_url().c_str(),
resource_name.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: client does not need update for type="
<< request.type_url() << " name=" << resource_name;
}
}
// Process unsubscriptions for any resource no longer
@ -467,8 +464,9 @@ class AdsServiceImpl
SubscriptionMap* subscription_map, SentState* sent_state,
absl::optional<DiscoveryResponse>* response)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(ads_mu_) {
gpr_log(GPR_INFO, "ADS[%s]: Received update for type=%s name=%s",
debug_label_.c_str(), resource_type.c_str(), resource_name.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: Received update for type=" << resource_type
<< " name=" << resource_name;
auto& subscription_name_map = (*subscription_map)[resource_type];
auto& resource_type_state = resource_map_[resource_type];
auto& resource_name_map = resource_type_state.resource_name_map;
@ -477,9 +475,9 @@ class AdsServiceImpl
ResourceState& resource_state = resource_name_map[resource_name];
if (ClientNeedsResourceUpdate(resource_type_state, resource_state,
sent_state->resource_type_version)) {
gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s",
debug_label_.c_str(), resource_type.c_str(),
resource_name.c_str());
LOG(INFO) << "ADS[" << debug_label_
<< "]: Sending update for type=" << resource_type
<< " name=" << resource_name;
response->emplace();
if (resource_state.resource.has_value()) {
auto* resource = (*response)->add_resources();
@ -510,8 +508,7 @@ class AdsServiceImpl
requests->emplace_back(std::move(request));
}
}
gpr_log(GPR_INFO, "ADS[%s]: Null read, stream closed",
debug_label_.c_str());
LOG(INFO) << "ADS[" << debug_label_ << "]: Null read, stream closed";
grpc_core::MutexLock lock(&ads_mu_);
*stream_closed = true;
}
@ -751,7 +748,7 @@ class LrsServiceImpl
using Stream = ServerReaderWriter<LoadStatsResponse, LoadStatsRequest>;
Status StreamLoadStats(ServerContext* /*context*/, Stream* stream) override {
gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats starts", debug_label_.c_str());
LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats starts";
if (stream_started_callback_ != nullptr) stream_started_callback_();
// Take a reference of the LrsServiceImpl object, reference will go
// out of scope after this method exits.
@ -778,8 +775,9 @@ class LrsServiceImpl
// Wait for report.
request.Clear();
while (stream->Read(&request)) {
gpr_log(GPR_INFO, "LRS[%s]: received client load report message: %s",
debug_label_.c_str(), request.DebugString().c_str());
LOG(INFO) << "LRS[" << debug_label_
<< "]: received client load report message: "
<< request.DebugString();
std::vector<ClientStats> stats;
for (const auto& cluster_stats : request.cluster_stats()) {
stats.emplace_back(cluster_stats);
@ -796,7 +794,7 @@ class LrsServiceImpl
lrs_cv_.Wait(&lrs_mu_);
}
}
gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats done", debug_label_.c_str());
LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats done";
return Status::OK;
}

@ -132,12 +132,12 @@ TEST_P(WrrTest, MetricsHaveLocalityLabel) {
WaitForAllBackends(DEBUG_LOCATION);
// Make sure we have a metric value for each of the two localities.
EXPECT_THAT(
stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality0")}),
stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality0")}),
::testing::Optional(::testing::Not(::testing::IsEmpty())));
EXPECT_THAT(
stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality1")}),
stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues,
{LocalityNameString("locality1")}),
::testing::Optional(::testing::Not(::testing::IsEmpty())));
}

@ -397,6 +397,9 @@ TEST_P(MetadataExchangeTest, ClientDoesNotSendMetadata) {
EXPECT_EQ(absl::get<std::string>(attributes.at("csm.mesh_id")), "mesh-id");
EXPECT_EQ(absl::get<std::string>(attributes.at("csm.remote_workload_type")),
"unknown");
EXPECT_EQ(absl::get<std::string>(
attributes.at("csm.remote_workload_canonical_service")),
"unknown");
}
TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) {
@ -424,6 +427,8 @@ TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) {
"mynamespace");
}
// Test that metadata exchange works and corresponding service mesh labels are
// received and recorded even if the server sends a trailers-only response.
TEST_P(MetadataExchangeTest, Retries) {
Init(std::move(
Options()

@ -51,6 +51,7 @@ grpc_cc_test(
"stats_plugin_end2end_test.cc",
],
external_deps = [
"absl/log:log",
"gtest",
"opencensus-stats-test",
"opencensus-tags",

@ -20,6 +20,7 @@
#include <thread> // NOLINT
#include <vector>
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "gmock/gmock.h"
@ -517,8 +518,8 @@ TEST_F(StatsPluginEnd2EndTest, TestRetryStatsWithAdditionalRetries) {
::testing::ElementsAre(client_method_name_), ::testing::Eq(0))));
auto data = client_retry_delay_per_call_view.GetData().distribution_data();
for (const auto& entry : data) {
gpr_log(GPR_ERROR, "Mean Retry Delay %s: %lf ms", entry.first[0].c_str(),
entry.second.mean());
LOG(ERROR) << "Mean Retry Delay " << entry.first[0] << ": "
<< entry.second.mean() << " ms";
}
// We expect the retry delay to be around 100ms.
EXPECT_THAT(
@ -1007,95 +1008,94 @@ TEST_F(StatsPluginEnd2EndTest, TestGlobalEnableOpenCensusTracing) {
// This test verifies that users depending on src/cpp/ext/filters/census header
// files can continue using the non-experimental names.
TEST(StatsPluginDeclarationTest, Declarations) {
gpr_log(GPR_INFO, "%p", ClientMethodTagKey);
gpr_log(GPR_INFO, "%p", ClientStatusTagKey);
gpr_log(GPR_INFO, "%p", ServerMethodTagKey);
gpr_log(GPR_INFO, "%p", ServerStatusTagKey);
gpr_log(GPR_INFO, "%p", kRpcClientReceivedBytesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientReceivedMessagesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientRetriesPerCallMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientRetryDelayPerCallMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientRoundtripLatencyMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientSentBytesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientSentMessagesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientServerLatencyMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcClientStartedRpcsMeasureName.data());
gpr_log(GPR_INFO, "%p",
kRpcClientTransparentRetriesPerCallMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerReceivedBytesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerReceivedMessagesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerSentBytesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerSentMessagesPerRpcMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerServerLatencyMeasureName.data());
gpr_log(GPR_INFO, "%p", kRpcServerStartedRpcsMeasureName.data());
gpr_log(GPR_INFO, "%p", ClientCompletedRpcsCumulative);
gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ClientRetriesCumulative);
gpr_log(GPR_INFO, "%p", ClientRetriesPerCallCumulative);
gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallCumulative);
gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyCumulative);
gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ClientServerLatencyCumulative);
gpr_log(GPR_INFO, "%p", ClientStartedRpcsCumulative);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesCumulative);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallCumulative);
gpr_log(GPR_INFO, "%p", ServerCompletedRpcsCumulative);
gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcCumulative);
gpr_log(GPR_INFO, "%p", ServerServerLatencyCumulative);
gpr_log(GPR_INFO, "%p", ServerStartedRpcsCumulative);
gpr_log(GPR_INFO, "%p", ClientCompletedRpcsMinute);
gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ClientRetriesMinute);
gpr_log(GPR_INFO, "%p", ClientRetriesPerCallMinute);
gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallMinute);
gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyMinute);
gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ClientServerLatencyMinute);
gpr_log(GPR_INFO, "%p", ClientStartedRpcsMinute);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesMinute);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallMinute);
gpr_log(GPR_INFO, "%p", ServerCompletedRpcsMinute);
gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcMinute);
gpr_log(GPR_INFO, "%p", ServerServerLatencyMinute);
gpr_log(GPR_INFO, "%p", ServerStartedRpcsMinute);
gpr_log(GPR_INFO, "%p", ClientCompletedRpcsHour);
gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcHour);
gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcHour);
gpr_log(GPR_INFO, "%p", ClientRetriesHour);
gpr_log(GPR_INFO, "%p", ClientRetriesPerCallHour);
gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallHour);
gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyHour);
gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcHour);
gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcHour);
gpr_log(GPR_INFO, "%p", ClientServerLatencyHour);
gpr_log(GPR_INFO, "%p", ClientStartedRpcsHour);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesHour);
gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallHour);
gpr_log(GPR_INFO, "%p", ServerCompletedRpcsHour);
gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcHour);
gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcHour);
gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcHour);
gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcHour);
gpr_log(GPR_INFO, "%p", ServerServerLatencyHour);
gpr_log(GPR_INFO, "%p", ServerStartedRpcsHour);
LOG(INFO) << ClientMethodTagKey;
LOG(INFO) << ClientStatusTagKey;
LOG(INFO) << ServerMethodTagKey;
LOG(INFO) << ServerStatusTagKey;
LOG(INFO) << kRpcClientReceivedBytesPerRpcMeasureName.data();
LOG(INFO) << kRpcClientReceivedMessagesPerRpcMeasureName.data();
LOG(INFO) << kRpcClientRetriesPerCallMeasureName.data();
LOG(INFO) << kRpcClientRetryDelayPerCallMeasureName.data();
LOG(INFO) << kRpcClientRoundtripLatencyMeasureName.data();
LOG(INFO) << kRpcClientSentBytesPerRpcMeasureName.data();
LOG(INFO) << kRpcClientSentMessagesPerRpcMeasureName.data();
LOG(INFO) << kRpcClientServerLatencyMeasureName.data();
LOG(INFO) << kRpcClientStartedRpcsMeasureName.data();
LOG(INFO) << kRpcClientTransparentRetriesPerCallMeasureName.data();
LOG(INFO) << kRpcServerReceivedBytesPerRpcMeasureName.data();
LOG(INFO) << kRpcServerReceivedMessagesPerRpcMeasureName.data();
LOG(INFO) << kRpcServerSentBytesPerRpcMeasureName.data();
LOG(INFO) << kRpcServerSentMessagesPerRpcMeasureName.data();
LOG(INFO) << kRpcServerServerLatencyMeasureName.data();
LOG(INFO) << kRpcServerStartedRpcsMeasureName.data();
LOG(INFO) << ClientCompletedRpcsCumulative;
LOG(INFO) << ClientReceivedBytesPerRpcCumulative;
LOG(INFO) << ClientReceivedMessagesPerRpcCumulative;
LOG(INFO) << ClientRetriesCumulative;
LOG(INFO) << ClientRetriesPerCallCumulative;
LOG(INFO) << ClientRetryDelayPerCallCumulative;
LOG(INFO) << ClientRoundtripLatencyCumulative;
LOG(INFO) << ClientSentBytesPerRpcCumulative;
LOG(INFO) << ClientSentMessagesPerRpcCumulative;
LOG(INFO) << ClientServerLatencyCumulative;
LOG(INFO) << ClientStartedRpcsCumulative;
LOG(INFO) << ClientTransparentRetriesCumulative;
LOG(INFO) << ClientTransparentRetriesPerCallCumulative;
LOG(INFO) << ServerCompletedRpcsCumulative;
LOG(INFO) << ServerReceivedBytesPerRpcCumulative;
LOG(INFO) << ServerReceivedMessagesPerRpcCumulative;
LOG(INFO) << ServerSentBytesPerRpcCumulative;
LOG(INFO) << ServerSentMessagesPerRpcCumulative;
LOG(INFO) << ServerServerLatencyCumulative;
LOG(INFO) << ServerStartedRpcsCumulative;
LOG(INFO) << ClientCompletedRpcsMinute;
LOG(INFO) << ClientReceivedBytesPerRpcMinute;
LOG(INFO) << ClientReceivedMessagesPerRpcMinute;
LOG(INFO) << ClientRetriesMinute;
LOG(INFO) << ClientRetriesPerCallMinute;
LOG(INFO) << ClientRetryDelayPerCallMinute;
LOG(INFO) << ClientRoundtripLatencyMinute;
LOG(INFO) << ClientSentBytesPerRpcMinute;
LOG(INFO) << ClientSentMessagesPerRpcMinute;
LOG(INFO) << ClientServerLatencyMinute;
LOG(INFO) << ClientStartedRpcsMinute;
LOG(INFO) << ClientTransparentRetriesMinute;
LOG(INFO) << ClientTransparentRetriesPerCallMinute;
LOG(INFO) << ServerCompletedRpcsMinute;
LOG(INFO) << ServerReceivedBytesPerRpcMinute;
LOG(INFO) << ServerReceivedMessagesPerRpcMinute;
LOG(INFO) << ServerSentBytesPerRpcMinute;
LOG(INFO) << ServerSentMessagesPerRpcMinute;
LOG(INFO) << ServerServerLatencyMinute;
LOG(INFO) << ServerStartedRpcsMinute;
LOG(INFO) << ClientCompletedRpcsHour;
LOG(INFO) << ClientReceivedBytesPerRpcHour;
LOG(INFO) << ClientReceivedMessagesPerRpcHour;
LOG(INFO) << ClientRetriesHour;
LOG(INFO) << ClientRetriesPerCallHour;
LOG(INFO) << ClientRetryDelayPerCallHour;
LOG(INFO) << ClientRoundtripLatencyHour;
LOG(INFO) << ClientSentBytesPerRpcHour;
LOG(INFO) << ClientSentMessagesPerRpcHour;
LOG(INFO) << ClientServerLatencyHour;
LOG(INFO) << ClientStartedRpcsHour;
LOG(INFO) << ClientTransparentRetriesHour;
LOG(INFO) << ClientTransparentRetriesPerCallHour;
LOG(INFO) << ServerCompletedRpcsHour;
LOG(INFO) << ServerReceivedBytesPerRpcHour;
LOG(INFO) << ServerReceivedMessagesPerRpcHour;
LOG(INFO) << ServerSentBytesPerRpcHour;
LOG(INFO) << ServerSentMessagesPerRpcHour;
LOG(INFO) << ServerServerLatencyHour;
LOG(INFO) << ServerStartedRpcsHour;
}
} // namespace

@ -1263,7 +1263,7 @@ using OpenTelemetryPluginNPCMetricsTest = OpenTelemetryPluginEnd2EndTest;
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) {
constexpr absl::string_view kMetricName = "uint64_counter";
constexpr int kCounterValues[] = {1, 2, 3};
constexpr uint64_t kCounterValues[] = {1, 2, 3};
constexpr int64_t kCounterResult = 6;
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
"label_key_2"};
@ -1273,9 +1273,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
kMetricName, "A simple uint64 counter.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter(
kMetricName, "A simple uint64 counter.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kMetricName})
.set_channel_scope_filter(
@ -1319,9 +1323,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter(
kMetricName, "A simple double counter.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/false);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter(
kMetricName, "A simple double counter.", "unit",
/*enable_by_default=*/false)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kMetricName})
.set_channel_scope_filter(
@ -1355,7 +1363,7 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) {
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) {
constexpr absl::string_view kMetricName = "uint64_histogram";
constexpr int kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6};
constexpr uint64_t kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6};
constexpr int64_t kSum = 26;
constexpr int64_t kMin = 1;
constexpr int64_t kMax = 6;
@ -1368,9 +1376,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram(
kMetricName, "A simple uint64 histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram(
kMetricName, "A simple uint64 histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1419,9 +1431,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleHistogram) {
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1466,9 +1482,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest,
"label_value_2"};
constexpr std::array<absl::string_view, 2> kOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
// Build and register a separate OpenTelemetryPlugin and verify its histogram
// recording.
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
@ -1592,9 +1612,14 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest,
constexpr std::array<absl::string_view, 3> kActualOptionalLabelValues = {
"optional_label_value_1", "optional_label_value_2",
"optional_label_value_4"};
auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit", kLabelKeys,
kOptionalLabelKeys, /*enable_by_default=*/true);
auto handle =
grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram(
kMetricName, "A simple double histogram.", "unit",
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1],
kOptionalLabelKeys[2], kOptionalLabelKeys[3])
.Build();
Init(std::move(
Options()
.set_metric_names({kMetricName})
@ -1655,13 +1680,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
auto integer_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
auto double_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kInt64CallbackGaugeMetric,
kDoubleCallbackGaugeMetric})
@ -1671,8 +1700,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
grpc_core::experimental::StatsPluginChannelScope(
"dns:///localhost:8080", ""));
// Multiple callbacks for the same metrics, each reporting different label
// values.
// Multiple callbacks for the same metrics, each reporting different
// label values.
int report_count_1 = 0;
int64_t int_value_1 = 1;
double double_value_1 = 0.5;
@ -1688,8 +1717,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
int report_count_2 = 0;
int64_t int_value_2 = 1;
double double_value_2 = 0.5;
@ -1705,8 +1734,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
constexpr int kIterations = 100;
MetricsCollectorThread collector{
this, grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
@ -1786,13 +1815,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
auto integer_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
auto double_gauge_handle =
grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit",
kLabelKeys, kOptionalLabelKeys,
/*enable_by_default=*/true);
/*enable_by_default=*/true)
.Labels(kLabelKeys[0], kLabelKeys[1])
.OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1])
.Build();
Init(std::move(Options()
.set_metric_names({kInt64CallbackGaugeMetric,
kDoubleCallbackGaugeMetric})
@ -1802,8 +1835,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
grpc_core::experimental::StatsPluginChannelScope(
"dns:///localhost:8080", ""));
// Multiple callbacks for the same metrics, each reporting different label
// values.
// Multiple callbacks for the same metrics, each reporting different
// label values.
int report_count_1 = 0;
int64_t int_value_1 = 1;
double double_value_1 = 0.5;
@ -1819,8 +1852,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
int report_count_2 = 0;
int64_t int_value_2 = 1;
double double_value_2 = 0.5;
@ -1836,8 +1869,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2,
kOptionalLabelValuesSet2);
},
{integer_gauge_handle, double_gauge_handle},
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor());
grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(),
integer_gauge_handle, double_gauge_handle);
constexpr int kIterations = 100;
MetricsCollectorThread collector{
this,
@ -1854,7 +1887,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest,
std::string,
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
data = collector.Stop();
// Verify that data is incremental without duplications (cached values).
// Verify that data is incremental without duplications (cached
// values).
EXPECT_EQ(report_count_1, kIterations);
EXPECT_EQ(report_count_2, kIterations);
EXPECT_EQ(data[kInt64CallbackGaugeMetric].size(),

@ -46,6 +46,7 @@ grpc_cc_binary(
external_deps = [
"absl/flags:flag",
"absl/log:check",
"absl/log:log",
"absl/time:time",
],
language = "C++",
@ -429,6 +430,7 @@ grpc_cc_binary(
external_deps = [
"absl/flags:flag",
"absl/log:check",
"absl/log:log",
],
deps = [
"//:grpc++",

@ -32,11 +32,11 @@
#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/strings/str_format.h"
#include "absl/time/time.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
@ -87,8 +87,8 @@ enum RpcMode {
GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds,
RpcMode rpc_mode) {
gpr_log(GPR_INFO, "DoRPCAndGetPath deadline_seconds:%d rpc_mode:%d",
deadline_seconds, rpc_mode);
LOG(INFO) << "DoRPCAndGetPath deadline_seconds:" << deadline_seconds
<< " rpc_mode:" << rpc_mode;
SimpleRequest request;
SimpleResponse response;
grpc::ClientContext context;
@ -101,16 +101,16 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds,
context.set_deadline(deadline);
grpc::Status s = stub->UnaryCall(&context, request, &response);
if (!s.ok()) {
gpr_log(GPR_INFO, "DoRPCAndGetPath failed. status-message: %s",
s.error_message().c_str());
LOG(INFO) << "DoRPCAndGetPath failed. status-message: "
<< s.error_message();
return GrpclbRouteType::GRPCLB_ROUTE_TYPE_UNKNOWN;
}
CHECK(response.grpclb_route_type() ==
GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND ||
response.grpclb_route_type() ==
GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK);
gpr_log(GPR_INFO, "DoRPCAndGetPath done. grpclb_route_type:%d",
response.grpclb_route_type());
LOG(INFO) << "DoRPCAndGetPath done. grpclb_route_type:"
<< response.grpclb_route_type();
return response.grpclb_route_type();
}
@ -120,7 +120,7 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds) {
bool TcpUserTimeoutMutateFd(int fd, grpc_socket_mutator* /*mutator*/) {
int timeout = 20000; // 20 seconds
gpr_log(GPR_INFO, "Setting socket option TCP_USER_TIMEOUT on fd: %d", fd);
LOG(INFO) << "Setting socket option TCP_USER_TIMEOUT on fd: " << fd;
if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
sizeof(timeout))) {
grpc_core::Crash("Failed to set socket option TCP_USER_TIMEOUT");
@ -161,7 +161,7 @@ std::unique_ptr<TestService::Stub> CreateFallbackTestStub() {
}
void RunCommand(const std::string& command) {
gpr_log(GPR_INFO, "RunCommand: |%s|", command.c_str());
LOG(INFO) << "RunCommand: |" << command << "|";
int out = std::system(command.c_str());
if (WIFEXITED(out)) {
int code = WEXITSTATUS(out);
@ -185,25 +185,23 @@ void WaitForFallbackAndDoRPCs(TestService::Stub* stub) {
while (absl::Now() < fallback_deadline) {
GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub, 1);
if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND) {
gpr_log(GPR_ERROR,
"Got grpclb route type backend. Backends are "
"supposed to be unreachable, so this test is broken");
LOG(ERROR) << "Got grpclb route type backend. Backends are "
"supposed to be unreachable, so this test is broken";
CHECK(0);
}
if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) {
gpr_log(GPR_INFO,
"Made one successful RPC to a fallback. Now expect the same for "
"the rest.");
LOG(INFO) << "Made one successful RPC to a fallback. Now expect the same "
"for the rest.";
fallback = true;
break;
} else {
gpr_log(GPR_ERROR, "Retryable RPC failure on iteration: %d",
fallback_retry_count);
LOG(ERROR) << "Retryable RPC failure on iteration: "
<< fallback_retry_count;
}
fallback_retry_count++;
}
if (!fallback) {
gpr_log(GPR_ERROR, "Didn't fall back within deadline");
LOG(ERROR) << "Didn't fall back within deadline";
CHECK(0);
}
for (int i = 0; i < 30; i++) {
@ -231,13 +229,13 @@ void DoFallbackAfterStartupTest() {
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
gpr_log(GPR_INFO, "Testing: %s", absl::GetFlag(FLAGS_test_case).c_str());
LOG(INFO) << "Testing: " << absl::GetFlag(FLAGS_test_case);
if (absl::GetFlag(FLAGS_test_case) == "fallback_before_startup") {
DoFallbackBeforeStartupTest();
gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!");
LOG(INFO) << "DoFallbackBeforeStartup done!";
} else if (absl::GetFlag(FLAGS_test_case) == "fallback_after_startup") {
DoFallbackAfterStartupTest();
gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!");
LOG(INFO) << "DoFallbackBeforeStartup done!";
} else {
grpc_core::Crash(absl::StrFormat("Invalid test case: %s",
absl::GetFlag(FLAGS_test_case).c_str()));

@ -22,10 +22,10 @@
#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/strings/str_format.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
@ -81,40 +81,40 @@ SimpleRequest Http2Client::BuildDefaultRequest() {
}
bool Http2Client::DoRstAfterHeader() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header");
VLOG(2) << "Sending RPC and expecting reset stream after header";
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
CHECK(!response.has_payload()); // no data should be received
gpr_log(GPR_DEBUG, "Done testing reset stream after header");
VLOG(2) << "Done testing reset stream after header";
return true;
}
bool Http2Client::DoRstAfterData() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data");
VLOG(2) << "Sending RPC and expecting reset stream after data";
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
// There is no guarantee that data would be received.
gpr_log(GPR_DEBUG, "Done testing reset stream after data");
VLOG(2) << "Done testing reset stream after data";
return true;
}
bool Http2Client::DoRstDuringData() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data");
VLOG(2) << "Sending RPC and expecting reset stream during data";
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
CHECK(!response.has_payload()); // no data should be received
gpr_log(GPR_DEBUG, "Done testing reset stream during data");
VLOG(2) << "Done testing reset stream during data";
return true;
}
bool Http2Client::DoGoaway() {
gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway");
VLOG(2) << "Sending two RPCs and expecting goaway";
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0'));
@ -127,16 +127,16 @@ bool Http2Client::DoGoaway() {
response.Clear();
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0'));
gpr_log(GPR_DEBUG, "Done testing goaway");
VLOG(2) << "Done testing goaway";
return true;
}
bool Http2Client::DoPing() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting ping");
VLOG(2) << "Sending RPC and expecting ping";
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0'));
gpr_log(GPR_DEBUG, "Done testing ping");
VLOG(2) << "Done testing ping";
return true;
}
@ -148,7 +148,7 @@ void Http2Client::MaxStreamsWorker(
}
bool Http2Client::DoMaxStreams() {
gpr_log(GPR_DEBUG, "Testing max streams");
VLOG(2) << "Testing max streams";
// Make an initial call on the channel to ensure the server's max streams
// setting is received
@ -167,7 +167,7 @@ bool Http2Client::DoMaxStreams() {
it->join();
}
gpr_log(GPR_DEBUG, "Done testing max streams");
VLOG(2) << "Done testing max streams";
return true;
}
@ -198,7 +198,7 @@ int main(int argc, char** argv) {
CHECK(channel->WaitForConnected(gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN))));
grpc::testing::Http2Client client(channel);
gpr_log(GPR_INFO, "Testing case: %s", absl::GetFlag(FLAGS_test_case).c_str());
LOG(INFO) << "Testing case: " << absl::GetFlag(FLAGS_test_case);
int ret = 0;
if (absl::GetFlag(FLAGS_test_case) == "rst_after_header") {
client.DoRstAfterHeader();
@ -219,8 +219,9 @@ int main(int argc, char** argv) {
char* joined_testcases =
gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", nullptr);
gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s",
absl::GetFlag(FLAGS_test_case).c_str(), joined_testcases);
LOG(ERROR) << "Unsupported test case " << absl::GetFlag(FLAGS_test_case)
<< ". Valid options are\n"
<< joined_testcases;
gpr_free(joined_testcases);
ret = 1;
}

@ -77,7 +77,10 @@ grpc_cc_library(
"driver.h",
"report.h",
],
external_deps = ["absl/log:check"],
external_deps = [
"absl/log:check",
"absl/log:log",
],
deps = [
":histogram",
":parse_json",

@ -26,10 +26,10 @@
#include <vector>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "google/protobuf/timestamp.pb.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
@ -78,13 +78,13 @@ static deque<string> get_workers(const string& env_name) {
}
}
if (out.empty()) {
gpr_log(GPR_ERROR,
"Environment variable \"%s\" does not contain a list of QPS "
"workers to use. Set it to a comma-separated list of "
"hostname:port pairs, starting with hosts that should act as "
"servers. E.g. export "
"%s=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\"",
env_name.c_str(), env_name.c_str());
LOG(ERROR) << "Environment variable \"" << env_name
<< "\" does not contain a list of QPS "
"workers to use. Set it to a comma-separated list of "
"hostname:port pairs, starting with hosts that should act as "
"servers. E.g. export "
<< env_name
<< "=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\"";
}
return out;
}
@ -237,7 +237,7 @@ struct ServerData {
static void FinishClients(const std::vector<ClientData>& clients,
const ClientArgs& client_mark) {
gpr_log(GPR_INFO, "Finishing clients");
LOG(INFO) << "Finishing clients";
for (size_t i = 0, i_end = clients.size(); i < i_end; i++) {
auto client = &clients[i];
if (!client->stream->Write(client_mark)) {
@ -252,13 +252,13 @@ static void FinishClients(const std::vector<ClientData>& clients,
static void ReceiveFinalStatusFromClients(
const std::vector<ClientData>& clients, Histogram& merged_latencies,
std::unordered_map<int, int64_t>& merged_statuses, ScenarioResult& result) {
gpr_log(GPR_INFO, "Receiving final status from clients");
LOG(INFO) << "Receiving final status from clients";
ClientStatus client_status;
for (size_t i = 0, i_end = clients.size(); i < i_end; i++) {
auto client = &clients[i];
// Read the client final status
if (client->stream->Read(&client_status)) {
gpr_log(GPR_INFO, "Received final status from client %zu", i);
LOG(INFO) << "Received final status from client " << i;
const auto& stats = client_status.stats();
merged_latencies.MergeProto(stats.latencies());
for (int i = 0; i < stats.request_results_size(); i++) {
@ -282,7 +282,7 @@ static void ReceiveFinalStatusFromClients(
static void ShutdownClients(const std::vector<ClientData>& clients,
ScenarioResult& result) {
gpr_log(GPR_INFO, "Shutdown clients");
LOG(INFO) << "Shutdown clients";
for (size_t i = 0, i_end = clients.size(); i < i_end; i++) {
auto client = &clients[i];
Status s = client->stream->Finish();
@ -300,7 +300,7 @@ static void ShutdownClients(const std::vector<ClientData>& clients,
static void FinishServers(const std::vector<ServerData>& servers,
const ServerArgs& server_mark) {
gpr_log(GPR_INFO, "Finishing servers");
LOG(INFO) << "Finishing servers";
for (size_t i = 0, i_end = servers.size(); i < i_end; i++) {
auto server = &servers[i];
if (!server->stream->Write(server_mark)) {
@ -314,13 +314,13 @@ static void FinishServers(const std::vector<ServerData>& servers,
static void ReceiveFinalStatusFromServer(const std::vector<ServerData>& servers,
ScenarioResult& result) {
gpr_log(GPR_INFO, "Receiving final status from servers");
LOG(INFO) << "Receiving final status from servers";
ServerStatus server_status;
for (size_t i = 0, i_end = servers.size(); i < i_end; i++) {
auto server = &servers[i];
// Read the server final status
if (server->stream->Read(&server_status)) {
gpr_log(GPR_INFO, "Received final status from server %zu", i);
LOG(INFO) << "Received final status from server " << i;
result.add_server_stats()->CopyFrom(server_status.stats());
result.add_server_cores(server_status.cores());
// That final status should be the last message on the server stream
@ -334,7 +334,7 @@ static void ReceiveFinalStatusFromServer(const std::vector<ServerData>& servers,
static void ShutdownServers(const std::vector<ServerData>& servers,
ScenarioResult& result) {
gpr_log(GPR_INFO, "Shutdown servers");
LOG(INFO) << "Shutdown servers";
for (size_t i = 0, i_end = servers.size(); i < i_end; i++) {
auto server = &servers[i];
Status s = server->stream->Finish();
@ -430,8 +430,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
ChannelArguments channel_args;
for (size_t i = 0; i < num_servers; i++) {
gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
workers[i].c_str(), i);
LOG(INFO) << "Starting server on " << workers[i] << " (worker #" << i
<< ")";
if (!run_inproc) {
servers[i].stub = WorkerService::NewStub(grpc::CreateTestChannel(
workers[i],
@ -487,8 +487,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
size_t channels_allocated = 0;
for (size_t i = 0; i < num_clients; i++) {
const auto& worker = workers[i + num_servers];
gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
worker.c_str(), i + num_servers);
LOG(INFO) << "Starting client on " << worker << " (worker #"
<< i + num_servers << ")";
if (!run_inproc) {
clients[i].stub = WorkerService::NewStub(grpc::CreateTestChannel(
worker,
@ -510,8 +510,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
(client_config.client_channels() - channels_allocated) /
(num_clients - i);
channels_allocated += num_channels;
gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i,
num_channels);
VLOG(2) << "Client " << i << " gets " << num_channels << " channels";
per_client_config.set_client_channels(num_channels);
ClientArgs args;
@ -533,7 +532,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
// Send an initial mark: clients can use this to know that everything is ready
// to start
gpr_log(GPR_INFO, "Initiating");
LOG(INFO) << "Initiating";
ServerArgs server_mark;
server_mark.mutable_mark()->set_reset(true);
ClientArgs client_mark;
@ -555,13 +554,13 @@ std::unique_ptr<ScenarioResult> RunScenario(
}
// Let everything warmup
gpr_log(GPR_INFO, "Warming up");
LOG(INFO) << "Warming up";
gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
gpr_sleep_until(
gpr_time_add(start, gpr_time_from_seconds(warmup_seconds, GPR_TIMESPAN)));
// Start a run
gpr_log(GPR_INFO, "Starting");
LOG(INFO) << "Starting";
auto start_time = time(nullptr);
@ -593,7 +592,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
}
// Wait some time
gpr_log(GPR_INFO, "Running");
LOG(INFO) << "Running";
// Use gpr_sleep_until rather than this_thread::sleep_until to support
// compilers that don't work with this_thread
gpr_sleep_until(gpr_time_add(
@ -669,8 +668,8 @@ bool RunQuit(
ctx.set_wait_for_ready(true);
Status s = stub->QuitWorker(&ctx, phony, &phony);
if (!s.ok()) {
gpr_log(GPR_ERROR, "Worker %zu could not be properly quit because %s", i,
s.error_message().c_str());
LOG(ERROR) << "Worker " << i << " could not be properly quit because "
<< s.error_message();
result = false;
}
}

@ -20,7 +20,8 @@
#include <fstream>
#include <grpc/support/log.h>
#include "absl/log/log.h"
#include <grpcpp/client_context.h>
#include "src/core/lib/gprpp/crash.h"
@ -79,58 +80,52 @@ void CompositeReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
}
void GprLogReporter::ReportQPS(const ScenarioResult& result) {
gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps());
LOG(INFO) << "QPS: " << result.summary().qps();
if (result.summary().failed_requests_per_second() > 0) {
gpr_log(GPR_INFO, "failed requests/second: %.1f",
result.summary().failed_requests_per_second());
gpr_log(GPR_INFO, "successful requests/second: %.1f",
result.summary().successful_requests_per_second());
LOG(INFO) << "failed requests/second: "
<< result.summary().failed_requests_per_second();
LOG(INFO) << "successful requests/second: "
<< result.summary().successful_requests_per_second();
}
}
void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) {
gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", result.summary().qps(),
result.summary().qps_per_server_core());
LOG(INFO) << "QPS: " << result.summary().qps() << " ("
<< result.summary().qps_per_server_core() << "/server core)";
}
void GprLogReporter::ReportLatency(const ScenarioResult& result) {
gpr_log(GPR_INFO,
"Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
result.summary().latency_50() / 1000,
result.summary().latency_90() / 1000,
result.summary().latency_95() / 1000,
result.summary().latency_99() / 1000,
result.summary().latency_999() / 1000);
LOG(INFO) << "Latencies (50/90/95/99/99.9%-ile): "
<< result.summary().latency_50() / 1000 << "/"
<< result.summary().latency_90() / 1000 << "/"
<< result.summary().latency_95() / 1000 << "/"
<< result.summary().latency_99() / 1000 << "/"
<< result.summary().latency_999() / 1000 << " us";
}
void GprLogReporter::ReportTimes(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Server system time: %.2f%%",
result.summary().server_system_time());
gpr_log(GPR_INFO, "Server user time: %.2f%%",
result.summary().server_user_time());
gpr_log(GPR_INFO, "Client system time: %.2f%%",
result.summary().client_system_time());
gpr_log(GPR_INFO, "Client user time: %.2f%%",
result.summary().client_user_time());
LOG(INFO) << "Server system time: " << result.summary().server_system_time();
LOG(INFO) << "Server user time: " << result.summary().server_user_time();
LOG(INFO) << "Client system time: " << result.summary().client_system_time();
LOG(INFO) << "Client user time: " << result.summary().client_user_time();
}
void GprLogReporter::ReportCpuUsage(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Server CPU usage: %.2f%%",
result.summary().server_cpu_usage());
LOG(INFO) << "Server CPU usage: " << result.summary().server_cpu_usage();
}
void GprLogReporter::ReportPollCount(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Client Polls per Request: %.2f",
result.summary().client_polls_per_request());
gpr_log(GPR_INFO, "Server Polls per Request: %.2f",
result.summary().server_polls_per_request());
LOG(INFO) << "Client Polls per Request: "
<< result.summary().client_polls_per_request();
LOG(INFO) << "Server Polls per Request: "
<< result.summary().server_polls_per_request();
}
void GprLogReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Server Queries/CPU-sec: %.2f",
result.summary().server_queries_per_cpu_sec());
gpr_log(GPR_INFO, "Client Queries/CPU-sec: %.2f",
result.summary().client_queries_per_cpu_sec());
LOG(INFO) << "Server Queries/CPU-sec: "
<< result.summary().server_queries_per_cpu_sec();
LOG(INFO) << "Client Queries/CPU-sec: "
<< result.summary().client_queries_per_cpu_sec();
}
void JsonReporter::ReportQPS(const ScenarioResult& result) {
@ -170,14 +165,14 @@ void RpcReporter::ReportQPS(const ScenarioResult& result) {
grpc::Status status;
Void phony;
gpr_log(GPR_INFO, "RPC reporter sending scenario result to server");
LOG(INFO) << "RPC reporter sending scenario result to server";
status = stub_->ReportScenario(&context, result, &phony);
if (status.ok()) {
gpr_log(GPR_INFO, "RpcReporter report RPC success!");
LOG(INFO) << "RpcReporter report RPC success!";
} else {
gpr_log(GPR_ERROR, "RpcReporter report RPC: code: %d. message: %s",
status.error_code(), status.error_message().c_str());
LOG(ERROR) << "RpcReporter report RPC: code: " << status.error_code()
<< ". message: " << status.error_message();
}
}

@ -28,6 +28,7 @@ grpc_cc_test(
deps = [
"//:grpc++_unsecure",
"//src/proto/grpc/testing:echo_proto",
"//test/core/event_engine:event_engine_test_utils",
"//test/core/test_util:grpc_test_util_base",
"//test/core/test_util:grpc_test_util_unsecure",
],

@ -16,14 +16,19 @@
//
//
#include <sys/socket.h>
#include <gtest/gtest.h>
#include <grpc/event_engine/slice_buffer.h>
#include <grpc/grpc.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <grpcpp/support/config.h>
#include "src/core/lib/gprpp/notification.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/event_engine/event_engine_test_utils.h"
#include "test/core/test_util/port.h"
#include "test/core/test_util/test_config.h"
@ -83,6 +88,56 @@ TEST_F(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) {
nullptr);
}
TEST_F(ServerBuilderTest, AddPassiveListener) {
std::unique_ptr<experimental::PassiveListener> passive_listener;
auto server =
ServerBuilder()
.experimental()
.AddPassiveListener(InsecureServerCredentials(), passive_listener)
.BuildAndStart();
server->Shutdown();
}
TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedFd) {
std::unique_ptr<experimental::PassiveListener> passive_listener;
ServerBuilder builder;
auto cq = builder.AddCompletionQueue();
// TODO(hork): why is the service necessary? Queue isn't drained otherwise.
auto server =
builder.RegisterService(&g_service)
.experimental()
.AddPassiveListener(InsecureServerCredentials(), passive_listener)
.BuildAndStart();
ASSERT_NE(server.get(), nullptr);
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
int fd = socket(AF_INET, SOCK_STREAM, 0);
auto accept_status = passive_listener->AcceptConnectedFd(fd);
ASSERT_TRUE(accept_status.ok()) << accept_status;
#else
int fd = -1;
auto accept_status = passive_listener->AcceptConnectedFd(fd);
ASSERT_FALSE(accept_status.ok()) << accept_status;
#endif
server->Shutdown();
}
TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedEndpoint) {
std::unique_ptr<experimental::PassiveListener> passive_listener;
auto server =
ServerBuilder()
.experimental()
.AddPassiveListener(InsecureServerCredentials(), passive_listener)
.BuildAndStart();
grpc_core::Notification endpoint_destroyed;
auto success = passive_listener->AcceptConnectedEndpoint(
std::make_unique<grpc_event_engine::experimental::ThreadedNoopEndpoint>(
&endpoint_destroyed));
ASSERT_TRUE(success.ok())
<< "AcceptConnectedEndpoint failure: " << success.ToString();
endpoint_destroyed.WaitForNotification();
server->Shutdown();
}
} // namespace
} // namespace grpc

@ -72,7 +72,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = {
"tools/dockerfile/grpc_artifact_python_musllinux_1_1_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_artifact_python_musllinux_1_1_x86@sha256:c288f83435186ee675d004ee52c93195a51201bf2b5fe92581584d977a2499a3",
"tools/dockerfile/interoptest/grpc_interop_aspnetcore.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_aspnetcore@sha256:8e2e732e78724a8382c340dca72e7653c5f82c251a3110fa2874cc00ba538878",
"tools/dockerfile/interoptest/grpc_interop_cxx.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_cxx@sha256:e5a474d33773d52ec6a8abbe2d61ee0c2a9c2b5f48793a5ea3b82c4445becf3f",
"tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021",
"tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2",
"tools/dockerfile/interoptest/grpc_interop_go.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go@sha256:889e7ff34399a5e16af87940d1eaa239e56da307f7faca3f8f1d28379c2e3df3",
"tools/dockerfile/interoptest/grpc_interop_go1.11.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.11@sha256:f2fe3a0a581c687ee4217bf58fd42b18bb1f63d3d006f1b67379ff553b0e23c6",
"tools/dockerfile/interoptest/grpc_interop_go1.16.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.16@sha256:3767f47c9d06584c6c07b7ab536e13f3e87550330e6c2652ad288d3a72b0de23",
@ -102,6 +102,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = {
"tools/dockerfile/test/cxx_debian11_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian11_x86@sha256:3f505ad99e52a4b3337fedb413e883bc8e5c1d9c089299c34002b89e01254d3b",
"tools/dockerfile/test/cxx_debian12_openssl309_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian12_openssl309_x64@sha256:f75bb715c4f9464526f9affb410f7965a0b8894516d7d98cd89a4e165ae065b7",
"tools/dockerfile/test/cxx_gcc_12_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_12_x64@sha256:bbdfe66f27b964f9bfd526646b94a19d904fea52bdb244f32fd4355cc8c4551f",
"tools/dockerfile/test/cxx_gcc_7_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5",
"tools/dockerfile/test/cxx_gcc_8_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_8_x64@sha256:989ceb4324a6240940d7185ccb581f8eff656d2c8c36d15fa14e3f57f294c913",
"tools/dockerfile/test/php73_zts_debian11_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php73_zts_debian11_x64@sha256:186a96566a9c11adfb198309431086bdb02421121c262a2bf0166e3e9b21fb37",
"tools/dockerfile/test/php7_debian11_arm64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php7_debian11_arm64@sha256:7ee21f253a2ddd255f4f6779cd19818eec6524e78b0bf0a7765339e4aa7347c3",

@ -53,7 +53,7 @@ def generate_run_tests_portability_tests(name):
# C and C++ under different compilers
for language in ["c", "c++"]:
compiler_configs = [
["gcc_7", "", "tools/dockerfile/test/cxx_gcc_8_x64.current_version"],
["gcc_7", "", "tools/dockerfile/test/cxx_gcc_7_x64.current_version"],
["gcc_12", "--cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=20", "tools/dockerfile/test/cxx_gcc_12_x64.current_version"],
["gcc10.2_openssl102", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl102_x64.current_version"],
["gcc10.2_openssl111", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl111_x64.current_version"],

@ -77,6 +77,10 @@ IGNORED_FILES = [
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/profiling/timers.h",
"src/core/lib/gprpp/crash.h",
# The grpc_core::Server redundant namespace qualification is required for
# older gcc versions.
"src/core/ext/transport/chttp2/server/chttp2_server.h",
"src/core/server/server.h",
]
# find our home

@ -21,6 +21,13 @@ import os
import re
import sys
IGNORED_FILES = [
# note: the grpc_core::Server redundant namespace qualification is required
# for older gcc versions.
"src/core/ext/transport/chttp2/server/chttp2_server.h",
"src/core/server/server.h",
]
def find_closing_mustache(contents, initial_depth):
"""Find the closing mustache for a given number of open mustaches."""
@ -166,6 +173,8 @@ for config in _CONFIGURATION:
for file in files:
if file.endswith(".cc") or file.endswith(".h"):
path = os.path.join(root, file)
if path in IGNORED_FILES:
continue
try:
with open(path) as f:
contents = f.read()

@ -1 +1 @@
us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021
us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2

@ -0,0 +1 @@
us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64:8bc7b7f679857e741188d07a7db7acecf3a9168f@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5

@ -0,0 +1,79 @@
# Copyright 2021 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.
FROM gcc:7
RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean
#=================
# Setup git to access working directory across docker boundary.
# This avoids the "fatal: detected dubious ownership in repository XYZ"
# git error.
RUN git config --global --add safe.directory '*'
RUN git config --global protocol.file.allow always
#====================
# run_tests.py python dependencies
# Basic python dependencies to be able to run tools/run_tests python scripts
# These dependencies are not sufficient to build gRPC Python, gRPC Python
# deps are defined elsewhere (e.g. python_deps.include)
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
python3-setuptools \
python3-yaml \
&& apt-get clean
# use pinned version of pip to avoid sudden breakages
RUN python3 -m pip install --upgrade pip==19.3.1
# TODO(jtattermusch): currently six is needed for tools/run_tests scripts
# but since our python2 usage is deprecated, we should get rid of it.
RUN python3 -m pip install six==1.16.0
# Google Cloud Platform API libraries
# These are needed for uploading test results to BigQuery (e.g. by tools/run_tests scripts)
RUN python3 -m pip install --upgrade google-auth==1.23.0 google-api-python-client==1.12.8 oauth2client==4.1.0
# Some cxx tests depend on the twisted package
RUN python3 -m pip install twisted
#=================
# Install cmake
# Note that this step should be only used for distributions that have new enough cmake to satisfy gRPC's cmake version requirement.
RUN apt-get update && apt-get install -y cmake && apt-get clean
#=================
# Install ccache (use slighly older release of ccache that works older compilers and cmake)
# Install ccache from source since ccache 3.x packaged with most linux distributions
# does not support Redis backend for caching.
RUN curl -sSL -o ccache.tar.gz https://github.com/ccache/ccache/releases/download/v4.5.1/ccache-4.5.1.tar.gz \
&& tar -zxf ccache.tar.gz \
&& cd ccache-4.5.1 \
&& mkdir build && cd build \
&& cmake -DCMAKE_BUILD_TYPE=Release -DZSTD_FROM_INTERNET=ON -DHIREDIS_FROM_INTERNET=ON .. \
&& make -j4 && make install \
&& cd ../.. \
&& rm -rf ccache-4.5.1 ccache.tar.gz
RUN mkdir /var/local/jenkins
# Define the default command.
CMD ["bash"]

@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \
include/grpc/impl/propagation_bits.h \
include/grpc/impl/slice_type.h \
include/grpc/load_reporting.h \
include/grpc/passive_listener.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \
include/grpcpp/impl/service_type.h \
include/grpcpp/impl/status.h \
include/grpcpp/impl/sync.h \
include/grpcpp/passive_listener.h \
include/grpcpp/resource_quota.h \
include/grpcpp/security/audit_logging.h \
include/grpcpp/security/auth_context.h \

@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \
include/grpc/impl/propagation_bits.h \
include/grpc/impl/slice_type.h \
include/grpc/load_reporting.h \
include/grpc/passive_listener.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \
include/grpcpp/impl/service_type.h \
include/grpcpp/impl/status.h \
include/grpcpp/impl/sync.h \
include/grpcpp/passive_listener.h \
include/grpcpp/resource_quota.h \
include/grpcpp/security/audit_logging.h \
include/grpcpp/security/auth_context.h \

@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \
include/grpc/impl/propagation_bits.h \
include/grpc/impl/slice_type.h \
include/grpc/load_reporting.h \
include/grpc/passive_listener.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \

@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \
include/grpc/impl/propagation_bits.h \
include/grpc/impl/slice_type.h \
include/grpc/load_reporting.h \
include/grpc/passive_listener.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \

@ -82,8 +82,8 @@ BANNED_EXCEPT = {
"src/core/load_balancing/rls/rls.cc",
"src/core/resolver/google_c2p/google_c2p_resolver.cc",
],
# use 'grpc_core::Crash' instead
"GPR_ASSERT(false": [],
# use 'absl CHECK' instead
"GPR_ASSERT": [],
# Use `std::exchange()` instead.
"absl::exchange": [],
# Use `std::make_unique()` instead.

Loading…
Cancel
Save