mirror of https://github.com/grpc/grpc.git
[Metrics] New OpenTelemetry Plugin Implementation of Stats Plugin (#36070)
<!--
If you know who should review your pull request, please assign it to that
person, otherwise the pull request would get assigned randomly.
If your pull request is for a specific language, please add the appropriate
lang label.
-->
Closes #36070
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36070 from yijiem:grpc-metrics 72653727b1
PiperOrigin-RevId: 618529035
This commit is contained in:
parent
041c283ccc
commit
c54c69dcdd
1
BUILD
1
BUILD
|
|
@ -1695,7 +1695,6 @@ grpc_cc_library(
|
|||
language = "c++",
|
||||
visibility = ["@grpc:alt_grpc_base_legacy"],
|
||||
deps = [
|
||||
"config",
|
||||
"gpr",
|
||||
"legacy_context",
|
||||
"tcp_tracer",
|
||||
|
|
|
|||
|
|
@ -5695,7 +5695,7 @@ endif()
|
|||
if(gRPC_BUILD_GRPCPP_OTEL_PLUGIN)
|
||||
|
||||
add_library(grpcpp_otel_plugin
|
||||
src/cpp/ext/otel/otel_client_filter.cc
|
||||
src/cpp/ext/otel/otel_client_call_tracer.cc
|
||||
src/cpp/ext/otel/otel_plugin.cc
|
||||
src/cpp/ext/otel/otel_server_call_tracer.cc
|
||||
)
|
||||
|
|
@ -7560,6 +7560,7 @@ add_executable(bad_ping_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/bad_ping.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8035,6 +8036,7 @@ add_executable(binary_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/binary_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8474,6 +8476,7 @@ add_executable(call_creds_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/call_creds.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8680,6 +8683,7 @@ add_executable(call_host_override_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/call_host_override.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8785,6 +8789,7 @@ add_executable(cancel_after_accept_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_after_accept.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8847,6 +8852,7 @@ add_executable(cancel_after_client_done_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_after_client_done.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8909,6 +8915,7 @@ add_executable(cancel_after_invoke_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_after_invoke.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -8971,6 +8978,7 @@ add_executable(cancel_after_round_trip_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_after_round_trip.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -9080,6 +9088,7 @@ add_executable(cancel_before_invoke_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_before_invoke.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -9184,6 +9193,7 @@ add_executable(cancel_in_a_vacuum_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_in_a_vacuum.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -9246,6 +9256,7 @@ add_executable(cancel_with_status_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/cancel_with_status.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -10892,6 +10903,7 @@ add_executable(client_streaming_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/client_streaming.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -11230,6 +11242,7 @@ add_executable(compressed_payload_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/compressed_payload.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -11514,6 +11527,7 @@ add_executable(connectivity_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/connectivity.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -11942,6 +11956,7 @@ add_executable(default_host_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/default_host.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -12149,6 +12164,7 @@ add_executable(disappearing_server_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/disappearing_server.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -12468,6 +12484,7 @@ add_executable(empty_batch_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/empty_batch.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -13844,6 +13861,7 @@ add_executable(filter_causes_close_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/filter_causes_close.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -13906,6 +13924,7 @@ add_executable(filter_context_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/filter_context.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -13968,6 +13987,7 @@ add_executable(filter_init_fails_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/filter_init_fails.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -14080,6 +14100,7 @@ add_executable(filtered_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/filtered_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -14868,6 +14889,7 @@ add_executable(graceful_server_shutdown_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/graceful_server_shutdown.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -15233,6 +15255,7 @@ add_executable(grpc_authz_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/grpc_authz.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -16623,6 +16646,7 @@ add_executable(high_initial_seqno_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/high_initial_seqno.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -16931,6 +16955,7 @@ add_executable(hpack_size_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/hpack_size.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -17086,6 +17111,7 @@ add_executable(http2_stats_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/http2_stats.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -17978,6 +18004,7 @@ add_executable(invoke_large_request_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/invoke_large_request.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -18366,6 +18393,7 @@ add_executable(keepalive_timeout_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/keepalive_timeout.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -18471,6 +18499,7 @@ add_executable(large_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/large_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -19143,6 +19172,7 @@ add_executable(max_concurrent_streams_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/max_concurrent_streams.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -19205,6 +19235,7 @@ add_executable(max_connection_age_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/max_connection_age.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -19267,6 +19298,7 @@ add_executable(max_connection_idle_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/max_connection_idle.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -19329,6 +19361,7 @@ add_executable(max_message_length_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/max_message_length.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -20010,6 +20043,7 @@ add_executable(negative_deadline_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/negative_deadline.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -20104,6 +20138,7 @@ add_executable(no_logging_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/no_logging.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -20166,6 +20201,7 @@ add_executable(no_op_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/no_op.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -20633,9 +20669,10 @@ add_executable(otel_plugin_test
|
|||
${_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
|
||||
src/cpp/ext/otel/otel_client_filter.cc
|
||||
src/cpp/ext/otel/otel_client_call_tracer.cc
|
||||
src/cpp/ext/otel/otel_plugin.cc
|
||||
src/cpp/ext/otel/otel_server_call_tracer.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/cpp/end2end/test_service_impl.cc
|
||||
test/cpp/ext/otel/otel_plugin_test.cc
|
||||
test/cpp/ext/otel/otel_test_library.cc
|
||||
|
|
@ -21093,6 +21130,7 @@ add_executable(payload_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/payload.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -21467,6 +21505,7 @@ add_executable(ping_pong_streaming_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/ping_pong_streaming.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -21580,6 +21619,7 @@ add_executable(ping_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/ping.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -22573,6 +22613,7 @@ add_executable(proxy_auth_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/proxy_auth.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23148,6 +23189,7 @@ add_executable(registered_call_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/registered_call.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23254,6 +23296,7 @@ add_executable(request_with_flags_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/request_with_flags.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23316,6 +23359,7 @@ add_executable(request_with_payload_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/request_with_payload.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23649,6 +23693,7 @@ add_executable(resource_quota_server_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/resource_quota_server.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23753,6 +23798,7 @@ add_executable(retry_cancel_after_first_attempt_starts_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_cancel_after_first_attempt_starts.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23815,6 +23861,7 @@ add_executable(retry_cancel_during_delay_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_cancel_during_delay.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23877,6 +23924,7 @@ add_executable(retry_cancel_with_multiple_send_batches_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_cancel_with_multiple_send_batches.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -23939,6 +23987,7 @@ add_executable(retry_cancellation_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_cancellation.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24001,6 +24050,7 @@ add_executable(retry_disabled_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_disabled.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24063,6 +24113,7 @@ add_executable(retry_exceeds_buffer_size_in_delay_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_exceeds_buffer_size_in_delay.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24125,6 +24176,7 @@ add_executable(retry_exceeds_buffer_size_in_initial_batch_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24187,6 +24239,7 @@ add_executable(retry_exceeds_buffer_size_in_subsequent_batch_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24249,6 +24302,7 @@ add_executable(retry_lb_drop_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_lb_drop.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24311,6 +24365,7 @@ add_executable(retry_lb_fail_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_lb_fail.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24373,6 +24428,7 @@ add_executable(retry_non_retriable_status_before_trailers_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_non_retriable_status_before_trailers.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24435,6 +24491,7 @@ add_executable(retry_non_retriable_status_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_non_retriable_status.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24497,6 +24554,7 @@ add_executable(retry_per_attempt_recv_timeout_on_last_attempt_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_per_attempt_recv_timeout_on_last_attempt.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24559,6 +24617,7 @@ add_executable(retry_per_attempt_recv_timeout_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_per_attempt_recv_timeout.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24621,6 +24680,7 @@ add_executable(retry_recv_initial_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_recv_initial_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24683,6 +24743,7 @@ add_executable(retry_recv_message_replay_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_recv_message_replay.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24745,6 +24806,7 @@ add_executable(retry_recv_message_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_recv_message.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24807,6 +24869,7 @@ add_executable(retry_recv_trailing_metadata_error_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_recv_trailing_metadata_error.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24869,6 +24932,7 @@ add_executable(retry_send_initial_metadata_refs_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_send_initial_metadata_refs.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24931,6 +24995,7 @@ add_executable(retry_send_op_fails_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_send_op_fails.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -24993,6 +25058,7 @@ add_executable(retry_send_recv_batch_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_send_recv_batch.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25055,6 +25121,7 @@ add_executable(retry_server_pushback_delay_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_server_pushback_delay.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25117,6 +25184,7 @@ add_executable(retry_server_pushback_disabled_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_server_pushback_disabled.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25221,6 +25289,7 @@ add_executable(retry_streaming_after_commit_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_streaming_after_commit.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25283,6 +25352,7 @@ add_executable(retry_streaming_succeeds_before_replay_finished_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25345,6 +25415,7 @@ add_executable(retry_streaming_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_streaming.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25407,6 +25478,7 @@ add_executable(retry_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25511,6 +25583,7 @@ add_executable(retry_throttled_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_throttled.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25573,6 +25646,7 @@ add_executable(retry_too_many_attempts_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_too_many_attempts.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25635,6 +25709,7 @@ add_executable(retry_transparent_goaway_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_transparent_goaway.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25697,6 +25772,7 @@ add_executable(retry_transparent_max_concurrent_streams_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_transparent_max_concurrent_streams.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25759,6 +25835,7 @@ add_executable(retry_transparent_not_sent_on_wire_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_transparent_not_sent_on_wire.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25821,6 +25898,7 @@ add_executable(retry_unref_before_finish_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_unref_before_finish.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -25883,6 +25961,7 @@ add_executable(retry_unref_before_recv_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/retry_unref_before_recv.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -26866,6 +26945,7 @@ add_executable(server_finishes_request_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/server_finishes_request.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27149,6 +27229,7 @@ add_executable(server_streaming_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/server_streaming.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27410,6 +27491,7 @@ add_executable(shutdown_finishes_calls_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/shutdown_finishes_calls.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27472,6 +27554,7 @@ add_executable(shutdown_finishes_tags_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/shutdown_finishes_tags.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27597,6 +27680,7 @@ add_executable(simple_delayed_request_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/simple_delayed_request.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27659,6 +27743,7 @@ add_executable(simple_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/simple_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -27765,6 +27850,7 @@ add_executable(simple_request_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/simple_request.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -28690,6 +28776,7 @@ add_executable(streaming_error_response_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/streaming_error_response.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -29421,6 +29508,7 @@ add_executable(test_core_end2end_channelz_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/channelz.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -30679,6 +30767,7 @@ add_executable(timeout_before_request_call_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/timeout_before_request_call.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -31182,6 +31271,7 @@ add_executable(trailing_metadata_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/trailing_metadata.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -32417,6 +32507,7 @@ add_executable(write_buffering_at_end_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/write_buffering_at_end.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
@ -32479,6 +32570,7 @@ add_executable(write_buffering_test
|
|||
test/core/end2end/fixtures/proxy.cc
|
||||
test/core/end2end/tests/write_buffering.cc
|
||||
test/core/event_engine/event_engine_test_utils.cc
|
||||
test/core/util/fake_stats_plugin.cc
|
||||
test/core/util/test_lb_policies.cc
|
||||
)
|
||||
if(WIN32 AND MSVC)
|
||||
|
|
|
|||
|
|
@ -1160,6 +1160,7 @@ let package = Package(
|
|||
"src/core/lib/channel/promise_based_filter.cc",
|
||||
"src/core/lib/channel/promise_based_filter.h",
|
||||
"src/core/lib/channel/server_call_tracer_filter.cc",
|
||||
"src/core/lib/channel/server_call_tracer_filter.h",
|
||||
"src/core/lib/channel/status_util.cc",
|
||||
"src/core/lib/channel/status_util.h",
|
||||
"src/core/lib/channel/tcp_tracer.h",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -909,6 +909,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/context.h',
|
||||
'src/core/lib/channel/metrics.h',
|
||||
'src/core/lib/channel/promise_based_filter.h',
|
||||
'src/core/lib/channel/server_call_tracer_filter.h',
|
||||
'src/core/lib/channel/status_util.h',
|
||||
'src/core/lib/channel/tcp_tracer.h',
|
||||
'src/core/lib/compression/compression_internal.h',
|
||||
|
|
@ -2175,6 +2176,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/context.h',
|
||||
'src/core/lib/channel/metrics.h',
|
||||
'src/core/lib/channel/promise_based_filter.h',
|
||||
'src/core/lib/channel/server_call_tracer_filter.h',
|
||||
'src/core/lib/channel/status_util.h',
|
||||
'src/core/lib/channel/tcp_tracer.h',
|
||||
'src/core/lib/compression/compression_internal.h',
|
||||
|
|
|
|||
|
|
@ -1276,6 +1276,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/promise_based_filter.cc',
|
||||
'src/core/lib/channel/promise_based_filter.h',
|
||||
'src/core/lib/channel/server_call_tracer_filter.cc',
|
||||
'src/core/lib/channel/server_call_tracer_filter.h',
|
||||
'src/core/lib/channel/status_util.cc',
|
||||
'src/core/lib/channel/status_util.h',
|
||||
'src/core/lib/channel/tcp_tracer.h',
|
||||
|
|
@ -2957,6 +2958,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/channel/context.h',
|
||||
'src/core/lib/channel/metrics.h',
|
||||
'src/core/lib/channel/promise_based_filter.h',
|
||||
'src/core/lib/channel/server_call_tracer_filter.h',
|
||||
'src/core/lib/channel/status_util.h',
|
||||
'src/core/lib/channel/tcp_tracer.h',
|
||||
'src/core/lib/compression/compression_internal.h',
|
||||
|
|
|
|||
|
|
@ -1166,6 +1166,7 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/channel/promise_based_filter.cc )
|
||||
s.files += %w( src/core/lib/channel/promise_based_filter.h )
|
||||
s.files += %w( src/core/lib/channel/server_call_tracer_filter.cc )
|
||||
s.files += %w( src/core/lib/channel/server_call_tracer_filter.h )
|
||||
s.files += %w( src/core/lib/channel/status_util.cc )
|
||||
s.files += %w( src/core/lib/channel/status_util.h )
|
||||
s.files += %w( src/core/lib/channel/tcp_tracer.h )
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ class OpenTelemetryPluginBuilder {
|
|||
/// options can be added.
|
||||
OpenTelemetryPluginBuilder& AddPluginOption(
|
||||
std::unique_ptr<OpenTelemetryPluginOption> option);
|
||||
// Records \a optional_label_key on all metrics that provide it.
|
||||
OpenTelemetryPluginBuilder& AddOptionalLabel(
|
||||
absl::string_view optional_label_key);
|
||||
/// Registers a global plugin that acts on all channels and servers running on
|
||||
/// the process.
|
||||
absl::Status BuildAndRegisterGlobal();
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,7 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/channel/promise_based_filter.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/promise_based_filter.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/server_call_tracer_filter.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/server_call_tracer_filter.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/status_util.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/status_util.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/channel/tcp_tracer.h" role="src" />
|
||||
|
|
|
|||
|
|
@ -119,6 +119,9 @@ grpc_cc_library(
|
|||
srcs = [
|
||||
"lib/channel/server_call_tracer_filter.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"lib/channel/server_call_tracer_filter.h",
|
||||
],
|
||||
external_deps = [
|
||||
"absl/status",
|
||||
"absl/status:statusor",
|
||||
|
|
@ -7548,6 +7551,7 @@ grpc_cc_library(
|
|||
"//:api_trace",
|
||||
"//:channel",
|
||||
"//:channel_create",
|
||||
"//:config",
|
||||
"//:debug_location",
|
||||
"//:exec_ctx",
|
||||
"//:gpr",
|
||||
|
|
@ -7579,10 +7583,14 @@ grpc_cc_library(
|
|||
],
|
||||
language = "c++",
|
||||
deps = [
|
||||
"arena",
|
||||
"channel_args",
|
||||
"no_destruct",
|
||||
"slice",
|
||||
"time",
|
||||
"//:call_tracer",
|
||||
"//:gpr",
|
||||
"//:legacy_context",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1340,6 +1340,7 @@ ClientChannelFilter::CreateLoadBalancedCall(
|
|||
const grpc_call_element_args& args, grpc_polling_entity* pollent,
|
||||
grpc_closure* on_call_destruction_complete,
|
||||
absl::AnyInvocable<void()> on_commit, bool is_transparent_retry) {
|
||||
promise_detail::Context<Arena> arena_ctx(args.arena);
|
||||
return OrphanablePtr<FilterBasedLoadBalancedCall>(
|
||||
args.arena->New<FilterBasedLoadBalancedCall>(
|
||||
this, args, pollent, on_call_destruction_complete,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "src/core/ext/transport/chaotic_good/frame_header.h"
|
||||
#include "src/core/ext/transport/chaotic_good/settings_metadata.h"
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/event_engine/channel_args_endpoint_config.h"
|
||||
#include "src/core/lib/event_engine/extensions/chaotic_good_extension.h"
|
||||
#include "src/core/lib/event_engine/query_extensions.h"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/ext/transport/inproc/legacy_inproc_transport.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/experiments/experiments.h"
|
||||
#include "src/core/lib/gprpp/crash.h"
|
||||
#include "src/core/lib/promise/promise.h"
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ namespace {
|
|||
GlobalStatsPluginRegistry::StatsPluginGroup GetStatsPluginGroupForKey(
|
||||
absl::string_view key) {
|
||||
if (key == GrpcXdsClient::kServerKey) {
|
||||
return GlobalStatsPluginRegistry::GetAllStatsPlugins();
|
||||
return GlobalStatsPluginRegistry::GetStatsPluginsForServer(ChannelArgs{});
|
||||
}
|
||||
// TODO(roth): How do we set the authority here?
|
||||
StatsPlugin::ChannelScope scope(key, "");
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/channel/tcp_tracer.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/core/lib/slice/slice_buffer.h"
|
||||
|
|
@ -207,8 +206,6 @@ class ServerCallTracerFactory {
|
|||
static absl::string_view ChannelArgName();
|
||||
};
|
||||
|
||||
void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder);
|
||||
|
||||
// Convenience functions to add call tracers to a call context. Allows setting
|
||||
// multiple call tracers to a single call. It is only valid to add client call
|
||||
// tracers before the client_channel filter sees the send_initial_metadata op.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "src/core/lib/channel/metrics.h"
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include <memory>
|
||||
|
||||
#include "src/core/lib/gprpp/crash.h"
|
||||
|
||||
|
|
@ -24,11 +24,10 @@ namespace grpc_core {
|
|||
|
||||
// Uses the Construct-on-First-Use idiom to avoid the static initialization
|
||||
// order fiasco.
|
||||
absl::flat_hash_map<absl::string_view,
|
||||
GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
|
||||
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
|
||||
GlobalInstrumentsRegistry::GetInstrumentList() {
|
||||
static NoDestruct<absl::flat_hash_map<
|
||||
absl::string_view, GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>>
|
||||
static NoDestruct<
|
||||
std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>>
|
||||
instruments;
|
||||
return *instruments;
|
||||
}
|
||||
|
|
@ -40,8 +39,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -56,7 +58,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalUInt64CounterHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -69,8 +71,11 @@ GlobalInstrumentsRegistry::RegisterDoubleCounter(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -85,7 +90,7 @@ GlobalInstrumentsRegistry::RegisterDoubleCounter(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalDoubleCounterHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -98,8 +103,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Histogram(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -114,7 +122,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Histogram(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalUInt64HistogramHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -127,8 +135,11 @@ GlobalInstrumentsRegistry::RegisterDoubleHistogram(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -143,7 +154,7 @@ GlobalInstrumentsRegistry::RegisterDoubleHistogram(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalDoubleHistogramHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -156,8 +167,11 @@ GlobalInstrumentsRegistry::RegisterInt64Gauge(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -172,7 +186,7 @@ GlobalInstrumentsRegistry::RegisterInt64Gauge(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalInt64GaugeHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -185,8 +199,11 @@ GlobalInstrumentsRegistry::RegisterDoubleGauge(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -201,7 +218,7 @@ GlobalInstrumentsRegistry::RegisterDoubleGauge(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalDoubleGaugeHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -214,8 +231,11 @@ GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -230,7 +250,7 @@ GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalCallbackInt64GaugeHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -243,8 +263,11 @@ GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
|
|||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
bool enable_by_default) {
|
||||
auto& instruments = GetInstrumentList();
|
||||
if (instruments.find(name) != instruments.end()) {
|
||||
Crash(absl::StrFormat("Metric name %s has already been registered.", name));
|
||||
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();
|
||||
GPR_ASSERT(index < std::numeric_limits<uint32_t>::max());
|
||||
|
|
@ -259,7 +282,7 @@ GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
|
|||
descriptor.label_keys = {label_keys.begin(), label_keys.end()};
|
||||
descriptor.optional_label_keys = {optional_label_keys.begin(),
|
||||
optional_label_keys.end()};
|
||||
instruments.emplace(name, std::move(descriptor));
|
||||
instruments.push_back(std::move(descriptor));
|
||||
GlobalCallbackDoubleGaugeHandle handle;
|
||||
handle.index = index;
|
||||
return handle;
|
||||
|
|
@ -268,10 +291,16 @@ GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge(
|
|||
void GlobalInstrumentsRegistry::ForEach(
|
||||
absl::FunctionRef<void(const GlobalInstrumentDescriptor&)> f) {
|
||||
for (const auto& instrument : GetInstrumentList()) {
|
||||
f(instrument.second);
|
||||
f(instrument);
|
||||
}
|
||||
}
|
||||
|
||||
const GlobalInstrumentsRegistry::GlobalInstrumentDescriptor&
|
||||
GlobalInstrumentsRegistry::GetInstrumentDescriptor(
|
||||
GlobalInstrumentHandle handle) {
|
||||
return GetInstrumentList().at(handle.index);
|
||||
}
|
||||
|
||||
RegisteredMetricCallback::RegisteredMetricCallback(
|
||||
GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group,
|
||||
absl::AnyInvocable<void(CallbackMetricReporter&)> callback,
|
||||
|
|
@ -281,14 +310,14 @@ RegisteredMetricCallback::RegisteredMetricCallback(
|
|||
callback_(std::move(callback)),
|
||||
metrics_(std::move(metrics)),
|
||||
min_interval_(min_interval) {
|
||||
for (auto& plugin : stats_plugin_group_.plugins_) {
|
||||
plugin->AddCallback(this);
|
||||
for (auto& state : stats_plugin_group_.plugins_state_) {
|
||||
state.plugin->AddCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
RegisteredMetricCallback::~RegisteredMetricCallback() {
|
||||
for (auto& plugin : stats_plugin_group_.plugins_) {
|
||||
plugin->RemoveCallback(this);
|
||||
for (auto& state : stats_plugin_group_.plugins_state_) {
|
||||
state.plugin->RemoveCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -301,6 +330,28 @@ GlobalStatsPluginRegistry::StatsPluginGroup::RegisterCallback(
|
|||
*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) {
|
||||
for (auto& state : plugins_state_) {
|
||||
auto* call_tracer = state.plugin->GetClientCallTracer(
|
||||
path, registered_method, state.scope_config);
|
||||
if (call_tracer != nullptr) {
|
||||
AddClientCallTracerToContext(call_context, call_tracer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalStatsPluginRegistry::StatsPluginGroup::AddServerCallTracers(
|
||||
grpc_call_context_element* call_context) {
|
||||
for (auto& state : plugins_state_) {
|
||||
auto* call_tracer = state.plugin->GetServerCallTracer(state.scope_config);
|
||||
if (call_tracer != nullptr) {
|
||||
AddServerCallTracerToContext(call_context, call_tracer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NoDestruct<Mutex> GlobalStatsPluginRegistry::mutex_;
|
||||
NoDestruct<std::vector<std::shared_ptr<StatsPlugin>>>
|
||||
GlobalStatsPluginRegistry::plugins_;
|
||||
|
|
@ -311,24 +362,32 @@ void GlobalStatsPluginRegistry::RegisterStatsPlugin(
|
|||
plugins_->push_back(std::move(plugin));
|
||||
}
|
||||
|
||||
GlobalStatsPluginRegistry::StatsPluginGroup
|
||||
GlobalStatsPluginRegistry::GetAllStatsPlugins() {
|
||||
MutexLock lock(&*mutex_);
|
||||
StatsPluginGroup group;
|
||||
for (const auto& plugin : *plugins_) {
|
||||
group.push_back(plugin);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
GlobalStatsPluginRegistry::StatsPluginGroup
|
||||
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
|
||||
const StatsPlugin::ChannelScope& scope) {
|
||||
MutexLock lock(&*mutex_);
|
||||
StatsPluginGroup group;
|
||||
for (const auto& plugin : *plugins_) {
|
||||
if (plugin->IsEnabledForChannel(scope)) {
|
||||
group.push_back(plugin);
|
||||
bool is_enabled = false;
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> config;
|
||||
std::tie(is_enabled, config) = plugin->IsEnabledForChannel(scope);
|
||||
if (is_enabled) {
|
||||
group.AddStatsPlugin(plugin, std::move(config));
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
GlobalStatsPluginRegistry::StatsPluginGroup
|
||||
GlobalStatsPluginRegistry::GetStatsPluginsForServer(const ChannelArgs& args) {
|
||||
MutexLock lock(&*mutex_);
|
||||
StatsPluginGroup group;
|
||||
for (const auto& plugin : *plugins_) {
|
||||
bool is_enabled = false;
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> config;
|
||||
std::tie(is_enabled, config) = plugin->IsEnabledForServer(args);
|
||||
if (is_enabled) {
|
||||
group.AddStatsPlugin(plugin, std::move(config));
|
||||
}
|
||||
}
|
||||
return group;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,13 @@
|
|||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/call_tracer.h"
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/gprpp/no_destruct.h"
|
||||
#include "src/core/lib/gprpp/sync.h"
|
||||
#include "src/core/lib/gprpp/time.h"
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
|
|
@ -58,10 +61,11 @@ class GlobalInstrumentsRegistry {
|
|||
kGauge,
|
||||
kCallbackGauge,
|
||||
};
|
||||
using InstrumentID = uint32_t;
|
||||
struct GlobalInstrumentDescriptor {
|
||||
ValueType value_type;
|
||||
InstrumentType instrument_type;
|
||||
uint32_t index;
|
||||
InstrumentID index;
|
||||
bool enable_by_default;
|
||||
absl::string_view name;
|
||||
absl::string_view description;
|
||||
|
|
@ -69,20 +73,20 @@ class GlobalInstrumentsRegistry {
|
|||
std::vector<absl::string_view> label_keys;
|
||||
std::vector<absl::string_view> optional_label_keys;
|
||||
};
|
||||
struct GlobalHandle {
|
||||
struct GlobalInstrumentHandle {
|
||||
// This is the index for the corresponding registered instrument that
|
||||
// StatsPlugins can use to uniquely identify an instrument in the current
|
||||
// process. Though this is not guaranteed to be stable between different
|
||||
// runs or between different versions.
|
||||
uint32_t index;
|
||||
InstrumentID index;
|
||||
};
|
||||
struct GlobalUInt64CounterHandle : public GlobalHandle {};
|
||||
struct GlobalDoubleCounterHandle : public GlobalHandle {};
|
||||
struct GlobalUInt64HistogramHandle : public GlobalHandle {};
|
||||
struct GlobalDoubleHistogramHandle : public GlobalHandle {};
|
||||
struct GlobalInt64GaugeHandle : public GlobalHandle {};
|
||||
struct GlobalDoubleGaugeHandle : public GlobalHandle {};
|
||||
struct GlobalCallbackHandle : public GlobalHandle {};
|
||||
struct GlobalUInt64CounterHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalDoubleCounterHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalUInt64HistogramHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalDoubleHistogramHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalInt64GaugeHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalDoubleGaugeHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalCallbackHandle : public GlobalInstrumentHandle {};
|
||||
struct GlobalCallbackInt64GaugeHandle : public GlobalCallbackHandle {};
|
||||
struct GlobalCallbackDoubleGaugeHandle : public GlobalCallbackHandle {};
|
||||
|
||||
|
|
@ -130,14 +134,15 @@ class GlobalInstrumentsRegistry {
|
|||
|
||||
static void ForEach(
|
||||
absl::FunctionRef<void(const GlobalInstrumentDescriptor&)> f);
|
||||
static const GlobalInstrumentDescriptor& GetInstrumentDescriptor(
|
||||
GlobalInstrumentHandle handle);
|
||||
|
||||
private:
|
||||
friend class GlobalInstrumentsRegistryTestPeer;
|
||||
|
||||
GlobalInstrumentsRegistry() = delete;
|
||||
|
||||
static absl::flat_hash_map<
|
||||
absl::string_view, GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
|
||||
static std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
|
||||
GetInstrumentList();
|
||||
};
|
||||
|
||||
|
|
@ -162,6 +167,7 @@ class RegisteredMetricCallback;
|
|||
// The StatsPlugin interface.
|
||||
class StatsPlugin {
|
||||
public:
|
||||
// Configuration (scope) for a specific client channel.
|
||||
class ChannelScope {
|
||||
public:
|
||||
ChannelScope(absl::string_view target, absl::string_view authority)
|
||||
|
|
@ -174,37 +180,74 @@ class StatsPlugin {
|
|||
absl::string_view target_;
|
||||
absl::string_view authority_;
|
||||
};
|
||||
// A general-purpose way for stats plugin to store per-channel or per-server
|
||||
// state.
|
||||
class ScopeConfig {
|
||||
public:
|
||||
virtual ~ScopeConfig() = default;
|
||||
};
|
||||
|
||||
virtual ~StatsPlugin() = default;
|
||||
|
||||
virtual bool IsEnabledForChannel(const ChannelScope& scope) const = 0;
|
||||
virtual bool IsEnabledForServer(const ChannelArgs& args) const = 0;
|
||||
// Whether this stats plugin is enabled for the channel specified by \a scope.
|
||||
// Returns true and a channel-specific ScopeConfig which may then be used to
|
||||
// configure the ClientCallTracer in GetClientCallTracer().
|
||||
virtual std::pair<bool, std::shared_ptr<ScopeConfig>> IsEnabledForChannel(
|
||||
const ChannelScope& scope) const = 0;
|
||||
// Whether this stats plugin is enabled for the server specified by \a args.
|
||||
// Returns true and a server-specific ScopeConfig which may then be used to
|
||||
// configure the ServerCallTracer in GetServerCallTracer().
|
||||
virtual std::pair<bool, std::shared_ptr<ScopeConfig>> IsEnabledForServer(
|
||||
const ChannelArgs& args) const = 0;
|
||||
|
||||
// Adds \a value to the uint64 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::RegisterUInt64Counter().
|
||||
virtual void AddCounter(
|
||||
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
|
||||
uint64_t value, absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
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,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
absl::Span<const absl::string_view> optional_label_values) = 0;
|
||||
// Records a uint64 \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::RegisterUInt64Histogram().
|
||||
virtual void RecordHistogram(
|
||||
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
|
||||
uint64_t value, absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
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,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
absl::Span<const absl::string_view> optional_label_values) = 0;
|
||||
// Sets an int64 \a value to the gauge specifed 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::RegisterInt64Gauge().
|
||||
virtual void SetGauge(
|
||||
GlobalInstrumentsRegistry::GlobalInt64GaugeHandle handle, int64_t value,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
absl::Span<const absl::string_view> optional_label_values) = 0;
|
||||
// Sets a double \a value to the gauge specifed 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::RegisterDoubleGauge().
|
||||
virtual void SetGauge(
|
||||
GlobalInstrumentsRegistry::GlobalDoubleGaugeHandle handle, double value,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) = 0;
|
||||
|
||||
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).
|
||||
virtual void AddCallback(RegisteredMetricCallback* callback) = 0;
|
||||
|
|
@ -212,13 +255,15 @@ class StatsPlugin {
|
|||
// plugin may not use the callback after this method returns.
|
||||
virtual void RemoveCallback(RegisteredMetricCallback* callback) = 0;
|
||||
|
||||
// TODO(yijiem): Details pending.
|
||||
// std::unique_ptr<AsyncInstrument> GetObservableGauge(
|
||||
// absl::string_view name, absl::string_view description,
|
||||
// absl::string_view unit);
|
||||
// AsyncInstrument* GetObservableCounter(
|
||||
// absl::string_view name, absl::string_view description,
|
||||
// absl::string_view unit);
|
||||
// Gets a ClientCallTracer associated with this stats plugin which can be used
|
||||
// in a call.
|
||||
virtual ClientCallTracer* GetClientCallTracer(
|
||||
const Slice& path, bool registered_method,
|
||||
std::shared_ptr<ScopeConfig> scope_config) = 0;
|
||||
// Gets a ServerCallTracer associated with this stats plugin which can be used
|
||||
// in a call.
|
||||
virtual ServerCallTracer* GetServerCallTracer(
|
||||
std::shared_ptr<ScopeConfig> scope_config) = 0;
|
||||
|
||||
// TODO(yijiem): This is an optimization for the StatsPlugin to create its own
|
||||
// representation of the label_values and use it multiple times. We would
|
||||
|
|
@ -230,63 +275,55 @@ class StatsPlugin {
|
|||
// absl::Span<absl::string_view> label_values) = 0;
|
||||
};
|
||||
|
||||
// A global registry of StatsPlugins. It has shared ownership to the registered
|
||||
// StatsPlugins. This API is supposed to be used during runtime after the main
|
||||
// A global registry of stats plugins. It has shared ownership to the registered
|
||||
// stats plugins. This API is supposed to be used during runtime after the main
|
||||
// function begins. This API is thread-safe.
|
||||
class GlobalStatsPluginRegistry {
|
||||
public:
|
||||
// A stats plugin group object is how the code in gRPC normally interacts with
|
||||
// stats plugins. They got a stats plugin group which contains all the stats
|
||||
// plugins for a specific scope and all operations on the stats plugin group
|
||||
// will be applied to all the stats plugins within the group.
|
||||
class StatsPluginGroup {
|
||||
public:
|
||||
void push_back(std::shared_ptr<StatsPlugin> plugin) {
|
||||
plugins_.push_back(std::move(plugin));
|
||||
// Adds a stats plugin and a scope config (per-channel or per-server) to the
|
||||
// group.
|
||||
void AddStatsPlugin(std::shared_ptr<StatsPlugin> plugin,
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> config) {
|
||||
PluginState plugin_state;
|
||||
plugin_state.plugin = std::move(plugin);
|
||||
plugin_state.scope_config = std::move(config);
|
||||
plugins_state_.push_back(std::move(plugin_state));
|
||||
}
|
||||
|
||||
void AddCounter(GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
|
||||
uint64_t value,
|
||||
// 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) {
|
||||
for (auto& plugin : plugins_) {
|
||||
plugin->AddCounter(handle, value, label_values, optional_values);
|
||||
for (auto& state : plugins_state_) {
|
||||
state.plugin->AddCounter(handle, value, label_values, optional_values);
|
||||
}
|
||||
}
|
||||
void AddCounter(GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle,
|
||||
double value,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) {
|
||||
for (auto& plugin : plugins_) {
|
||||
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) {
|
||||
for (auto& state : plugins_state_) {
|
||||
state.plugin->RecordHistogram(handle, value, label_values,
|
||||
optional_values);
|
||||
}
|
||||
}
|
||||
void RecordHistogram(
|
||||
GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle,
|
||||
uint64_t value, absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) {
|
||||
for (auto& plugin : plugins_) {
|
||||
plugin->RecordHistogram(handle, value, label_values, optional_values);
|
||||
}
|
||||
}
|
||||
void RecordHistogram(
|
||||
GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle,
|
||||
double value, absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) {
|
||||
for (auto& plugin : plugins_) {
|
||||
plugin->RecordHistogram(handle, value, label_values, optional_values);
|
||||
}
|
||||
}
|
||||
void SetGauge(GlobalInstrumentsRegistry::GlobalInt64GaugeHandle handle,
|
||||
int64_t value,
|
||||
// Sets a value to a gauge in all stats plugins within the group. See the
|
||||
// StatsPlugin interface for more documentation and valid types.
|
||||
template <class HandleType, class ValueType>
|
||||
void SetGauge(HandleType handle, ValueType value,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) {
|
||||
for (auto& plugin : plugins_) {
|
||||
plugin->SetGauge(handle, value, label_values, optional_values);
|
||||
}
|
||||
}
|
||||
void SetGauge(GlobalInstrumentsRegistry::GlobalDoubleGaugeHandle handle,
|
||||
double value,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) {
|
||||
for (auto& plugin : plugins_) {
|
||||
plugin->SetGauge(handle, value, label_values, optional_values);
|
||||
for (auto& state : plugins_state_) {
|
||||
state.plugin->SetGauge(handle, value, label_values, optional_values);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -303,21 +340,33 @@ class GlobalStatsPluginRegistry {
|
|||
std::vector<GlobalInstrumentsRegistry::GlobalCallbackHandle> metrics,
|
||||
Duration min_interval = Duration::Seconds(5));
|
||||
|
||||
// Adds all available client call tracers associated with the stats plugins
|
||||
// within the group to \a call_context.
|
||||
void AddClientCallTracers(const Slice& path, bool registered_method,
|
||||
grpc_call_context_element* call_context);
|
||||
// Adds all available server call tracers associated with the stats plugins
|
||||
// within the group to \a call_context.
|
||||
void AddServerCallTracers(grpc_call_context_element* call_context);
|
||||
|
||||
private:
|
||||
friend class RegisteredMetricCallback;
|
||||
|
||||
std::vector<std::shared_ptr<StatsPlugin>> plugins_;
|
||||
struct PluginState {
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> scope_config;
|
||||
std::shared_ptr<StatsPlugin> plugin;
|
||||
};
|
||||
|
||||
std::vector<PluginState> plugins_state_;
|
||||
};
|
||||
|
||||
// Registers a stats plugin with the global stats plugin registry.
|
||||
static void RegisterStatsPlugin(std::shared_ptr<StatsPlugin> plugin);
|
||||
|
||||
// The following functions can be invoked to get a StatsPluginGroup for
|
||||
// a specified scope.
|
||||
static StatsPluginGroup GetAllStatsPlugins();
|
||||
static StatsPluginGroup GetStatsPluginsForChannel(
|
||||
const StatsPlugin::ChannelScope& scope);
|
||||
// TODO(yijiem): Implement this.
|
||||
// StatsPluginsGroup GetStatsPluginsForServer(ChannelArgs& args);
|
||||
static StatsPluginGroup GetStatsPluginsForServer(const ChannelArgs& args);
|
||||
|
||||
private:
|
||||
friend class GlobalStatsPluginRegistryTestPeer;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "src/core/lib/channel/server_call_tracer_filter.h"
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
// 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_SRC_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_FILTER_H
|
||||
#define GRPC_SRC_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_FILTER_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder);
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_FILTER_H
|
||||
|
|
@ -588,6 +588,12 @@ class FilterStackCall final : public Call {
|
|||
}
|
||||
|
||||
private:
|
||||
class ScopedContext : public promise_detail::Context<Arena> {
|
||||
public:
|
||||
explicit ScopedContext(FilterStackCall* call)
|
||||
: promise_detail::Context<Arena>(call->arena()) {}
|
||||
};
|
||||
|
||||
static constexpr gpr_atm kRecvNone = 0;
|
||||
static constexpr gpr_atm kRecvInitialMetadataFirst = 1;
|
||||
|
||||
|
|
@ -807,6 +813,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|||
GPR_DEBUG_ASSERT(FromCallStack(call->call_stack()) == call);
|
||||
*out_call = call->c_ptr();
|
||||
grpc_slice path = grpc_empty_slice();
|
||||
ScopedContext ctx(call);
|
||||
if (call->is_client()) {
|
||||
call->final_op_.client.status_details = nullptr;
|
||||
call->final_op_.client.status = nullptr;
|
||||
|
|
@ -822,6 +829,8 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|||
call->send_initial_metadata_.Set(
|
||||
GrpcRegisteredMethod(), reinterpret_cast<void*>(static_cast<uintptr_t>(
|
||||
args->registered_method)));
|
||||
channel_stack->stats_plugin_group->AddClientCallTracers(
|
||||
Slice(CSliceRef(path)), args->registered_method, call->context_);
|
||||
} else {
|
||||
global_stats().IncrementServerCallsCreated();
|
||||
call->final_op_.server.cancelled = nullptr;
|
||||
|
|
@ -830,6 +839,9 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|||
// collecting from when the call is created at the transport. The idea is
|
||||
// that the transport would create the call tracer and pass it in as part of
|
||||
// the metadata.
|
||||
// TODO(yijiem): OpenCensus and internal Census is still using this way to
|
||||
// set server call tracer. We need to refactor them to stats plugins
|
||||
// (including removing the client channel filters).
|
||||
if (args->server != nullptr &&
|
||||
args->server->server_call_tracer_factory() != nullptr) {
|
||||
auto* server_call_tracer =
|
||||
|
|
@ -846,6 +858,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
|
|||
call->ContextSet(GRPC_CONTEXT_CALL_TRACER, server_call_tracer, nullptr);
|
||||
}
|
||||
}
|
||||
channel_stack->stats_plugin_group->AddServerCallTracers(call->context_);
|
||||
}
|
||||
|
||||
Call* parent = Call::FromC(args->parent);
|
||||
|
|
@ -2725,6 +2738,8 @@ class ClientPromiseBasedCall final : public PromiseBasedCall {
|
|||
"non-nullptr.");
|
||||
}
|
||||
ScopedContext context(this);
|
||||
args->channel->channel_stack()->stats_plugin_group->AddClientCallTracers(
|
||||
*args->path, args->registered_method, this->context());
|
||||
send_initial_metadata_ =
|
||||
GetContext<Arena>()->MakePooled<ClientMetadata>(GetContext<Arena>());
|
||||
send_initial_metadata_->Set(HttpPathMetadata(), std::move(*args->path));
|
||||
|
|
@ -3390,11 +3405,16 @@ ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena,
|
|||
if (channelz_node != nullptr) {
|
||||
channelz_node->RecordCallStarted();
|
||||
}
|
||||
ScopedContext activity_context(this);
|
||||
// TODO(yashykt): In the future, we want to also enable stats and trace
|
||||
// collecting from when the call is created at the transport. The idea is that
|
||||
// the transport would create the call tracer and pass it in as part of the
|
||||
// metadata.
|
||||
if (args->server->server_call_tracer_factory() != nullptr) {
|
||||
// TODO(yijiem): OpenCensus and internal Census is still using this way to
|
||||
// set server call tracer. We need to refactor them to stats plugins
|
||||
// (including removing the client channel filters).
|
||||
if (args->server != nullptr &&
|
||||
args->server->server_call_tracer_factory() != nullptr) {
|
||||
auto* server_call_tracer =
|
||||
args->server->server_call_tracer_factory()->CreateNewServerCallTracer(
|
||||
arena, args->server->channel_args());
|
||||
|
|
@ -3409,7 +3429,8 @@ ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena,
|
|||
ContextSet(GRPC_CONTEXT_CALL_TRACER, server_call_tracer, nullptr);
|
||||
}
|
||||
}
|
||||
ScopedContext activity_context(this);
|
||||
args->channel->channel_stack()->stats_plugin_group->AddServerCallTracers(
|
||||
context());
|
||||
Spawn("server_promise",
|
||||
channel()->channel_stack()->MakeServerCallPromise(
|
||||
CallArgs{nullptr, ClientInitialMetadataOutstandingToken::Empty(),
|
||||
|
|
|
|||
|
|
@ -89,12 +89,17 @@ absl::StatusOr<OrphanablePtr<Channel>> LegacyChannel::Create(
|
|||
status.ToString().c_str());
|
||||
return status;
|
||||
}
|
||||
// TODO(roth): Figure out how to populate authority here.
|
||||
// Or maybe just don't worry about this if no one needs it until after
|
||||
// the call v3 stack lands.
|
||||
StatsPlugin::ChannelScope scope(builder.target(), "");
|
||||
*(*r)->stats_plugin_group =
|
||||
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(scope);
|
||||
if (channel_stack_type == GRPC_SERVER_CHANNEL) {
|
||||
*(*r)->stats_plugin_group =
|
||||
GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
} else {
|
||||
// TODO(roth): Figure out how to populate authority here.
|
||||
// Or maybe just don't worry about this if no one needs it until after
|
||||
// the call v3 stack lands.
|
||||
StatsPlugin::ChannelScope scope(target, "");
|
||||
*(*r)->stats_plugin_group =
|
||||
GlobalStatsPluginRegistry::GetStatsPluginsForChannel(scope);
|
||||
}
|
||||
return MakeOrphanable<LegacyChannel>(
|
||||
grpc_channel_stack_type_is_client(builder.channel_stack_type()),
|
||||
builder.IsPromising(), std::move(target), args, std::move(*r));
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <grpc/grpc.h>
|
||||
|
||||
#include "src/core/lib/channel/server_call_tracer_filter.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/core/lib/surface/lame_client.h"
|
||||
|
|
@ -27,7 +28,6 @@
|
|||
#include "src/core/lib/transport/http_connect_handshaker.h"
|
||||
#include "src/core/lib/transport/tcp_connect_handshaker.h"
|
||||
|
||||
|
||||
namespace grpc_event_engine {
|
||||
namespace experimental {
|
||||
extern void RegisterEventEngineChannelArgPreconditioning(
|
||||
|
|
|
|||
|
|
@ -31,14 +31,13 @@ package(
|
|||
grpc_cc_library(
|
||||
name = "otel_plugin",
|
||||
srcs = [
|
||||
"otel_client_filter.cc",
|
||||
"otel_client_call_tracer.cc",
|
||||
"otel_plugin.cc",
|
||||
"otel_server_call_tracer.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"key_value_iterable.h",
|
||||
"otel_call_tracer.h",
|
||||
"otel_client_filter.h",
|
||||
"otel_client_call_tracer.h",
|
||||
"otel_plugin.h",
|
||||
"otel_server_call_tracer.h",
|
||||
"//:include/grpcpp/ext/otel_plugin.h",
|
||||
|
|
@ -77,6 +76,7 @@ grpc_cc_library(
|
|||
"//src/core:context",
|
||||
"//src/core:error",
|
||||
"//src/core:metadata_batch",
|
||||
"//src/core:metrics",
|
||||
"//src/core:slice",
|
||||
"//src/core:slice_buffer",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -46,23 +46,26 @@ inline opentelemetry::nostd::string_view AbslStrViewToOpenTelemetryStrView(
|
|||
// An iterable class based on opentelemetry::common::KeyValueIterable that
|
||||
// allows gRPC to iterate on its various sources of attributes and avoid an
|
||||
// allocation in cases wherever possible.
|
||||
class KeyValueIterable : public opentelemetry::common::KeyValueIterable {
|
||||
class OpenTelemetryPlugin::KeyValueIterable
|
||||
: public opentelemetry::common::KeyValueIterable {
|
||||
public:
|
||||
explicit KeyValueIterable(
|
||||
KeyValueIterable(
|
||||
const std::vector<std::unique_ptr<LabelsIterable>>&
|
||||
injected_labels_from_plugin_options,
|
||||
absl::Span<const std::pair<absl::string_view, absl::string_view>>
|
||||
additional_labels,
|
||||
const ActivePluginOptionsView* active_plugin_options_view,
|
||||
const OpenTelemetryPlugin::ActivePluginOptionsView*
|
||||
active_plugin_options_view,
|
||||
absl::Span<const std::shared_ptr<std::map<std::string, std::string>>>
|
||||
optional_labels_span,
|
||||
bool is_client)
|
||||
bool is_client, const OpenTelemetryPlugin* otel_plugin)
|
||||
: injected_labels_from_plugin_options_(
|
||||
injected_labels_from_plugin_options),
|
||||
additional_labels_(additional_labels),
|
||||
active_plugin_options_view_(active_plugin_options_view),
|
||||
optional_labels_(optional_labels_span),
|
||||
is_client_(is_client) {}
|
||||
is_client_(is_client),
|
||||
otel_plugin_(otel_plugin) {}
|
||||
|
||||
bool ForEachKeyValue(opentelemetry::nostd::function_ref<
|
||||
bool(opentelemetry::nostd::string_view,
|
||||
|
|
@ -75,7 +78,8 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable {
|
|||
size_t /*index*/) {
|
||||
return plugin_option.labels_injector()->AddOptionalLabels(
|
||||
is_client_, optional_labels_, callback);
|
||||
})) {
|
||||
},
|
||||
otel_plugin_)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& plugin_option_injected_iterable :
|
||||
|
|
@ -115,7 +119,8 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable {
|
|||
size += plugin_option.labels_injector()->GetOptionalLabelsSize(
|
||||
is_client_, optional_labels_);
|
||||
return true;
|
||||
});
|
||||
},
|
||||
otel_plugin_);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
|
@ -125,10 +130,12 @@ class KeyValueIterable : public opentelemetry::common::KeyValueIterable {
|
|||
injected_labels_from_plugin_options_;
|
||||
absl::Span<const std::pair<absl::string_view, absl::string_view>>
|
||||
additional_labels_;
|
||||
const ActivePluginOptionsView* active_plugin_options_view_;
|
||||
const OpenTelemetryPlugin::ActivePluginOptionsView*
|
||||
active_plugin_options_view_;
|
||||
absl::Span<const std::shared_ptr<std::map<std::string, std::string>>>
|
||||
optional_labels_;
|
||||
bool is_client_;
|
||||
const OpenTelemetryPlugin* otel_plugin_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "src/cpp/ext/otel/otel_client_call_tracer.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "opentelemetry/context/context.h"
|
||||
#include "opentelemetry/metrics/sync_instruments.h"
|
||||
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/client_channel/client_channel_filter.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/channel/status_util.h"
|
||||
#include "src/core/lib/channel/tcp_tracer.h"
|
||||
#include "src/core/lib/gprpp/sync.h"
|
||||
#include "src/core/lib/promise/context.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
#include "src/core/lib/slice/slice_buffer.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/cpp/ext/otel/key_value_iterable.h"
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
//
|
||||
// OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer
|
||||
//
|
||||
|
||||
OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::CallAttemptTracer(
|
||||
const OpenTelemetryPlugin::ClientCallTracer* parent, bool arena_allocated)
|
||||
: parent_(parent),
|
||||
arena_allocated_(arena_allocated),
|
||||
start_time_(absl::Now()) {
|
||||
if (parent_->otel_plugin_->client_.attempt.started != nullptr) {
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 2>
|
||||
additional_labels = {
|
||||
{{OpenTelemetryMethodKey(), parent_->MethodForStats()},
|
||||
{OpenTelemetryTargetKey(),
|
||||
parent_->scope_config_->filtered_target()}}};
|
||||
// We might not have all the injected labels that we want at this point, so
|
||||
// avoid recording a subset of injected labels here.
|
||||
parent_->otel_plugin_->client_.attempt.started->Add(
|
||||
1, KeyValueIterable(
|
||||
/*injected_labels_from_plugin_options=*/{}, additional_labels,
|
||||
/*active_plugin_options_view=*/nullptr,
|
||||
/*optional_labels_span=*/{}, /*is_client=*/true,
|
||||
parent_->otel_plugin_));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordReceivedInitialMetadata(grpc_metadata_batch* recv_initial_metadata) {
|
||||
parent_->scope_config_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t /*index*/) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
injected_labels_from_plugin_options_.push_back(
|
||||
labels_injector->GetLabels(recv_initial_metadata));
|
||||
}
|
||||
return true;
|
||||
},
|
||||
parent_->otel_plugin_);
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordSendInitialMetadata(grpc_metadata_batch* send_initial_metadata) {
|
||||
parent_->scope_config_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t /*index*/) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
labels_injector->AddLabels(send_initial_metadata, nullptr);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
parent_->otel_plugin_);
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordSendMessage(const grpc_core::SliceBuffer& send_message) {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Send message: %ld bytes", send_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordSendCompressedMessage(
|
||||
const grpc_core::SliceBuffer& send_compressed_message) {
|
||||
RecordAnnotation(absl::StrFormat("Send compressed message: %ld bytes",
|
||||
send_compressed_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordReceivedMessage(const grpc_core::SliceBuffer& recv_message) {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Received message: %ld bytes", recv_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordReceivedDecompressedMessage(
|
||||
const grpc_core::SliceBuffer& recv_decompressed_message) {
|
||||
RecordAnnotation(absl::StrFormat("Received decompressed message: %ld bytes",
|
||||
recv_decompressed_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
RecordReceivedTrailingMetadata(
|
||||
absl::Status status, grpc_metadata_batch* /*recv_trailing_metadata*/,
|
||||
const grpc_transport_stream_stats* transport_stream_stats) {
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 3>
|
||||
additional_labels = {
|
||||
{{OpenTelemetryMethodKey(), parent_->MethodForStats()},
|
||||
{OpenTelemetryTargetKey(),
|
||||
parent_->scope_config_->filtered_target()},
|
||||
{OpenTelemetryStatusKey(),
|
||||
grpc_status_code_to_string(
|
||||
static_cast<grpc_status_code>(status.code()))}}};
|
||||
KeyValueIterable labels(
|
||||
injected_labels_from_plugin_options_, additional_labels,
|
||||
&parent_->scope_config_->active_plugin_options_view(),
|
||||
optional_labels_array_, /*is_client=*/true, parent_->otel_plugin_);
|
||||
if (parent_->otel_plugin_->client_.attempt.duration != nullptr) {
|
||||
parent_->otel_plugin_->client_.attempt.duration->Record(
|
||||
absl::ToDoubleSeconds(absl::Now() - start_time_), labels,
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
if (parent_->otel_plugin_->client_.attempt
|
||||
.sent_total_compressed_message_size != nullptr) {
|
||||
parent_->otel_plugin_->client_.attempt.sent_total_compressed_message_size
|
||||
->Record(transport_stream_stats != nullptr
|
||||
? transport_stream_stats->outgoing.data_bytes
|
||||
: 0,
|
||||
labels, opentelemetry::context::Context{});
|
||||
}
|
||||
if (parent_->otel_plugin_->client_.attempt
|
||||
.rcvd_total_compressed_message_size != nullptr) {
|
||||
parent_->otel_plugin_->client_.attempt.rcvd_total_compressed_message_size
|
||||
->Record(transport_stream_stats != nullptr
|
||||
? transport_stream_stats->incoming.data_bytes
|
||||
: 0,
|
||||
labels, opentelemetry::context::Context{});
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::RecordCancel(
|
||||
absl::Status /*cancel_error*/) {}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::RecordEnd(
|
||||
const gpr_timespec& /*latency*/) {
|
||||
if (arena_allocated_) {
|
||||
this->~CallAttemptTracer();
|
||||
} else {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::RecordAnnotation(
|
||||
absl::string_view /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::RecordAnnotation(
|
||||
const Annotation& /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
std::shared_ptr<grpc_core::TcpTracerInterface>
|
||||
OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::StartNewTcpTrace() {
|
||||
// No TCP trace.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer::
|
||||
AddOptionalLabels(
|
||||
OptionalLabelComponent component,
|
||||
std::shared_ptr<std::map<std::string, std::string>> optional_labels) {
|
||||
optional_labels_array_[static_cast<std::size_t>(component)] =
|
||||
std::move(optional_labels);
|
||||
}
|
||||
|
||||
//
|
||||
// OpenTelemetryPlugin::ClientCallTracer
|
||||
//
|
||||
|
||||
OpenTelemetryPlugin::ClientCallTracer::ClientCallTracer(
|
||||
const grpc_core::Slice& path, grpc_core::Arena* arena,
|
||||
bool registered_method, OpenTelemetryPlugin* otel_plugin,
|
||||
std::shared_ptr<OpenTelemetryPlugin::ClientScopeConfig> scope_config)
|
||||
: path_(path.Ref()),
|
||||
arena_(arena),
|
||||
registered_method_(registered_method),
|
||||
otel_plugin_(otel_plugin),
|
||||
scope_config_(std::move(scope_config)) {}
|
||||
|
||||
OpenTelemetryPlugin::ClientCallTracer::~ClientCallTracer() {}
|
||||
|
||||
OpenTelemetryPlugin::ClientCallTracer::CallAttemptTracer*
|
||||
OpenTelemetryPlugin::ClientCallTracer::StartNewAttempt(
|
||||
bool is_transparent_retry) {
|
||||
// We allocate the first attempt on the arena and all subsequent attempts
|
||||
// on the heap, so that in the common case we don't require a heap
|
||||
// allocation, nor do we unnecessarily grow the arena.
|
||||
bool is_first_attempt = true;
|
||||
{
|
||||
grpc_core::MutexLock lock(&mu_);
|
||||
if (transparent_retries_ != 0 || retries_ != 0) {
|
||||
is_first_attempt = false;
|
||||
}
|
||||
if (is_transparent_retry) {
|
||||
++transparent_retries_;
|
||||
} else {
|
||||
++retries_;
|
||||
}
|
||||
}
|
||||
if (is_first_attempt) {
|
||||
return arena_->New<CallAttemptTracer>(this, /*arena_allocated=*/true);
|
||||
}
|
||||
return new CallAttemptTracer(this, /*arena_allocated=*/false);
|
||||
}
|
||||
|
||||
absl::string_view OpenTelemetryPlugin::ClientCallTracer::MethodForStats()
|
||||
const {
|
||||
absl::string_view method = absl::StripPrefix(path_.as_string_view(), "/");
|
||||
if (registered_method_ ||
|
||||
(otel_plugin_->generic_method_attribute_filter() != nullptr &&
|
||||
otel_plugin_->generic_method_attribute_filter()(method))) {
|
||||
return method;
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::RecordAnnotation(
|
||||
absl::string_view /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ClientCallTracer::RecordAnnotation(
|
||||
const Annotation& /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
//
|
||||
//
|
||||
|
||||
#ifndef GRPC_SRC_CPP_EXT_OTEL_OTEL_CALL_TRACER_H
|
||||
#define GRPC_SRC_CPP_EXT_OTEL_OTEL_CALL_TRACER_H
|
||||
#ifndef GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
|
||||
#define GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
|
|
@ -42,18 +42,19 @@
|
|||
#include "src/core/lib/slice/slice_buffer.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "src/cpp/ext/otel/otel_client_filter.h"
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer {
|
||||
class OpenTelemetryPlugin::ClientCallTracer
|
||||
: public grpc_core::ClientCallTracer {
|
||||
public:
|
||||
class OpenTelemetryCallAttemptTracer : public CallAttemptTracer {
|
||||
class CallAttemptTracer
|
||||
: public grpc_core::ClientCallTracer::CallAttemptTracer {
|
||||
public:
|
||||
OpenTelemetryCallAttemptTracer(const OpenTelemetryCallTracer* parent,
|
||||
bool arena_allocated);
|
||||
CallAttemptTracer(const OpenTelemetryPlugin::ClientCallTracer* parent,
|
||||
bool arena_allocated);
|
||||
|
||||
std::string TraceId() override {
|
||||
// Not implemented
|
||||
|
|
@ -96,7 +97,7 @@ class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer {
|
|||
optional_labels) override;
|
||||
|
||||
private:
|
||||
const OpenTelemetryCallTracer* parent_;
|
||||
const ClientCallTracer* parent_;
|
||||
const bool arena_allocated_;
|
||||
// Start time (for measuring latency).
|
||||
absl::Time start_time_;
|
||||
|
|
@ -109,11 +110,11 @@ class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer {
|
|||
injected_labels_from_plugin_options_;
|
||||
};
|
||||
|
||||
explicit OpenTelemetryCallTracer(OpenTelemetryClientFilter* parent,
|
||||
grpc_core::Slice path,
|
||||
grpc_core::Arena* arena,
|
||||
bool registered_method);
|
||||
~OpenTelemetryCallTracer() override;
|
||||
ClientCallTracer(
|
||||
const grpc_core::Slice& path, grpc_core::Arena* arena,
|
||||
bool registered_method, OpenTelemetryPlugin* otel_plugin,
|
||||
std::shared_ptr<OpenTelemetryPlugin::ClientScopeConfig> scope_config);
|
||||
~ClientCallTracer() override;
|
||||
|
||||
std::string TraceId() override {
|
||||
// Not implemented
|
||||
|
|
@ -130,19 +131,19 @@ class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer {
|
|||
return false;
|
||||
}
|
||||
|
||||
OpenTelemetryCallAttemptTracer* StartNewAttempt(
|
||||
bool is_transparent_retry) override;
|
||||
CallAttemptTracer* StartNewAttempt(bool is_transparent_retry) override;
|
||||
void RecordAnnotation(absl::string_view /*annotation*/) override;
|
||||
void RecordAnnotation(const Annotation& /*annotation*/) override;
|
||||
|
||||
private:
|
||||
absl::string_view MethodForStats() const;
|
||||
|
||||
const OpenTelemetryClientFilter* parent_;
|
||||
// Client method.
|
||||
grpc_core::Slice path_;
|
||||
grpc_core::Arena* arena_;
|
||||
const bool registered_method_;
|
||||
OpenTelemetryPlugin* otel_plugin_;
|
||||
std::shared_ptr<OpenTelemetryPlugin::ClientScopeConfig> scope_config_;
|
||||
grpc_core::Mutex mu_;
|
||||
// Non-transparent attempts per call
|
||||
uint64_t retries_ ABSL_GUARDED_BY(&mu_) = 0;
|
||||
|
|
@ -153,4 +154,4 @@ class OpenTelemetryCallTracer : public grpc_core::ClientCallTracer {
|
|||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CPP_EXT_OTEL_OTEL_CALL_TRACER_H
|
||||
#endif // GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2023 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "src/cpp/ext/otel/otel_client_filter.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "opentelemetry/context/context.h"
|
||||
#include "opentelemetry/metrics/sync_instruments.h"
|
||||
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/log.h>
|
||||
#include <grpc/support/time.h>
|
||||
|
||||
#include "src/core/client_channel/client_channel_filter.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/channel/status_util.h"
|
||||
#include "src/core/lib/channel/tcp_tracer.h"
|
||||
#include "src/core/lib/gprpp/sync.h"
|
||||
#include "src/core/lib/promise/context.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
#include "src/core/lib/slice/slice_buffer.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/cpp/ext/otel/key_value_iterable.h"
|
||||
#include "src/cpp/ext/otel/otel_call_tracer.h"
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
//
|
||||
// OpenTelemetryClientFilter
|
||||
//
|
||||
|
||||
const grpc_channel_filter OpenTelemetryClientFilter::kFilter =
|
||||
grpc_core::MakePromiseBasedFilter<OpenTelemetryClientFilter,
|
||||
grpc_core::FilterEndpoint::kClient>(
|
||||
"otel_client");
|
||||
|
||||
absl::StatusOr<OpenTelemetryClientFilter> OpenTelemetryClientFilter::Create(
|
||||
const grpc_core::ChannelArgs& args, ChannelFilter::Args /*filter_args*/) {
|
||||
return OpenTelemetryClientFilter(
|
||||
args.GetOwnedString(GRPC_ARG_SERVER_URI).value_or(""));
|
||||
}
|
||||
|
||||
grpc_core::ArenaPromise<grpc_core::ServerMetadataHandle>
|
||||
OpenTelemetryClientFilter::MakeCallPromise(
|
||||
grpc_core::CallArgs call_args,
|
||||
grpc_core::NextPromiseFactory next_promise_factory) {
|
||||
auto* path = call_args.client_initial_metadata->get_pointer(
|
||||
grpc_core::HttpPathMetadata());
|
||||
bool registered_method = reinterpret_cast<uintptr_t>(
|
||||
call_args.client_initial_metadata->get(grpc_core::GrpcRegisteredMethod())
|
||||
.value_or(nullptr));
|
||||
auto* call_context = grpc_core::GetContext<grpc_call_context_element>();
|
||||
auto* tracer =
|
||||
grpc_core::GetContext<grpc_core::Arena>()
|
||||
->ManagedNew<OpenTelemetryCallTracer>(
|
||||
this, path != nullptr ? path->Ref() : grpc_core::Slice(),
|
||||
grpc_core::GetContext<grpc_core::Arena>(), registered_method);
|
||||
GPR_DEBUG_ASSERT(
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value ==
|
||||
nullptr);
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value = tracer;
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].destroy = nullptr;
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
|
||||
OpenTelemetryClientFilter::OpenTelemetryClientFilter(std::string target)
|
||||
: active_plugin_options_view_(
|
||||
ActivePluginOptionsView::MakeForClient(target)) {
|
||||
// Use the original target string only if a filter on the attribute is not
|
||||
// registered or if the filter returns true, otherwise use "other".
|
||||
if (OpenTelemetryPluginState().target_attribute_filter == nullptr ||
|
||||
OpenTelemetryPluginState().target_attribute_filter(target)) {
|
||||
filtered_target_ = std::move(target);
|
||||
} else {
|
||||
filtered_target_ = "other";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer
|
||||
//
|
||||
|
||||
OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
OpenTelemetryCallAttemptTracer(const OpenTelemetryCallTracer* parent,
|
||||
bool arena_allocated)
|
||||
: parent_(parent),
|
||||
arena_allocated_(arena_allocated),
|
||||
start_time_(absl::Now()) {
|
||||
if (OpenTelemetryPluginState().client.attempt.started != nullptr) {
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 2>
|
||||
additional_labels = {
|
||||
{{OpenTelemetryMethodKey(), parent_->MethodForStats()},
|
||||
{OpenTelemetryTargetKey(), parent_->parent_->filtered_target()}}};
|
||||
// We might not have all the injected labels that we want at this point, so
|
||||
// avoid recording a subset of injected labels here.
|
||||
OpenTelemetryPluginState().client.attempt.started->Add(
|
||||
1, KeyValueIterable(/*injected_labels_from_plugin_options=*/{},
|
||||
additional_labels,
|
||||
/*active_plugin_options_view=*/nullptr,
|
||||
/*optional_labels_span=*/{}, /*is_client=*/true));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordReceivedInitialMetadata(grpc_metadata_batch* recv_initial_metadata) {
|
||||
parent_->parent_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t /*index*/) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
injected_labels_from_plugin_options_.push_back(
|
||||
labels_injector->GetLabels(recv_initial_metadata));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordSendInitialMetadata(grpc_metadata_batch* send_initial_metadata) {
|
||||
parent_->parent_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t /*index*/) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
labels_injector->AddLabels(send_initial_metadata, nullptr);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordSendMessage(
|
||||
const grpc_core::SliceBuffer& send_message) {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Send message: %ld bytes", send_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordSendCompressedMessage(
|
||||
const grpc_core::SliceBuffer& send_compressed_message) {
|
||||
RecordAnnotation(absl::StrFormat("Send compressed message: %ld bytes",
|
||||
send_compressed_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordReceivedMessage(const grpc_core::SliceBuffer& recv_message) {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Received message: %ld bytes", recv_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordReceivedDecompressedMessage(
|
||||
const grpc_core::SliceBuffer& recv_decompressed_message) {
|
||||
RecordAnnotation(absl::StrFormat("Received decompressed message: %ld bytes",
|
||||
recv_decompressed_message.Length()));
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::
|
||||
RecordReceivedTrailingMetadata(
|
||||
absl::Status status, grpc_metadata_batch* /*recv_trailing_metadata*/,
|
||||
const grpc_transport_stream_stats* transport_stream_stats) {
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 3>
|
||||
additional_labels = {
|
||||
{{OpenTelemetryMethodKey(), parent_->MethodForStats()},
|
||||
{OpenTelemetryTargetKey(), parent_->parent_->filtered_target()},
|
||||
{OpenTelemetryStatusKey(),
|
||||
grpc_status_code_to_string(
|
||||
static_cast<grpc_status_code>(status.code()))}}};
|
||||
KeyValueIterable labels(injected_labels_from_plugin_options_,
|
||||
additional_labels,
|
||||
&parent_->parent_->active_plugin_options_view(),
|
||||
optional_labels_array_, /*is_client=*/true);
|
||||
if (OpenTelemetryPluginState().client.attempt.duration != nullptr) {
|
||||
OpenTelemetryPluginState().client.attempt.duration->Record(
|
||||
absl::ToDoubleSeconds(absl::Now() - start_time_), labels,
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
if (OpenTelemetryPluginState()
|
||||
.client.attempt.sent_total_compressed_message_size != nullptr) {
|
||||
OpenTelemetryPluginState()
|
||||
.client.attempt.sent_total_compressed_message_size->Record(
|
||||
transport_stream_stats != nullptr
|
||||
? transport_stream_stats->outgoing.data_bytes
|
||||
: 0,
|
||||
labels, opentelemetry::context::Context{});
|
||||
}
|
||||
if (OpenTelemetryPluginState()
|
||||
.client.attempt.rcvd_total_compressed_message_size != nullptr) {
|
||||
OpenTelemetryPluginState()
|
||||
.client.attempt.rcvd_total_compressed_message_size->Record(
|
||||
transport_stream_stats != nullptr
|
||||
? transport_stream_stats->incoming.data_bytes
|
||||
: 0,
|
||||
labels, opentelemetry::context::Context{});
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordCancel(
|
||||
absl::Status /*cancel_error*/) {}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordEnd(
|
||||
const gpr_timespec& /*latency*/) {
|
||||
if (arena_allocated_) {
|
||||
this->~OpenTelemetryCallAttemptTracer();
|
||||
} else {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordAnnotation(
|
||||
absl::string_view /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::RecordAnnotation(
|
||||
const Annotation& /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
std::shared_ptr<grpc_core::TcpTracerInterface>
|
||||
OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::StartNewTcpTrace() {
|
||||
// No TCP trace.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer::AddOptionalLabels(
|
||||
OptionalLabelComponent component,
|
||||
std::shared_ptr<std::map<std::string, std::string>> optional_labels) {
|
||||
optional_labels_array_[static_cast<std::size_t>(component)] =
|
||||
std::move(optional_labels);
|
||||
}
|
||||
|
||||
//
|
||||
// OpenTelemetryCallTracer
|
||||
//
|
||||
|
||||
OpenTelemetryCallTracer::OpenTelemetryCallTracer(
|
||||
OpenTelemetryClientFilter* parent, grpc_core::Slice path,
|
||||
grpc_core::Arena* arena, bool registered_method)
|
||||
: parent_(parent),
|
||||
path_(std::move(path)),
|
||||
arena_(arena),
|
||||
registered_method_(registered_method) {}
|
||||
|
||||
OpenTelemetryCallTracer::~OpenTelemetryCallTracer() {}
|
||||
|
||||
OpenTelemetryCallTracer::OpenTelemetryCallAttemptTracer*
|
||||
OpenTelemetryCallTracer::StartNewAttempt(bool is_transparent_retry) {
|
||||
// We allocate the first attempt on the arena and all subsequent attempts
|
||||
// on the heap, so that in the common case we don't require a heap
|
||||
// allocation, nor do we unnecessarily grow the arena.
|
||||
bool is_first_attempt = true;
|
||||
{
|
||||
grpc_core::MutexLock lock(&mu_);
|
||||
if (transparent_retries_ != 0 || retries_ != 0) {
|
||||
is_first_attempt = false;
|
||||
}
|
||||
if (is_transparent_retry) {
|
||||
++transparent_retries_;
|
||||
} else {
|
||||
++retries_;
|
||||
}
|
||||
}
|
||||
if (is_first_attempt) {
|
||||
return arena_->New<OpenTelemetryCallAttemptTracer>(
|
||||
this, /*arena_allocated=*/true);
|
||||
}
|
||||
return new OpenTelemetryCallAttemptTracer(this, /*arena_allocated=*/false);
|
||||
}
|
||||
|
||||
absl::string_view OpenTelemetryCallTracer::MethodForStats() const {
|
||||
absl::string_view method = absl::StripPrefix(path_.as_string_view(), "/");
|
||||
if (registered_method_ ||
|
||||
(OpenTelemetryPluginState().generic_method_attribute_filter != nullptr &&
|
||||
OpenTelemetryPluginState().generic_method_attribute_filter(method))) {
|
||||
return method;
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::RecordAnnotation(
|
||||
absl::string_view /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void OpenTelemetryCallTracer::RecordAnnotation(
|
||||
const Annotation& /*annotation*/) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2023 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_SRC_CPP_EXT_OTEL_OTEL_CLIENT_FILTER_H
|
||||
#define GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_FILTER_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/promise_based_filter.h"
|
||||
#include "src/core/lib/promise/arena_promise.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
class OpenTelemetryClientFilter : public grpc_core::ChannelFilter {
|
||||
public:
|
||||
static const grpc_channel_filter kFilter;
|
||||
|
||||
static absl::StatusOr<OpenTelemetryClientFilter> Create(
|
||||
const grpc_core::ChannelArgs& /*args*/,
|
||||
ChannelFilter::Args /*filter_args*/);
|
||||
|
||||
grpc_core::ArenaPromise<grpc_core::ServerMetadataHandle> MakeCallPromise(
|
||||
grpc_core::CallArgs call_args,
|
||||
grpc_core::NextPromiseFactory next_promise_factory) override;
|
||||
|
||||
absl::string_view filtered_target() const { return filtered_target_; }
|
||||
|
||||
const ActivePluginOptionsView& active_plugin_options_view() const {
|
||||
return active_plugin_options_view_;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit OpenTelemetryClientFilter(std::string target);
|
||||
|
||||
std::string filtered_target_;
|
||||
ActivePluginOptionsView active_plugin_options_view_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_FILTER_H
|
||||
|
|
@ -20,11 +20,13 @@
|
|||
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "opentelemetry/metrics/meter.h"
|
||||
#include "opentelemetry/metrics/meter_provider.h"
|
||||
#include "opentelemetry/metrics/sync_instruments.h"
|
||||
#include "opentelemetry/nostd/shared_ptr.h"
|
||||
#include "opentelemetry/nostd/unique_ptr.h"
|
||||
|
||||
|
|
@ -37,21 +39,13 @@
|
|||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/surface/channel_stack_type.h"
|
||||
#include "src/cpp/ext/otel/otel_client_filter.h"
|
||||
#include "src/cpp/ext/otel/key_value_iterable.h"
|
||||
#include "src/cpp/ext/otel/otel_client_call_tracer.h"
|
||||
#include "src/cpp/ext/otel/otel_server_call_tracer.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
// TODO(yashykt): Extend this to allow multiple OpenTelemetry plugins to be
|
||||
// registered in the same binary.
|
||||
struct OpenTelemetryPluginState* g_otel_plugin_state_;
|
||||
|
||||
const struct OpenTelemetryPluginState& OpenTelemetryPluginState() {
|
||||
GPR_DEBUG_ASSERT(g_otel_plugin_state_ != nullptr);
|
||||
return *g_otel_plugin_state_;
|
||||
}
|
||||
|
||||
absl::string_view OpenTelemetryMethodKey() { return "grpc.method"; }
|
||||
|
||||
absl::string_view OpenTelemetryStatusKey() { return "grpc.status"; }
|
||||
|
|
@ -60,7 +54,7 @@ absl::string_view OpenTelemetryTargetKey() { return "grpc.target"; }
|
|||
|
||||
namespace {
|
||||
absl::flat_hash_set<std::string> BaseMetrics() {
|
||||
return absl::flat_hash_set<std::string>{
|
||||
absl::flat_hash_set<std::string> base_metrics{
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptStartedInstrumentName),
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
|
|
@ -79,9 +73,67 @@ absl::flat_hash_set<std::string> BaseMetrics() {
|
|||
kServerCallSentTotalCompressedMessageSizeInstrumentName),
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallRcvdTotalCompressedMessageSizeInstrumentName)};
|
||||
grpc_core::GlobalInstrumentsRegistry::ForEach(
|
||||
[&](const grpc_core::GlobalInstrumentsRegistry::
|
||||
GlobalInstrumentDescriptor& descriptor) {
|
||||
if (descriptor.enable_by_default) {
|
||||
base_metrics.emplace(descriptor.name);
|
||||
}
|
||||
});
|
||||
return base_metrics;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class OpenTelemetryPlugin::NPCMetricsKeyValueIterable
|
||||
: public opentelemetry::common::KeyValueIterable {
|
||||
public:
|
||||
NPCMetricsKeyValueIterable(
|
||||
absl::Span<const absl::string_view> label_keys,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_label_keys,
|
||||
absl::Span<const absl::string_view> optional_label_values,
|
||||
const OptionalLabelsBitSet& optional_labels_bits)
|
||||
: label_keys_(label_keys),
|
||||
label_values_(label_values),
|
||||
optional_label_keys_(optional_label_keys),
|
||||
optional_label_values_(optional_label_values),
|
||||
optional_labels_bits_(optional_labels_bits) {}
|
||||
|
||||
bool ForEachKeyValue(opentelemetry::nostd::function_ref<
|
||||
bool(opentelemetry::nostd::string_view,
|
||||
opentelemetry::common::AttributeValue)>
|
||||
callback) const noexcept override {
|
||||
for (size_t i = 0; i < label_keys_.size(); i++) {
|
||||
if (!callback(AbslStrViewToOpenTelemetryStrView(label_keys_[i]),
|
||||
AbslStrViewToOpenTelemetryStrView(label_values_[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < optional_label_keys_.size(); ++i) {
|
||||
if (!optional_labels_bits_.test(i)) {
|
||||
continue;
|
||||
}
|
||||
if (!callback(
|
||||
AbslStrViewToOpenTelemetryStrView(optional_label_keys_[i]),
|
||||
AbslStrViewToOpenTelemetryStrView(optional_label_values_[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t size() const noexcept override {
|
||||
return label_keys_.size() + optional_labels_bits_.count();
|
||||
}
|
||||
|
||||
private:
|
||||
absl::Span<const absl::string_view> label_keys_;
|
||||
absl::Span<const absl::string_view> label_values_;
|
||||
absl::Span<const absl::string_view> optional_label_keys_;
|
||||
absl::Span<const absl::string_view> optional_label_values_;
|
||||
const OptionalLabelsBitSet& optional_labels_bits_;
|
||||
};
|
||||
|
||||
//
|
||||
// OpenTelemetryPluginBuilderImpl
|
||||
//
|
||||
|
|
@ -156,112 +208,352 @@ OpenTelemetryPluginBuilderImpl& OpenTelemetryPluginBuilderImpl::AddPluginOption(
|
|||
return *this;
|
||||
}
|
||||
|
||||
OpenTelemetryPluginBuilderImpl&
|
||||
OpenTelemetryPluginBuilderImpl::AddOptionalLabel(
|
||||
absl::string_view optional_label_key) {
|
||||
if (optional_label_keys_ == nullptr) {
|
||||
optional_label_keys_ = std::make_shared<std::set<absl::string_view>>();
|
||||
}
|
||||
optional_label_keys_->emplace(optional_label_key);
|
||||
return *this;
|
||||
}
|
||||
|
||||
absl::Status OpenTelemetryPluginBuilderImpl::BuildAndRegisterGlobal() {
|
||||
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::MeterProvider>
|
||||
meter_provider = meter_provider_;
|
||||
delete g_otel_plugin_state_;
|
||||
g_otel_plugin_state_ = new struct OpenTelemetryPluginState;
|
||||
if (meter_provider == nullptr) {
|
||||
if (meter_provider_ == nullptr) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
auto meter = meter_provider->GetMeter("grpc-c++", GRPC_CPP_VERSION_STRING);
|
||||
if (metrics_.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptStartedInstrumentName)) {
|
||||
g_otel_plugin_state_->client.attempt.started = meter->CreateUInt64Counter(
|
||||
grpc_core::GlobalStatsPluginRegistry::RegisterStatsPlugin(
|
||||
std::make_shared<OpenTelemetryPlugin>(
|
||||
metrics_, meter_provider_, std::move(target_selector_),
|
||||
std::move(target_attribute_filter_),
|
||||
std::move(generic_method_attribute_filter_),
|
||||
std::move(server_selector_), std::move(plugin_options_),
|
||||
std::move(optional_label_keys_)));
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
OpenTelemetryPlugin::OpenTelemetryPlugin(
|
||||
const absl::flat_hash_set<std::string>& metrics,
|
||||
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::MeterProvider>
|
||||
meter_provider,
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_selector,
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_attribute_filter,
|
||||
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
|
||||
generic_method_attribute_filter,
|
||||
absl::AnyInvocable<bool(const grpc_core::ChannelArgs& /*args*/) const>
|
||||
server_selector,
|
||||
std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>
|
||||
plugin_options,
|
||||
std::shared_ptr<std::set<absl::string_view>> optional_label_keys)
|
||||
: meter_provider_(std::move(meter_provider)),
|
||||
target_selector_(std::move(target_selector)),
|
||||
server_selector_(std::move(server_selector)),
|
||||
target_attribute_filter_(std::move(target_attribute_filter)),
|
||||
generic_method_attribute_filter_(
|
||||
std::move(generic_method_attribute_filter)),
|
||||
plugin_options_(std::move(plugin_options)) {
|
||||
auto meter = meter_provider_->GetMeter("grpc-c++", GRPC_CPP_VERSION_STRING);
|
||||
// Per-call metrics.
|
||||
if (metrics.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptStartedInstrumentName)) {
|
||||
client_.attempt.started = meter->CreateUInt64Counter(
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptStartedInstrumentName),
|
||||
"Number of client call attempts started", "{attempt}");
|
||||
}
|
||||
if (metrics_.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptDurationInstrumentName)) {
|
||||
g_otel_plugin_state_->client.attempt.duration =
|
||||
meter->CreateDoubleHistogram(
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptDurationInstrumentName),
|
||||
"End-to-end time taken to complete a client call attempt", "s");
|
||||
if (metrics.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptDurationInstrumentName)) {
|
||||
client_.attempt.duration = meter->CreateDoubleHistogram(
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptDurationInstrumentName),
|
||||
"End-to-end time taken to complete a client call attempt", "s");
|
||||
}
|
||||
if (metrics_.contains(
|
||||
if (metrics.contains(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptSentTotalCompressedMessageSizeInstrumentName)) {
|
||||
g_otel_plugin_state_->client.attempt.sent_total_compressed_message_size =
|
||||
client_.attempt.sent_total_compressed_message_size =
|
||||
meter->CreateUInt64Histogram(
|
||||
std::string(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptSentTotalCompressedMessageSizeInstrumentName),
|
||||
"Compressed message bytes sent per client call attempt", "By");
|
||||
}
|
||||
if (metrics_.contains(
|
||||
if (metrics.contains(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptRcvdTotalCompressedMessageSizeInstrumentName)) {
|
||||
g_otel_plugin_state_->client.attempt.rcvd_total_compressed_message_size =
|
||||
client_.attempt.rcvd_total_compressed_message_size =
|
||||
meter->CreateUInt64Histogram(
|
||||
std::string(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kClientAttemptRcvdTotalCompressedMessageSizeInstrumentName),
|
||||
"Compressed message bytes received per call attempt", "By");
|
||||
}
|
||||
if (metrics_.contains(
|
||||
if (metrics.contains(
|
||||
grpc::OpenTelemetryPluginBuilder::kServerCallStartedInstrumentName)) {
|
||||
g_otel_plugin_state_->server.call.started = meter->CreateUInt64Counter(
|
||||
server_.call.started = meter->CreateUInt64Counter(
|
||||
std::string(
|
||||
grpc::OpenTelemetryPluginBuilder::kServerCallStartedInstrumentName),
|
||||
"Number of server calls started", "{call}");
|
||||
}
|
||||
if (metrics_.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallDurationInstrumentName)) {
|
||||
g_otel_plugin_state_->server.call.duration = meter->CreateDoubleHistogram(
|
||||
if (metrics.contains(grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallDurationInstrumentName)) {
|
||||
server_.call.duration = meter->CreateDoubleHistogram(
|
||||
std::string(grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallDurationInstrumentName),
|
||||
"End-to-end time taken to complete a call from server transport's "
|
||||
"perspective",
|
||||
"s");
|
||||
}
|
||||
if (metrics_.contains(
|
||||
if (metrics.contains(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallSentTotalCompressedMessageSizeInstrumentName)) {
|
||||
g_otel_plugin_state_->server.call.sent_total_compressed_message_size =
|
||||
server_.call.sent_total_compressed_message_size =
|
||||
meter->CreateUInt64Histogram(
|
||||
std::string(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallSentTotalCompressedMessageSizeInstrumentName),
|
||||
"Compressed message bytes sent per server call", "By");
|
||||
}
|
||||
if (metrics_.contains(
|
||||
if (metrics.contains(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallRcvdTotalCompressedMessageSizeInstrumentName)) {
|
||||
g_otel_plugin_state_->server.call.rcvd_total_compressed_message_size =
|
||||
server_.call.rcvd_total_compressed_message_size =
|
||||
meter->CreateUInt64Histogram(
|
||||
std::string(
|
||||
grpc::OpenTelemetryPluginBuilder::
|
||||
kServerCallRcvdTotalCompressedMessageSizeInstrumentName),
|
||||
"Compressed message bytes received per server call", "By");
|
||||
}
|
||||
g_otel_plugin_state_->target_attribute_filter =
|
||||
std::move(target_attribute_filter_);
|
||||
g_otel_plugin_state_->server_selector = std::move(server_selector_);
|
||||
g_otel_plugin_state_->generic_method_attribute_filter =
|
||||
std::move(generic_method_attribute_filter_);
|
||||
g_otel_plugin_state_->meter_provider = std::move(meter_provider);
|
||||
g_otel_plugin_state_->plugin_options = std::move(plugin_options_);
|
||||
grpc_core::ServerCallTracerFactory::RegisterGlobal(
|
||||
new grpc::internal::OpenTelemetryServerCallTracerFactory());
|
||||
grpc_core::CoreConfiguration::RegisterBuilder(
|
||||
[target_selector = std::move(target_selector_)](
|
||||
grpc_core::CoreConfiguration::Builder* builder) mutable {
|
||||
builder->channel_init()
|
||||
->RegisterFilter(
|
||||
GRPC_CLIENT_CHANNEL,
|
||||
&grpc::internal::OpenTelemetryClientFilter::kFilter)
|
||||
.If([target_selector = std::move(target_selector)](
|
||||
const grpc_core::ChannelArgs& args) {
|
||||
// Only register the filter if no channel selector has been set or
|
||||
// the target selector returns true for the target.
|
||||
return target_selector == nullptr ||
|
||||
target_selector(
|
||||
args.GetString(GRPC_ARG_SERVER_URI).value_or(""));
|
||||
});
|
||||
// Non-per-call metrics.
|
||||
grpc_core::GlobalInstrumentsRegistry::ForEach(
|
||||
[&, this](const grpc_core::GlobalInstrumentsRegistry::
|
||||
GlobalInstrumentDescriptor& descriptor) {
|
||||
GPR_ASSERT(descriptor.optional_label_keys.size() <=
|
||||
kOptionalLabelsSizeLimit);
|
||||
if (instruments_data_.size() < descriptor.index + 1) {
|
||||
instruments_data_.resize(descriptor.index + 1);
|
||||
}
|
||||
if (!metrics.contains(descriptor.name)) {
|
||||
return;
|
||||
}
|
||||
switch (descriptor.instrument_type) {
|
||||
case grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCounter:
|
||||
switch (descriptor.value_type) {
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kUInt64:
|
||||
instruments_data_[descriptor.index].instrument =
|
||||
meter->CreateUInt64Counter(
|
||||
std::string(descriptor.name),
|
||||
std::string(descriptor.description),
|
||||
std::string(descriptor.unit));
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble:
|
||||
instruments_data_[descriptor.index].instrument =
|
||||
meter->CreateDoubleCounter(
|
||||
std::string(descriptor.name),
|
||||
std::string(descriptor.description),
|
||||
std::string(descriptor.unit));
|
||||
break;
|
||||
default:
|
||||
grpc_core::Crash(
|
||||
absl::StrFormat("Unknown or unsupported value type: %d",
|
||||
descriptor.value_type));
|
||||
}
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::InstrumentType::kHistogram:
|
||||
switch (descriptor.value_type) {
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kUInt64:
|
||||
instruments_data_[descriptor.index].instrument =
|
||||
meter->CreateUInt64Histogram(
|
||||
std::string(descriptor.name),
|
||||
std::string(descriptor.description),
|
||||
std::string(descriptor.unit));
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble:
|
||||
instruments_data_[descriptor.index].instrument =
|
||||
meter->CreateDoubleHistogram(
|
||||
std::string(descriptor.name),
|
||||
std::string(descriptor.description),
|
||||
std::string(descriptor.unit));
|
||||
break;
|
||||
default:
|
||||
grpc_core::Crash(
|
||||
absl::StrFormat("Unknown or unsupported value type: %d",
|
||||
descriptor.value_type));
|
||||
}
|
||||
break;
|
||||
// TODO(yashkt, yijiem): implement gauges.
|
||||
case grpc_core::GlobalInstrumentsRegistry::InstrumentType::kGauge:
|
||||
switch (descriptor.value_type) {
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64:
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble:
|
||||
break;
|
||||
default:
|
||||
grpc_core::Crash(
|
||||
absl::StrFormat("Unknown or unsupported value type: %d",
|
||||
descriptor.value_type));
|
||||
}
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::InstrumentType::
|
||||
kCallbackGauge:
|
||||
switch (descriptor.value_type) {
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64:
|
||||
break;
|
||||
case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble:
|
||||
break;
|
||||
default:
|
||||
grpc_core::Crash(
|
||||
absl::StrFormat("Unknown or unsupported value type: %d",
|
||||
descriptor.value_type));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
grpc_core::Crash(absl::StrFormat("Unknown instrument_type: %d",
|
||||
descriptor.instrument_type));
|
||||
}
|
||||
for (size_t i = 0; i < descriptor.optional_label_keys.size(); ++i) {
|
||||
if (optional_label_keys->find(descriptor.optional_label_keys[i]) !=
|
||||
optional_label_keys->end()) {
|
||||
instruments_data_[descriptor.index].optional_labels_bits.set(i);
|
||||
}
|
||||
}
|
||||
});
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
|
||||
OpenTelemetryPlugin::IsEnabledForChannel(const ChannelScope& scope) const {
|
||||
if (target_selector_ == nullptr || target_selector_(scope.target())) {
|
||||
return {true, std::make_shared<ClientScopeConfig>(this, scope)};
|
||||
}
|
||||
return {false, nullptr};
|
||||
}
|
||||
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.
|
||||
if (server_selector_ == nullptr || server_selector_(args)) {
|
||||
return {true, std::make_shared<ServerScopeConfig>(this, args)};
|
||||
}
|
||||
return {false, nullptr};
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::AddCounter(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle 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);
|
||||
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
|
||||
// This instrument is disabled.
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(absl::holds_alternative<
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>>>(
|
||||
instrument_data.instrument));
|
||||
const auto& descriptor =
|
||||
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
|
||||
GPR_ASSERT(descriptor.label_keys.size() == label_values.size());
|
||||
GPR_ASSERT(descriptor.optional_label_keys.size() == optional_values.size());
|
||||
absl::get<std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>>>(
|
||||
instrument_data.instrument)
|
||||
->Add(value, NPCMetricsKeyValueIterable(
|
||||
descriptor.label_keys, label_values,
|
||||
descriptor.optional_label_keys, optional_values,
|
||||
instrument_data.optional_labels_bits));
|
||||
}
|
||||
void OpenTelemetryPlugin::AddCounter(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle 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);
|
||||
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
|
||||
// This instrument is disabled.
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(absl::holds_alternative<
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<double>>>(
|
||||
instrument_data.instrument));
|
||||
const auto& descriptor =
|
||||
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
|
||||
GPR_ASSERT(descriptor.label_keys.size() == label_values.size());
|
||||
GPR_ASSERT(descriptor.optional_label_keys.size() == optional_values.size());
|
||||
absl::get<std::unique_ptr<opentelemetry::metrics::Counter<double>>>(
|
||||
instrument_data.instrument)
|
||||
->Add(value, NPCMetricsKeyValueIterable(
|
||||
descriptor.label_keys, label_values,
|
||||
descriptor.optional_label_keys, optional_values,
|
||||
instrument_data.optional_labels_bits));
|
||||
}
|
||||
void OpenTelemetryPlugin::RecordHistogram(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle 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);
|
||||
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
|
||||
// This instrument is disabled.
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(absl::holds_alternative<
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>>(
|
||||
instrument_data.instrument));
|
||||
const auto& descriptor =
|
||||
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
|
||||
GPR_ASSERT(descriptor.label_keys.size() == label_values.size());
|
||||
GPR_ASSERT(descriptor.optional_label_keys.size() == optional_values.size());
|
||||
absl::get<std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>>(
|
||||
instrument_data.instrument)
|
||||
->Record(value,
|
||||
NPCMetricsKeyValueIterable(descriptor.label_keys, label_values,
|
||||
descriptor.optional_label_keys,
|
||||
optional_values,
|
||||
instrument_data.optional_labels_bits),
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
void OpenTelemetryPlugin::RecordHistogram(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle 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);
|
||||
if (absl::holds_alternative<Disabled>(instrument_data.instrument)) {
|
||||
// This instrument is disabled.
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(absl::holds_alternative<
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>>>(
|
||||
instrument_data.instrument));
|
||||
const auto& descriptor =
|
||||
grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle);
|
||||
GPR_ASSERT(descriptor.label_keys.size() == label_values.size());
|
||||
GPR_ASSERT(descriptor.optional_label_keys.size() == optional_values.size());
|
||||
absl::get<std::unique_ptr<opentelemetry::metrics::Histogram<double>>>(
|
||||
instrument_data.instrument)
|
||||
->Record(value,
|
||||
NPCMetricsKeyValueIterable(descriptor.label_keys, label_values,
|
||||
descriptor.optional_label_keys,
|
||||
optional_values,
|
||||
instrument_data.optional_labels_bits),
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
|
||||
grpc_core::ClientCallTracer* OpenTelemetryPlugin::GetClientCallTracer(
|
||||
const grpc_core::Slice& path, bool registered_method,
|
||||
std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig> scope_config) {
|
||||
return grpc_core::GetContext<grpc_core::Arena>()
|
||||
->ManagedNew<ClientCallTracer>(
|
||||
path, grpc_core::GetContext<grpc_core::Arena>(), registered_method,
|
||||
this,
|
||||
std::static_pointer_cast<OpenTelemetryPlugin::ClientScopeConfig>(
|
||||
scope_config));
|
||||
}
|
||||
grpc_core::ServerCallTracer* OpenTelemetryPlugin::GetServerCallTracer(
|
||||
std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig> scope_config) {
|
||||
return grpc_core::GetContext<grpc_core::Arena>()
|
||||
->ManagedNew<ServerCallTracer>(
|
||||
this,
|
||||
std::static_pointer_cast<OpenTelemetryPlugin::ServerScopeConfig>(
|
||||
scope_config));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
|
@ -324,6 +616,12 @@ OpenTelemetryPluginBuilder& OpenTelemetryPluginBuilder::AddPluginOption(
|
|||
return *this;
|
||||
}
|
||||
|
||||
OpenTelemetryPluginBuilder& OpenTelemetryPluginBuilder::AddOptionalLabel(
|
||||
absl::string_view optional_label_key) {
|
||||
impl_->AddOptionalLabel(optional_label_key);
|
||||
return *this;
|
||||
}
|
||||
|
||||
absl::Status OpenTelemetryPluginBuilder::BuildAndRegisterGlobal() {
|
||||
return impl_->BuildAndRegisterGlobal();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <grpcpp/ext/otel_plugin.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/metrics.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
|
||||
namespace grpc {
|
||||
|
|
@ -112,41 +113,6 @@ class InternalOpenTelemetryPluginOption
|
|||
virtual const grpc::internal::LabelsInjector* labels_injector() const = 0;
|
||||
};
|
||||
|
||||
struct OpenTelemetryPluginState {
|
||||
struct Client {
|
||||
struct Attempt {
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>> started;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>> duration;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
sent_total_compressed_message_size;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
rcvd_total_compressed_message_size;
|
||||
} attempt;
|
||||
} client;
|
||||
struct Server {
|
||||
struct Call {
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>> started;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>> duration;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
sent_total_compressed_message_size;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
rcvd_total_compressed_message_size;
|
||||
} call;
|
||||
} server;
|
||||
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::MeterProvider>
|
||||
meter_provider;
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_attribute_filter;
|
||||
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
|
||||
generic_method_attribute_filter;
|
||||
absl::AnyInvocable<bool(const grpc_core::ChannelArgs& /*args*/) const>
|
||||
server_selector;
|
||||
std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>
|
||||
plugin_options;
|
||||
};
|
||||
|
||||
const struct OpenTelemetryPluginState& OpenTelemetryPluginState();
|
||||
|
||||
// Tags
|
||||
absl::string_view OpenTelemetryMethodKey();
|
||||
absl::string_view OpenTelemetryStatusKey();
|
||||
|
|
@ -202,6 +168,9 @@ class OpenTelemetryPluginBuilderImpl {
|
|||
generic_method_attribute_filter);
|
||||
OpenTelemetryPluginBuilderImpl& AddPluginOption(
|
||||
std::unique_ptr<InternalOpenTelemetryPluginOption> option);
|
||||
// Records \a optional_label_key on all metrics that provide it.
|
||||
OpenTelemetryPluginBuilderImpl& AddOptionalLabel(
|
||||
absl::string_view optional_label_key);
|
||||
absl::Status BuildAndRegisterGlobal();
|
||||
|
||||
private:
|
||||
|
|
@ -217,53 +186,232 @@ class OpenTelemetryPluginBuilderImpl {
|
|||
server_selector_;
|
||||
std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>
|
||||
plugin_options_;
|
||||
std::shared_ptr<std::set<absl::string_view>> optional_label_keys_;
|
||||
};
|
||||
|
||||
// Creates a convenience wrapper to help iterate over only those plugin options
|
||||
// that are active over a given channel/server.
|
||||
class ActivePluginOptionsView {
|
||||
class OpenTelemetryPlugin : public grpc_core::StatsPlugin {
|
||||
public:
|
||||
static ActivePluginOptionsView MakeForClient(absl::string_view target) {
|
||||
return ActivePluginOptionsView(
|
||||
[target](const InternalOpenTelemetryPluginOption& plugin_option) {
|
||||
return plugin_option.IsActiveOnClientChannel(target);
|
||||
});
|
||||
}
|
||||
|
||||
static ActivePluginOptionsView MakeForServer(
|
||||
const grpc_core::ChannelArgs& args) {
|
||||
return ActivePluginOptionsView(
|
||||
[&args](const InternalOpenTelemetryPluginOption& plugin_option) {
|
||||
return plugin_option.IsActiveOnServer(args);
|
||||
});
|
||||
}
|
||||
|
||||
bool ForEach(
|
||||
absl::FunctionRef<bool(const InternalOpenTelemetryPluginOption&, size_t)>
|
||||
func) const {
|
||||
for (size_t i = 0; i < OpenTelemetryPluginState().plugin_options.size();
|
||||
++i) {
|
||||
const auto& plugin_option = OpenTelemetryPluginState().plugin_options[i];
|
||||
if (active_mask_[i] && !func(*plugin_option, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
OpenTelemetryPlugin(
|
||||
const absl::flat_hash_set<std::string>& metrics,
|
||||
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::MeterProvider>
|
||||
meter_provider,
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_selector,
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_attribute_filter,
|
||||
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
|
||||
generic_method_attribute_filter,
|
||||
absl::AnyInvocable<bool(const grpc_core::ChannelArgs& /*args*/) const>
|
||||
server_selector,
|
||||
std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>
|
||||
plugin_options,
|
||||
std::shared_ptr<std::set<absl::string_view>> optional_label_keys);
|
||||
|
||||
private:
|
||||
explicit ActivePluginOptionsView(
|
||||
absl::FunctionRef<bool(const InternalOpenTelemetryPluginOption&)> func) {
|
||||
for (size_t i = 0; i < OpenTelemetryPluginState().plugin_options.size();
|
||||
++i) {
|
||||
const auto& plugin_option = OpenTelemetryPluginState().plugin_options[i];
|
||||
if (plugin_option != nullptr && func(*plugin_option)) {
|
||||
active_mask_.set(i);
|
||||
class ClientCallTracer;
|
||||
class KeyValueIterable;
|
||||
class NPCMetricsKeyValueIterable;
|
||||
class ServerCallTracer;
|
||||
|
||||
// Creates a convenience wrapper to help iterate over only those plugin
|
||||
// options that are active over a given channel/server.
|
||||
class ActivePluginOptionsView {
|
||||
public:
|
||||
static ActivePluginOptionsView MakeForClient(
|
||||
absl::string_view target, const OpenTelemetryPlugin* otel_plugin) {
|
||||
return ActivePluginOptionsView(
|
||||
[target](const InternalOpenTelemetryPluginOption& plugin_option) {
|
||||
return plugin_option.IsActiveOnClientChannel(target);
|
||||
},
|
||||
otel_plugin);
|
||||
}
|
||||
|
||||
static ActivePluginOptionsView MakeForServer(
|
||||
const grpc_core::ChannelArgs& args,
|
||||
const OpenTelemetryPlugin* otel_plugin) {
|
||||
return ActivePluginOptionsView(
|
||||
[&args](const InternalOpenTelemetryPluginOption& plugin_option) {
|
||||
return plugin_option.IsActiveOnServer(args);
|
||||
},
|
||||
otel_plugin);
|
||||
}
|
||||
|
||||
bool ForEach(absl::FunctionRef<
|
||||
bool(const InternalOpenTelemetryPluginOption&, size_t)>
|
||||
func,
|
||||
const OpenTelemetryPlugin* otel_plugin) const {
|
||||
for (size_t i = 0; i < otel_plugin->plugin_options().size(); ++i) {
|
||||
const auto& plugin_option = otel_plugin->plugin_options()[i];
|
||||
if (active_mask_[i] && !func(*plugin_option, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit ActivePluginOptionsView(
|
||||
absl::FunctionRef<bool(const InternalOpenTelemetryPluginOption&)> func,
|
||||
const OpenTelemetryPlugin* otel_plugin) {
|
||||
for (size_t i = 0; i < otel_plugin->plugin_options().size(); ++i) {
|
||||
const auto& plugin_option = otel_plugin->plugin_options()[i];
|
||||
if (plugin_option != nullptr && func(*plugin_option)) {
|
||||
active_mask_.set(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::bitset<64> active_mask_;
|
||||
};
|
||||
|
||||
class ClientScopeConfig : public grpc_core::StatsPlugin::ScopeConfig {
|
||||
public:
|
||||
ClientScopeConfig(const OpenTelemetryPlugin* otel_plugin,
|
||||
const ChannelScope& scope)
|
||||
: active_plugin_options_view_(ActivePluginOptionsView::MakeForClient(
|
||||
scope.target(), otel_plugin)),
|
||||
filtered_target_(
|
||||
// Use the original target string only if a filter on the
|
||||
// attribute is not registered or if the filter returns true,
|
||||
// otherwise use "other".
|
||||
otel_plugin->target_attribute_filter() == nullptr ||
|
||||
otel_plugin->target_attribute_filter()(scope.target())
|
||||
? scope.target()
|
||||
: "other") {}
|
||||
|
||||
const ActivePluginOptionsView& active_plugin_options_view() const {
|
||||
return active_plugin_options_view_;
|
||||
}
|
||||
|
||||
absl::string_view filtered_target() const { return filtered_target_; }
|
||||
|
||||
private:
|
||||
ActivePluginOptionsView active_plugin_options_view_;
|
||||
std::string filtered_target_;
|
||||
};
|
||||
class ServerScopeConfig : public grpc_core::StatsPlugin::ScopeConfig {
|
||||
public:
|
||||
ServerScopeConfig(const OpenTelemetryPlugin* otel_plugin,
|
||||
const grpc_core::ChannelArgs& args)
|
||||
: active_plugin_options_view_(
|
||||
ActivePluginOptionsView::MakeForServer(args, otel_plugin)) {}
|
||||
|
||||
const ActivePluginOptionsView& active_plugin_options_view() const {
|
||||
return active_plugin_options_view_;
|
||||
}
|
||||
|
||||
private:
|
||||
ActivePluginOptionsView active_plugin_options_view_;
|
||||
};
|
||||
|
||||
struct ClientMetrics {
|
||||
struct Attempt {
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>> started;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>> duration;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
sent_total_compressed_message_size;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
rcvd_total_compressed_message_size;
|
||||
} attempt;
|
||||
};
|
||||
struct ServerMetrics {
|
||||
struct Call {
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>> started;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>> duration;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
sent_total_compressed_message_size;
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>
|
||||
rcvd_total_compressed_message_size;
|
||||
} call;
|
||||
};
|
||||
|
||||
// StatsPlugin:
|
||||
std::pair<bool, std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig>>
|
||||
IsEnabledForChannel(const ChannelScope& scope) const override;
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
double value, absl::Span<const absl::string_view> label_values,
|
||||
absl::Span<const absl::string_view> optional_values) override;
|
||||
void SetGauge(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalInt64GaugeHandle /*handle*/,
|
||||
int64_t /*value*/, absl::Span<const absl::string_view> /*label_values*/,
|
||||
absl::Span<const absl::string_view> /*optional_values*/) override {}
|
||||
void SetGauge(
|
||||
grpc_core::GlobalInstrumentsRegistry::GlobalDoubleGaugeHandle /*handle*/,
|
||||
double /*value*/, absl::Span<const absl::string_view> /*label_values*/,
|
||||
absl::Span<const absl::string_view> /*optional_values*/) override {}
|
||||
// TODO(yashkt, yijiem): implement async instrument.
|
||||
void AddCallback(grpc_core::RegisteredMetricCallback* /*callback*/) override {
|
||||
}
|
||||
void RemoveCallback(
|
||||
grpc_core::RegisteredMetricCallback* /*callback*/) override {}
|
||||
grpc_core::ClientCallTracer* GetClientCallTracer(
|
||||
const grpc_core::Slice& path, bool registered_method,
|
||||
std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig> scope_config)
|
||||
override;
|
||||
grpc_core::ServerCallTracer* GetServerCallTracer(
|
||||
std::shared_ptr<grpc_core::StatsPlugin::ScopeConfig> scope_config)
|
||||
override;
|
||||
|
||||
const absl::AnyInvocable<bool(const grpc_core::ChannelArgs& /*args*/) const>&
|
||||
server_selector() const {
|
||||
return server_selector_;
|
||||
}
|
||||
const absl::AnyInvocable<bool(absl::string_view /*target*/) const>&
|
||||
target_attribute_filter() const {
|
||||
return target_attribute_filter_;
|
||||
}
|
||||
const absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>&
|
||||
generic_method_attribute_filter() const {
|
||||
return generic_method_attribute_filter_;
|
||||
}
|
||||
const std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>&
|
||||
plugin_options() const {
|
||||
return plugin_options_;
|
||||
}
|
||||
|
||||
std::bitset<64> active_mask_;
|
||||
// Instruments for per-call metrics.
|
||||
ClientMetrics client_;
|
||||
ServerMetrics server_;
|
||||
// Instruments for non-per-call metrics.
|
||||
struct Disabled {};
|
||||
using Instrument = absl::variant<
|
||||
Disabled, std::unique_ptr<opentelemetry::metrics::Counter<uint64_t>>,
|
||||
std::unique_ptr<opentelemetry::metrics::Counter<double>>,
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<uint64_t>>,
|
||||
std::unique_ptr<opentelemetry::metrics::Histogram<double>>>;
|
||||
static constexpr int kOptionalLabelsSizeLimit = 64;
|
||||
using OptionalLabelsBitSet = std::bitset<kOptionalLabelsSizeLimit>;
|
||||
struct InstrumentData {
|
||||
Instrument instrument;
|
||||
OptionalLabelsBitSet optional_labels_bits;
|
||||
};
|
||||
std::vector<InstrumentData> instruments_data_;
|
||||
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::MeterProvider>
|
||||
meter_provider_;
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const> target_selector_;
|
||||
absl::AnyInvocable<bool(const grpc_core::ChannelArgs& /*args*/) const>
|
||||
server_selector_;
|
||||
absl::AnyInvocable<bool(absl::string_view /*target*/) const>
|
||||
target_attribute_filter_;
|
||||
absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const>
|
||||
generic_method_attribute_filter_;
|
||||
std::vector<std::unique_ptr<InternalOpenTelemetryPluginOption>>
|
||||
plugin_options_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
|
@ -50,127 +49,11 @@
|
|||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
// OpenTelemetryServerCallTracer implementation
|
||||
|
||||
class OpenTelemetryServerCallTracer : public grpc_core::ServerCallTracer {
|
||||
public:
|
||||
explicit OpenTelemetryServerCallTracer(const grpc_core::ChannelArgs& args)
|
||||
: start_time_(absl::Now()),
|
||||
active_plugin_options_view_(
|
||||
ActivePluginOptionsView::MakeForServer(args)),
|
||||
injected_labels_from_plugin_options_(
|
||||
OpenTelemetryPluginState().plugin_options.size()) {}
|
||||
|
||||
std::string TraceId() override {
|
||||
// Not implemented
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SpanId() override {
|
||||
// Not implemented
|
||||
return "";
|
||||
}
|
||||
|
||||
bool IsSampled() override {
|
||||
// Not implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
// Please refer to `grpc_transport_stream_op_batch_payload` for details on
|
||||
// arguments.
|
||||
void RecordSendInitialMetadata(
|
||||
grpc_metadata_batch* send_initial_metadata) override {
|
||||
active_plugin_options_view_.ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t index) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
labels_injector->AddLabels(
|
||||
send_initial_metadata,
|
||||
injected_labels_from_plugin_options_[index].get());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void RecordSendTrailingMetadata(
|
||||
grpc_metadata_batch* /*send_trailing_metadata*/) override;
|
||||
|
||||
void RecordSendMessage(const grpc_core::SliceBuffer& send_message) override {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Send message: %ld bytes", send_message.Length()));
|
||||
}
|
||||
void RecordSendCompressedMessage(
|
||||
const grpc_core::SliceBuffer& send_compressed_message) override {
|
||||
RecordAnnotation(absl::StrFormat("Send compressed message: %ld bytes",
|
||||
send_compressed_message.Length()));
|
||||
}
|
||||
|
||||
void RecordReceivedInitialMetadata(
|
||||
grpc_metadata_batch* recv_initial_metadata) override;
|
||||
|
||||
void RecordReceivedMessage(
|
||||
const grpc_core::SliceBuffer& recv_message) override {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Received message: %ld bytes", recv_message.Length()));
|
||||
}
|
||||
void RecordReceivedDecompressedMessage(
|
||||
const grpc_core::SliceBuffer& recv_decompressed_message) override {
|
||||
RecordAnnotation(absl::StrFormat("Received decompressed message: %ld bytes",
|
||||
recv_decompressed_message.Length()));
|
||||
}
|
||||
|
||||
void RecordReceivedTrailingMetadata(
|
||||
grpc_metadata_batch* /*recv_trailing_metadata*/) override {}
|
||||
|
||||
void RecordCancel(grpc_error_handle /*cancel_error*/) override {
|
||||
elapsed_time_ = absl::Now() - start_time_;
|
||||
}
|
||||
|
||||
void RecordEnd(const grpc_call_final_info* final_info) override;
|
||||
|
||||
void RecordAnnotation(absl::string_view /*annotation*/) override {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void RecordAnnotation(const Annotation& /*annotation*/) override {
|
||||
// Not implemented
|
||||
}
|
||||
std::shared_ptr<grpc_core::TcpTracerInterface> StartNewTcpTrace() override {
|
||||
// No TCP trace.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::string_view MethodForStats() const {
|
||||
absl::string_view method = absl::StripPrefix(path_.as_string_view(), "/");
|
||||
if (registered_method_ ||
|
||||
(OpenTelemetryPluginState().generic_method_attribute_filter !=
|
||||
nullptr &&
|
||||
OpenTelemetryPluginState().generic_method_attribute_filter(method))) {
|
||||
return method;
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
absl::Time start_time_;
|
||||
absl::Duration elapsed_time_;
|
||||
grpc_core::Slice path_;
|
||||
bool registered_method_;
|
||||
ActivePluginOptionsView active_plugin_options_view_;
|
||||
// TODO(yashykt): It's wasteful to do this per call. When we re-haul the stats
|
||||
// infrastructure, this should move to be done per server.
|
||||
std::vector<std::unique_ptr<LabelsIterable>>
|
||||
injected_labels_from_plugin_options_;
|
||||
};
|
||||
|
||||
void OpenTelemetryServerCallTracer::RecordReceivedInitialMetadata(
|
||||
void OpenTelemetryPlugin::ServerCallTracer::RecordReceivedInitialMetadata(
|
||||
grpc_metadata_batch* recv_initial_metadata) {
|
||||
path_ =
|
||||
recv_initial_metadata->get_pointer(grpc_core::HttpPathMetadata())->Ref();
|
||||
active_plugin_options_view_.ForEach(
|
||||
scope_config_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t index) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
|
|
@ -179,31 +62,48 @@ void OpenTelemetryServerCallTracer::RecordReceivedInitialMetadata(
|
|||
labels_injector->GetLabels(recv_initial_metadata);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
otel_plugin_);
|
||||
registered_method_ =
|
||||
recv_initial_metadata->get(grpc_core::GrpcRegisteredMethod())
|
||||
.value_or(nullptr) != nullptr;
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 1>
|
||||
additional_labels = {{{OpenTelemetryMethodKey(), MethodForStats()}}};
|
||||
if (OpenTelemetryPluginState().server.call.started != nullptr) {
|
||||
if (otel_plugin_->server_.call.started != nullptr) {
|
||||
// We might not have all the injected labels that we want at this point, so
|
||||
// avoid recording a subset of injected labels here.
|
||||
OpenTelemetryPluginState().server.call.started->Add(
|
||||
otel_plugin_->server_.call.started->Add(
|
||||
1, KeyValueIterable(/*injected_labels_from_plugin_options=*/{},
|
||||
additional_labels,
|
||||
/*active_plugin_options_view=*/nullptr, {},
|
||||
/*is_client=*/false));
|
||||
/*is_client=*/false, otel_plugin_));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenTelemetryServerCallTracer::RecordSendTrailingMetadata(
|
||||
void OpenTelemetryPlugin::ServerCallTracer::RecordSendInitialMetadata(
|
||||
grpc_metadata_batch* send_initial_metadata) {
|
||||
scope_config_->active_plugin_options_view().ForEach(
|
||||
[&](const InternalOpenTelemetryPluginOption& plugin_option,
|
||||
size_t index) {
|
||||
auto* labels_injector = plugin_option.labels_injector();
|
||||
if (labels_injector != nullptr) {
|
||||
labels_injector->AddLabels(
|
||||
send_initial_metadata,
|
||||
injected_labels_from_plugin_options_[index].get());
|
||||
}
|
||||
return true;
|
||||
},
|
||||
otel_plugin_);
|
||||
}
|
||||
|
||||
void OpenTelemetryPlugin::ServerCallTracer::RecordSendTrailingMetadata(
|
||||
grpc_metadata_batch* /*send_trailing_metadata*/) {
|
||||
// We need to record the time when the trailing metadata was sent to
|
||||
// mark the completeness of the request.
|
||||
elapsed_time_ = absl::Now() - start_time_;
|
||||
}
|
||||
|
||||
void OpenTelemetryServerCallTracer::RecordEnd(
|
||||
void OpenTelemetryPlugin::ServerCallTracer::RecordEnd(
|
||||
const grpc_call_final_info* final_info) {
|
||||
std::array<std::pair<absl::string_view, absl::string_view>, 2>
|
||||
additional_labels = {
|
||||
|
|
@ -214,47 +114,25 @@ void OpenTelemetryServerCallTracer::RecordEnd(
|
|||
KeyValueIterable labels(
|
||||
injected_labels_from_plugin_options_, additional_labels,
|
||||
/*active_plugin_options_view=*/nullptr, /*optional_labels_span=*/{},
|
||||
/*is_client=*/false);
|
||||
if (OpenTelemetryPluginState().server.call.duration != nullptr) {
|
||||
OpenTelemetryPluginState().server.call.duration->Record(
|
||||
/*is_client=*/false, otel_plugin_);
|
||||
if (otel_plugin_->server_.call.duration != nullptr) {
|
||||
otel_plugin_->server_.call.duration->Record(
|
||||
absl::ToDoubleSeconds(elapsed_time_), labels,
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
if (OpenTelemetryPluginState()
|
||||
.server.call.sent_total_compressed_message_size != nullptr) {
|
||||
OpenTelemetryPluginState()
|
||||
.server.call.sent_total_compressed_message_size->Record(
|
||||
final_info->stats.transport_stream_stats.outgoing.data_bytes,
|
||||
labels, opentelemetry::context::Context{});
|
||||
if (otel_plugin_->server_.call.sent_total_compressed_message_size !=
|
||||
nullptr) {
|
||||
otel_plugin_->server_.call.sent_total_compressed_message_size->Record(
|
||||
final_info->stats.transport_stream_stats.outgoing.data_bytes, labels,
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
if (OpenTelemetryPluginState()
|
||||
.server.call.rcvd_total_compressed_message_size != nullptr) {
|
||||
OpenTelemetryPluginState()
|
||||
.server.call.rcvd_total_compressed_message_size->Record(
|
||||
final_info->stats.transport_stream_stats.incoming.data_bytes,
|
||||
labels, opentelemetry::context::Context{});
|
||||
if (otel_plugin_->server_.call.rcvd_total_compressed_message_size !=
|
||||
nullptr) {
|
||||
otel_plugin_->server_.call.rcvd_total_compressed_message_size->Record(
|
||||
final_info->stats.transport_stream_stats.incoming.data_bytes, labels,
|
||||
opentelemetry::context::Context{});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//
|
||||
// OpenTelemetryServerCallTracerFactory
|
||||
//
|
||||
|
||||
grpc_core::ServerCallTracer*
|
||||
OpenTelemetryServerCallTracerFactory::CreateNewServerCallTracer(
|
||||
grpc_core::Arena* arena, const grpc_core::ChannelArgs& args) {
|
||||
return arena->ManagedNew<OpenTelemetryServerCallTracer>(args);
|
||||
}
|
||||
|
||||
bool OpenTelemetryServerCallTracerFactory::IsServerTraced(
|
||||
const grpc_core::ChannelArgs& args) {
|
||||
// Return true only if there is no server selector registered or if the server
|
||||
// selector returns true.
|
||||
return OpenTelemetryPluginState().server_selector == nullptr ||
|
||||
OpenTelemetryPluginState().server_selector(args);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
|
|
|||
|
|
@ -21,21 +21,116 @@
|
|||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "absl/strings/strip.h"
|
||||
|
||||
#include "src/core/lib/channel/call_tracer.h"
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
namespace grpc {
|
||||
namespace internal {
|
||||
|
||||
class OpenTelemetryServerCallTracerFactory
|
||||
: public grpc_core::ServerCallTracerFactory {
|
||||
public:
|
||||
grpc_core::ServerCallTracer* CreateNewServerCallTracer(
|
||||
grpc_core::Arena* arena,
|
||||
const grpc_core::ChannelArgs& channel_args) override;
|
||||
// OpenTelemetryPlugin::ServerCallTracer implementation
|
||||
|
||||
bool IsServerTraced(const grpc_core::ChannelArgs& args) override;
|
||||
class OpenTelemetryPlugin::ServerCallTracer
|
||||
: public grpc_core::ServerCallTracer {
|
||||
public:
|
||||
ServerCallTracer(
|
||||
OpenTelemetryPlugin* otel_plugin,
|
||||
std::shared_ptr<OpenTelemetryPlugin::ServerScopeConfig> scope_config)
|
||||
: start_time_(absl::Now()),
|
||||
injected_labels_from_plugin_options_(
|
||||
otel_plugin->plugin_options().size()),
|
||||
otel_plugin_(otel_plugin),
|
||||
scope_config_(std::move(scope_config)) {}
|
||||
|
||||
std::string TraceId() override {
|
||||
// Not implemented
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SpanId() override {
|
||||
// Not implemented
|
||||
return "";
|
||||
}
|
||||
|
||||
bool IsSampled() override {
|
||||
// Not implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
// Please refer to `grpc_transport_stream_op_batch_payload` for details on
|
||||
// arguments.
|
||||
void RecordSendInitialMetadata(
|
||||
grpc_metadata_batch* send_initial_metadata) override;
|
||||
|
||||
void RecordSendTrailingMetadata(
|
||||
grpc_metadata_batch* /*send_trailing_metadata*/) override;
|
||||
|
||||
void RecordSendMessage(const grpc_core::SliceBuffer& send_message) override {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Send message: %ld bytes", send_message.Length()));
|
||||
}
|
||||
void RecordSendCompressedMessage(
|
||||
const grpc_core::SliceBuffer& send_compressed_message) override {
|
||||
RecordAnnotation(absl::StrFormat("Send compressed message: %ld bytes",
|
||||
send_compressed_message.Length()));
|
||||
}
|
||||
|
||||
void RecordReceivedInitialMetadata(
|
||||
grpc_metadata_batch* recv_initial_metadata) override;
|
||||
|
||||
void RecordReceivedMessage(
|
||||
const grpc_core::SliceBuffer& recv_message) override {
|
||||
RecordAnnotation(
|
||||
absl::StrFormat("Received message: %ld bytes", recv_message.Length()));
|
||||
}
|
||||
void RecordReceivedDecompressedMessage(
|
||||
const grpc_core::SliceBuffer& recv_decompressed_message) override {
|
||||
RecordAnnotation(absl::StrFormat("Received decompressed message: %ld bytes",
|
||||
recv_decompressed_message.Length()));
|
||||
}
|
||||
|
||||
void RecordReceivedTrailingMetadata(
|
||||
grpc_metadata_batch* /*recv_trailing_metadata*/) override {}
|
||||
|
||||
void RecordCancel(grpc_error_handle /*cancel_error*/) override {
|
||||
elapsed_time_ = absl::Now() - start_time_;
|
||||
}
|
||||
|
||||
void RecordEnd(const grpc_call_final_info* final_info) override;
|
||||
|
||||
void RecordAnnotation(absl::string_view /*annotation*/) override {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
void RecordAnnotation(const Annotation& /*annotation*/) override {
|
||||
// Not implemented
|
||||
}
|
||||
std::shared_ptr<grpc_core::TcpTracerInterface> StartNewTcpTrace() override {
|
||||
// No TCP trace.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
absl::string_view MethodForStats() const {
|
||||
absl::string_view method = absl::StripPrefix(path_.as_string_view(), "/");
|
||||
if (registered_method_ ||
|
||||
(otel_plugin_->generic_method_attribute_filter() != nullptr &&
|
||||
otel_plugin_->generic_method_attribute_filter()(method))) {
|
||||
return method;
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
absl::Time start_time_;
|
||||
absl::Duration elapsed_time_;
|
||||
grpc_core::Slice path_;
|
||||
bool registered_method_;
|
||||
std::vector<std::unique_ptr<LabelsIterable>>
|
||||
injected_labels_from_plugin_options_;
|
||||
OpenTelemetryPlugin* otel_plugin_;
|
||||
std::shared_ptr<OpenTelemetryPlugin::ServerScopeConfig> scope_config_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
|
|
|||
|
|
@ -1168,7 +1168,7 @@ TEST_F(PickFirstTest, MetricValues) {
|
|||
const absl::string_view kLabelValues[] = {target_};
|
||||
auto stats_plugin = std::make_shared<FakeStatsPlugin>(
|
||||
nullptr, /*use_disabled_by_default_metrics=*/true);
|
||||
stats_plugin_group_.push_back(stats_plugin);
|
||||
stats_plugin_group_.AddStatsPlugin(stats_plugin, nullptr);
|
||||
// Send an update containing two addresses.
|
||||
constexpr std::array<absl::string_view, 2> kAddresses = {
|
||||
"ipv4:127.0.0.1:443", "ipv4:127.0.0.1:444"};
|
||||
|
|
|
|||
|
|
@ -1084,7 +1084,7 @@ TEST_F(WeightedRoundRobinTest, MetricValues) {
|
|||
const absl::string_view kOptionalLabelValues[] = {kLocalityName};
|
||||
auto stats_plugin = std::make_shared<FakeStatsPlugin>(
|
||||
nullptr, /*use_disabled_by_default_metrics=*/true);
|
||||
stats_plugin_group_.push_back(stats_plugin);
|
||||
stats_plugin_group_.AddStatsPlugin(stats_plugin, nullptr);
|
||||
// Send address list to LB policy.
|
||||
const std::array<absl::string_view, 3> kAddresses = {
|
||||
"ipv4:127.0.0.1:441", "ipv4:127.0.0.1:442", "ipv4:127.0.0.1:443"};
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []):
|
|||
"//src/core:stats_data",
|
||||
"//src/core:status_helper",
|
||||
"//src/core:time",
|
||||
"//test/core/util:fake_stats_plugin",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/core/util:test_lb_policies",
|
||||
],
|
||||
|
|
@ -170,6 +171,7 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []):
|
|||
"//src/core:time",
|
||||
"//test/core/event_engine/fuzzing_event_engine",
|
||||
"//test/core/event_engine/fuzzing_event_engine:fuzzing_event_engine_proto",
|
||||
"//test/core/util:fake_stats_plugin",
|
||||
"//test/core/util:fuzz_config_vars",
|
||||
"//test/core/util:fuzz_config_vars_proto",
|
||||
"//test/core/util:grpc_test_util",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/channel/metrics.h"
|
||||
#include "src/core/lib/channel/promise_based_filter.h"
|
||||
#include "src/core/lib/channel/tcp_tracer.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
#include "test/core/end2end/end2end_tests.h"
|
||||
#include "test/core/util/fake_stats_plugin.h"
|
||||
|
||||
namespace grpc_core {
|
||||
namespace {
|
||||
|
|
@ -130,33 +132,6 @@ class FakeCallTracer : public ClientCallTracer {
|
|||
grpc_transport_stream_stats
|
||||
FakeCallTracer::FakeCallAttemptTracer::transport_stream_stats_;
|
||||
|
||||
class FakeClientFilter : public ChannelFilter {
|
||||
public:
|
||||
static const grpc_channel_filter kFilter;
|
||||
|
||||
static absl::StatusOr<FakeClientFilter> Create(
|
||||
const ChannelArgs& /*args*/, ChannelFilter::Args /*filter_args*/) {
|
||||
return FakeClientFilter();
|
||||
}
|
||||
|
||||
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) override {
|
||||
auto* call_context = GetContext<grpc_call_context_element>();
|
||||
auto* tracer = GetContext<Arena>()->ManagedNew<FakeCallTracer>();
|
||||
GPR_DEBUG_ASSERT(
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value ==
|
||||
nullptr);
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].value = tracer;
|
||||
call_context[GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE].destroy =
|
||||
nullptr;
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
};
|
||||
|
||||
const grpc_channel_filter FakeClientFilter::kFilter =
|
||||
MakePromiseBasedFilter<FakeClientFilter, FilterEndpoint::kClient>(
|
||||
"fake_client");
|
||||
|
||||
class FakeServerCallTracer : public ServerCallTracer {
|
||||
public:
|
||||
~FakeServerCallTracer() override {}
|
||||
|
|
@ -203,11 +178,18 @@ class FakeServerCallTracer : public ServerCallTracer {
|
|||
|
||||
grpc_transport_stream_stats FakeServerCallTracer::transport_stream_stats_;
|
||||
|
||||
class FakeServerCallTracerFactory : public ServerCallTracerFactory {
|
||||
// TODO(yijiem): figure out how to reuse FakeStatsPlugin instead of
|
||||
// inheriting and overriding it here.
|
||||
class NewFakeStatsPlugin : public FakeStatsPlugin {
|
||||
public:
|
||||
ServerCallTracer* CreateNewServerCallTracer(
|
||||
Arena* arena, const ChannelArgs& /*args*/) override {
|
||||
return arena->ManagedNew<FakeServerCallTracer>();
|
||||
ClientCallTracer* GetClientCallTracer(
|
||||
const Slice& /*path*/, bool /*registered_method*/,
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> /*scope_config*/) override {
|
||||
return GetContext<Arena>()->ManagedNew<FakeCallTracer>();
|
||||
}
|
||||
ServerCallTracer* GetServerCallTracer(
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> /*scope_config*/) override {
|
||||
return GetContext<Arena>()->ManagedNew<FakeServerCallTracer>();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -219,12 +201,8 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) {
|
|||
g_mu = new Mutex();
|
||||
g_client_call_ended_notify = new Notification();
|
||||
g_server_call_ended_notify = new Notification();
|
||||
CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) {
|
||||
builder->channel_init()->RegisterFilter<FakeClientFilter>(
|
||||
GRPC_CLIENT_CHANNEL);
|
||||
});
|
||||
ServerCallTracerFactory::RegisterGlobal(new FakeServerCallTracerFactory);
|
||||
|
||||
GlobalStatsPluginRegistry::RegisterStatsPlugin(
|
||||
std::make_shared<NewFakeStatsPlugin>());
|
||||
auto send_from_client = RandomSlice(10);
|
||||
auto send_from_server = RandomSlice(20);
|
||||
CoreEnd2endTest::IncomingStatusOnClient server_status;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <grpc/status.h>
|
||||
|
||||
#include "src/core/ext/transport/chaotic_good/client_transport.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
||||
#include "src/core/lib/iomgr/timer_manager.h"
|
||||
#include "src/core/lib/promise/activity.h"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include <grpc/grpc.h>
|
||||
#include <grpc/status.h>
|
||||
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/promise/if.h"
|
||||
#include "src/core/lib/promise/loop.h"
|
||||
#include "src/core/lib/promise/seq.h"
|
||||
|
|
|
|||
|
|
@ -122,17 +122,17 @@ namespace {
|
|||
|
||||
template <typename HandleType>
|
||||
absl::optional<HandleType> FindInstrument(
|
||||
const absl::flat_hash_map<
|
||||
absl::string_view,
|
||||
GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>& instruments,
|
||||
const std::vector<GlobalInstrumentsRegistry::GlobalInstrumentDescriptor>&
|
||||
instruments,
|
||||
absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type,
|
||||
GlobalInstrumentsRegistry::InstrumentType instrument_type) {
|
||||
auto it = instruments.find(name);
|
||||
if (it != instruments.end() && it->second.value_type == value_type &&
|
||||
it->second.instrument_type == instrument_type) {
|
||||
HandleType handle;
|
||||
handle.index = it->second.index;
|
||||
return handle;
|
||||
for (const auto& descriptor : instruments) {
|
||||
if (descriptor.name == name && descriptor.value_type == value_type &&
|
||||
descriptor.instrument_type == instrument_type) {
|
||||
HandleType handle;
|
||||
handle.index = descriptor.index;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
|
@ -216,9 +216,11 @@ GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName(
|
|||
GlobalInstrumentsRegistry::GlobalInstrumentDescriptor*
|
||||
GlobalInstrumentsRegistryTestPeer::FindMetricDescriptorByName(
|
||||
absl::string_view name) {
|
||||
auto& instruments = GlobalInstrumentsRegistry::GetInstrumentList();
|
||||
auto it = instruments.find(name);
|
||||
if (it != instruments.end()) return &it->second;
|
||||
for (auto& descriptor : GlobalInstrumentsRegistry::GetInstrumentList()) {
|
||||
if (descriptor.name == name) {
|
||||
return &descriptor;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,8 @@ std::string MakeLabelString(
|
|||
|
||||
class FakeStatsPlugin : public StatsPlugin {
|
||||
public:
|
||||
class ScopeConfig : public StatsPlugin::ScopeConfig {};
|
||||
|
||||
explicit FakeStatsPlugin(
|
||||
absl::AnyInvocable<bool(const ChannelScope& /*scope*/) const>
|
||||
channel_filter = nullptr,
|
||||
|
|
@ -266,13 +268,16 @@ class FakeStatsPlugin : public StatsPlugin {
|
|||
});
|
||||
}
|
||||
|
||||
bool IsEnabledForChannel(const ChannelScope& scope) const override {
|
||||
if (channel_filter_ == nullptr) return true;
|
||||
return channel_filter_(scope);
|
||||
std::pair<bool, std::shared_ptr<StatsPlugin::ScopeConfig>>
|
||||
IsEnabledForChannel(const ChannelScope& scope) const override {
|
||||
if (channel_filter_ == nullptr || channel_filter_(scope)) {
|
||||
return {true, nullptr};
|
||||
}
|
||||
return {false, nullptr};
|
||||
}
|
||||
|
||||
bool IsEnabledForServer(const ChannelArgs& /*args*/) const override {
|
||||
return false;
|
||||
std::pair<bool, std::shared_ptr<StatsPlugin::ScopeConfig>> IsEnabledForServer(
|
||||
const ChannelArgs& /*args*/) const override {
|
||||
return {true, nullptr};
|
||||
}
|
||||
|
||||
void AddCounter(
|
||||
|
|
@ -382,6 +387,16 @@ class FakeStatsPlugin : public StatsPlugin {
|
|||
callbacks_.erase(callback);
|
||||
}
|
||||
|
||||
ClientCallTracer* GetClientCallTracer(
|
||||
const Slice& /*path*/, bool /*registered_method*/,
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> /*scope_config*/) override {
|
||||
return nullptr;
|
||||
}
|
||||
ServerCallTracer* GetServerCallTracer(
|
||||
std::shared_ptr<StatsPlugin::ScopeConfig> /*scope_config*/) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
absl::optional<uint64_t> GetCounterValue(
|
||||
GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle,
|
||||
absl::Span<const absl::string_view> label_values,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ grpc_cc_library(
|
|||
deps = [
|
||||
"//:grpc++",
|
||||
"//src/cpp/ext/otel:otel_plugin",
|
||||
"//test/core/util:fake_stats_plugin",
|
||||
"//test/core/util:grpc_test_util",
|
||||
"//test/cpp/end2end:test_service_impl",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -18,10 +18,15 @@
|
|||
|
||||
#include "src/cpp/ext/otel/otel_plugin.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "opentelemetry/metrics/provider.h"
|
||||
#include "opentelemetry/nostd/variant.h"
|
||||
#include "opentelemetry/sdk/common/attribute_utils.h"
|
||||
#include "opentelemetry/sdk/metrics/data/point_data.h"
|
||||
#include "opentelemetry/sdk/metrics/meter_provider.h"
|
||||
#include "opentelemetry/sdk/metrics/metric_reader.h"
|
||||
|
||||
|
|
@ -38,6 +43,73 @@ namespace grpc {
|
|||
namespace testing {
|
||||
namespace {
|
||||
|
||||
#define GRPC_ARG_SERVER_SELECTOR_KEY "grpc.testing.server_selector_key"
|
||||
#define GRPC_ARG_SERVER_SELECTOR_VALUE "grpc.testing.server_selector_value"
|
||||
|
||||
template <typename T>
|
||||
void PopulateLabelMap(
|
||||
T label_keys, T label_values,
|
||||
std::unordered_map<std::string,
|
||||
opentelemetry::sdk::common::OwnedAttributeValue>*
|
||||
label_maps) {
|
||||
for (size_t i = 0; i < label_keys.size(); ++i) {
|
||||
(*label_maps)[std::string(label_keys[i])] = std::string(label_values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
MATCHER_P4(AttributesEq, label_keys, label_values, optional_label_keys,
|
||||
optional_label_values, "") {
|
||||
std::unordered_map<std::string,
|
||||
opentelemetry::sdk::common::OwnedAttributeValue>
|
||||
label_map;
|
||||
PopulateLabelMap(label_keys, label_values, &label_map);
|
||||
PopulateLabelMap(optional_label_keys, optional_label_values, &label_map);
|
||||
return ::testing::ExplainMatchResult(
|
||||
::testing::UnorderedElementsAreArray(label_map),
|
||||
arg.attributes.GetAttributes(), result_listener);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto IntOrDoubleEq(T result) {
|
||||
return ::testing::Eq(result);
|
||||
}
|
||||
template <>
|
||||
auto IntOrDoubleEq(double result) {
|
||||
return ::testing::DoubleEq(result);
|
||||
}
|
||||
|
||||
MATCHER_P(CounterResultEq, result, "") {
|
||||
return ::testing::ExplainMatchResult(
|
||||
::testing::VariantWith<opentelemetry::sdk::metrics::SumPointData>(
|
||||
::testing::Field(
|
||||
&opentelemetry::sdk::metrics::SumPointData::value_,
|
||||
::testing::VariantWith<std::remove_cv_t<decltype(result)>>(
|
||||
IntOrDoubleEq(result)))),
|
||||
arg.point_data, result_listener);
|
||||
}
|
||||
|
||||
MATCHER_P4(HistogramResultEq, sum, min, max, count, "") {
|
||||
return ::testing::ExplainMatchResult(
|
||||
::testing::VariantWith<opentelemetry::sdk::metrics::HistogramPointData>(
|
||||
::testing::AllOf(
|
||||
::testing::Field(
|
||||
&opentelemetry::sdk::metrics::HistogramPointData::sum_,
|
||||
::testing::VariantWith<std::remove_cv_t<decltype(sum)>>(
|
||||
IntOrDoubleEq(sum))),
|
||||
::testing::Field(
|
||||
&opentelemetry::sdk::metrics::HistogramPointData::min_,
|
||||
::testing::VariantWith<std::remove_cv_t<decltype(min)>>(
|
||||
IntOrDoubleEq(min))),
|
||||
::testing::Field(
|
||||
&opentelemetry::sdk::metrics::HistogramPointData::max_,
|
||||
::testing::VariantWith<std::remove_cv_t<decltype(max)>>(
|
||||
IntOrDoubleEq(max))),
|
||||
::testing::Field(
|
||||
&opentelemetry::sdk::metrics::HistogramPointData::count_,
|
||||
::testing::Eq(count)))),
|
||||
arg.point_data, result_listener);
|
||||
}
|
||||
|
||||
TEST(OpenTelemetryPluginBuildTest, ApiDependency) {
|
||||
opentelemetry::metrics::Provider::GetMeterProvider();
|
||||
}
|
||||
|
|
@ -933,6 +1005,354 @@ TEST_F(OpenTelemetryPluginOptionEnd2EndTest,
|
|||
EXPECT_EQ(absl::get<std::string>(server_attributes.at("key5")), "value5");
|
||||
}
|
||||
|
||||
using OpenTelemetryPluginNPCMetricsTest = OpenTelemetryPluginEnd2EndTest;
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) {
|
||||
constexpr absl::string_view kMetricName = "uint64_counter";
|
||||
constexpr int kCounterValues[] = {1, 2, 3};
|
||||
constexpr int64_t kCounterResult = 6;
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"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);
|
||||
Init(std::move(Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_target_selector([](absl::string_view target) {
|
||||
return absl::StartsWith(target, "dns:///");
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
|
||||
grpc_core::StatsPlugin::ChannelScope("dns:///localhost:8080", ""));
|
||||
for (auto v : kCounterValues) {
|
||||
stats_plugins.AddCounter(handle, v, kLabelValues, kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(data, ::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName, ::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues,
|
||||
kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
CounterResultEq(kCounterResult))))));
|
||||
}
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) {
|
||||
constexpr absl::string_view kMetricName = "double_counter";
|
||||
constexpr double kCounterValues[] = {1.23, 2.34, 3.45};
|
||||
constexpr double kCounterResult = 7.02;
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"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);
|
||||
Init(std::move(Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_target_selector([](absl::string_view target) {
|
||||
return absl::StartsWith(target, "dns:///");
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel(
|
||||
grpc_core::StatsPlugin::ChannelScope("dns:///localhost:8080", ""));
|
||||
for (auto v : kCounterValues) {
|
||||
stats_plugins.AddCounter(handle, v, kLabelValues, kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(data, ::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName, ::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues,
|
||||
kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
CounterResultEq(kCounterResult))))));
|
||||
}
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) {
|
||||
constexpr absl::string_view kMetricName = "uint64_histogram";
|
||||
constexpr int kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6};
|
||||
constexpr int64_t kSum = 26;
|
||||
constexpr int64_t kMin = 1;
|
||||
constexpr int64_t kMax = 6;
|
||||
constexpr int64_t kCount = 8;
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"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);
|
||||
Init(std::move(
|
||||
Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_server_selector([](const grpc_core::ChannelArgs& args) {
|
||||
return args.GetString(GRPC_ARG_SERVER_SELECTOR_KEY) ==
|
||||
GRPC_ARG_SERVER_SELECTOR_VALUE;
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
grpc_core::ChannelArgs args;
|
||||
args = args.Set(GRPC_ARG_SERVER_SELECTOR_KEY, GRPC_ARG_SERVER_SELECTOR_VALUE);
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
for (auto v : kHistogramValues) {
|
||||
stats_plugins.RecordHistogram(handle, v, kLabelValues,
|
||||
kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(data,
|
||||
::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
}
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleHistogram) {
|
||||
constexpr absl::string_view kMetricName = "double_histogram";
|
||||
constexpr double kHistogramValues[] = {1.1, 1.2, 2.2, 3.3,
|
||||
4.4, 4.5, 5.5, 6.6};
|
||||
constexpr double kSum = 28.8;
|
||||
constexpr double kMin = 1.1;
|
||||
constexpr double kMax = 6.6;
|
||||
constexpr double kCount = 8;
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"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);
|
||||
Init(std::move(
|
||||
Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_server_selector([](const grpc_core::ChannelArgs& args) {
|
||||
return args.GetString(GRPC_ARG_SERVER_SELECTOR_KEY) ==
|
||||
GRPC_ARG_SERVER_SELECTOR_VALUE;
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
grpc_core::ChannelArgs args;
|
||||
args = args.Set(GRPC_ARG_SERVER_SELECTOR_KEY, GRPC_ARG_SERVER_SELECTOR_VALUE);
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
for (auto v : kHistogramValues) {
|
||||
stats_plugins.RecordHistogram(handle, v, kLabelValues,
|
||||
kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(data,
|
||||
::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
}
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest,
|
||||
RegisterMultipleOpenTelemetryPlugins) {
|
||||
constexpr absl::string_view kMetricName = "yet_another_double_histogram";
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"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);
|
||||
// Build and register a separate OpenTelemetryPlugin and verify its histogram
|
||||
// recording.
|
||||
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
|
||||
auto reader = BuildAndRegisterOpenTelemetryPlugin(std::move(
|
||||
Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_server_selector([](const grpc_core::ChannelArgs& args) {
|
||||
return args.GetString(GRPC_ARG_SERVER_SELECTOR_KEY) ==
|
||||
GRPC_ARG_SERVER_SELECTOR_VALUE;
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
EXPECT_EQ(ot_builder.BuildAndRegisterGlobal(), absl::OkStatus());
|
||||
grpc_core::ChannelArgs args;
|
||||
args = args.Set(GRPC_ARG_SERVER_SELECTOR_KEY, GRPC_ARG_SERVER_SELECTOR_VALUE);
|
||||
{
|
||||
constexpr double kHistogramValues[] = {1.23, 2.34, 3.45, 4.56};
|
||||
constexpr double kSum = 11.58;
|
||||
constexpr double kMin = 1.23;
|
||||
constexpr double kMax = 4.56;
|
||||
constexpr int kCount = 4;
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
for (auto v : kHistogramValues) {
|
||||
stats_plugins.RecordHistogram(handle, v, kLabelValues,
|
||||
kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); },
|
||||
reader.get());
|
||||
EXPECT_THAT(
|
||||
data, ::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
}
|
||||
// Now build and register another OpenTelemetryPlugin using the test fixture
|
||||
// and record histogram.
|
||||
constexpr double kHistogramValues[] = {1.1, 1.2, 2.2, 3.3,
|
||||
4.4, 4.5, 5.5, 6.6};
|
||||
constexpr double kSum = 28.8;
|
||||
constexpr double kMin = 1.1;
|
||||
constexpr double kMax = 6.6;
|
||||
constexpr int kCount = 8;
|
||||
Init(std::move(
|
||||
Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_server_selector([](const grpc_core::ChannelArgs& args) {
|
||||
return args.GetString(GRPC_ARG_SERVER_SELECTOR_KEY) ==
|
||||
GRPC_ARG_SERVER_SELECTOR_VALUE;
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
for (auto v : kHistogramValues) {
|
||||
stats_plugins.RecordHistogram(handle, v, kLabelValues,
|
||||
kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(data,
|
||||
::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
// Verify that the first plugin gets the data as well.
|
||||
data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); },
|
||||
reader.get());
|
||||
EXPECT_THAT(data,
|
||||
::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kOptionalLabelKeys,
|
||||
kOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
}
|
||||
|
||||
TEST_F(OpenTelemetryPluginNPCMetricsTest,
|
||||
DisabledOptionalLabelKeysShouldNotBeRecorded) {
|
||||
constexpr absl::string_view kMetricName =
|
||||
"yet_another_yet_another_double_histogram";
|
||||
constexpr double kHistogramValues[] = {1.1, 1.2, 2.2, 3.3,
|
||||
4.4, 4.5, 5.5, 6.6};
|
||||
constexpr double kSum = 28.8;
|
||||
constexpr double kMin = 1.1;
|
||||
constexpr double kMax = 6.6;
|
||||
constexpr double kCount = 8;
|
||||
constexpr std::array<absl::string_view, 2> kLabelKeys = {"label_key_1",
|
||||
"label_key_2"};
|
||||
constexpr std::array<absl::string_view, 4> kOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2", "optional_label_key_3",
|
||||
"optional_label_key_4"};
|
||||
constexpr std::array<absl::string_view, 2> kActualOptionalLabelKeys = {
|
||||
"optional_label_key_1", "optional_label_key_2"};
|
||||
constexpr std::array<absl::string_view, 2> kLabelValues = {"label_value_1",
|
||||
"label_value_2"};
|
||||
constexpr std::array<absl::string_view, 4> kOptionalLabelValues = {
|
||||
"optional_label_value_1", "optional_label_value_2",
|
||||
"optional_label_value_3", "optional_label_value_4"};
|
||||
constexpr std::array<absl::string_view, 2> kActualOptionalLabelValues = {
|
||||
"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);
|
||||
Init(std::move(
|
||||
Options()
|
||||
.set_metric_names({kMetricName})
|
||||
.set_server_selector([](const grpc_core::ChannelArgs& args) {
|
||||
return args.GetString(GRPC_ARG_SERVER_SELECTOR_KEY) ==
|
||||
GRPC_ARG_SERVER_SELECTOR_VALUE;
|
||||
})
|
||||
.add_optional_label(kOptionalLabelKeys[0])
|
||||
.add_optional_label(kOptionalLabelKeys[1])));
|
||||
grpc_core::ChannelArgs args;
|
||||
args = args.Set(GRPC_ARG_SERVER_SELECTOR_KEY, GRPC_ARG_SERVER_SELECTOR_VALUE);
|
||||
auto stats_plugins =
|
||||
grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForServer(args);
|
||||
for (auto v : kHistogramValues) {
|
||||
stats_plugins.RecordHistogram(handle, v, kLabelValues,
|
||||
kOptionalLabelValues);
|
||||
}
|
||||
auto data = ReadCurrentMetricsData(
|
||||
[&](const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&
|
||||
data) { return !data.contains(kMetricName); });
|
||||
EXPECT_THAT(
|
||||
data,
|
||||
::testing::ElementsAre(::testing::Pair(
|
||||
kMetricName,
|
||||
::testing::ElementsAre(::testing::AllOf(
|
||||
AttributesEq(kLabelKeys, kLabelValues, kActualOptionalLabelKeys,
|
||||
kActualOptionalLabelValues),
|
||||
HistogramResultEq(kSum, kMin, kMax, kCount))))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "src/core/lib/channel/promise_based_filter.h"
|
||||
#include "src/core/lib/config/core_configuration.h"
|
||||
#include "src/core/lib/gprpp/notification.h"
|
||||
#include "test/core/util/fake_stats_plugin.h"
|
||||
#include "test/core/util/test_config.h"
|
||||
#include "test/cpp/end2end/test_service_impl.h"
|
||||
#include "test/cpp/util/byte_buffer_proto_helper.h"
|
||||
|
|
@ -83,38 +84,7 @@ const grpc_channel_filter AddServiceLabelsFilter::kFilter =
|
|||
"add_service_labels_filter");
|
||||
|
||||
void OpenTelemetryPluginEnd2EndTest::Init(Options config) {
|
||||
// We are resetting the MeterProvider and OpenTelemetry plugin at the start
|
||||
// of each test to avoid test results from one test carrying over to another
|
||||
// test. (Some measurements can get arbitrarily delayed.)
|
||||
auto meter_provider =
|
||||
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>(
|
||||
std::make_unique<opentelemetry::sdk::metrics::ViewRegistry>(),
|
||||
*config.resource);
|
||||
reader_.reset(new grpc::testing::MockMetricReader);
|
||||
meter_provider->AddMetricReader(reader_);
|
||||
grpc_core::CoreConfiguration::Reset();
|
||||
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
|
||||
ot_builder.DisableAllMetrics();
|
||||
for (const auto& metric_name : config.metric_names) {
|
||||
ot_builder.EnableMetric(metric_name);
|
||||
}
|
||||
if (config.use_meter_provider) {
|
||||
auto meter_provider =
|
||||
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
|
||||
reader_.reset(new grpc::testing::MockMetricReader);
|
||||
meter_provider->AddMetricReader(reader_);
|
||||
ot_builder.SetMeterProvider(std::move(meter_provider));
|
||||
}
|
||||
ot_builder.SetTargetSelector(std::move(config.target_selector));
|
||||
ot_builder.SetServerSelector(std::move(config.server_selector));
|
||||
ot_builder.SetTargetAttributeFilter(
|
||||
std::move(config.target_attribute_filter));
|
||||
ot_builder.SetGenericMethodAttributeFilter(
|
||||
std::move(config.generic_method_attribute_filter));
|
||||
for (auto& option : config.plugin_options) {
|
||||
ot_builder.AddPluginOption(std::move(option));
|
||||
}
|
||||
ASSERT_EQ(ot_builder.BuildAndRegisterGlobal(), absl::OkStatus());
|
||||
ChannelArguments channel_args;
|
||||
if (!config.labels_to_inject.empty()) {
|
||||
labels_to_inject_ = config.labels_to_inject;
|
||||
|
|
@ -125,6 +95,7 @@ void OpenTelemetryPluginEnd2EndTest::Init(Options config) {
|
|||
});
|
||||
channel_args.SetPointer(GRPC_ARG_LABELS_TO_INJECT, &labels_to_inject_);
|
||||
}
|
||||
reader_ = BuildAndRegisterOpenTelemetryPlugin(std::move(config));
|
||||
grpc_init();
|
||||
grpc::ServerBuilder builder;
|
||||
int port;
|
||||
|
|
@ -148,6 +119,8 @@ void OpenTelemetryPluginEnd2EndTest::TearDown() {
|
|||
server_->Shutdown();
|
||||
grpc_shutdown_blocking();
|
||||
grpc_core::ServerCallTracerFactory::TestOnlyReset();
|
||||
grpc_core::GlobalStatsPluginRegistryTestPeer::
|
||||
ResetGlobalStatsPluginRegistry();
|
||||
}
|
||||
|
||||
void OpenTelemetryPluginEnd2EndTest::ResetStub(
|
||||
|
|
@ -183,14 +156,18 @@ OpenTelemetryPluginEnd2EndTest::ReadCurrentMetricsData(
|
|||
bool(const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&)>
|
||||
continue_predicate) {
|
||||
continue_predicate,
|
||||
opentelemetry::sdk::metrics::MetricReader* reader) {
|
||||
if (reader == nullptr) {
|
||||
reader = reader_.get();
|
||||
}
|
||||
absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
|
||||
data;
|
||||
auto deadline = absl::Now() + absl::Seconds(5);
|
||||
do {
|
||||
reader_->Collect([&](opentelemetry::sdk::metrics::ResourceMetrics& rm) {
|
||||
reader->Collect([&](opentelemetry::sdk::metrics::ResourceMetrics& rm) {
|
||||
for (const opentelemetry::sdk::metrics::ScopeMetrics& smd :
|
||||
rm.scope_metric_data_) {
|
||||
for (const opentelemetry::sdk::metrics::MetricData& md :
|
||||
|
|
@ -207,5 +184,46 @@ OpenTelemetryPluginEnd2EndTest::ReadCurrentMetricsData(
|
|||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<opentelemetry::sdk::metrics::MetricReader>
|
||||
OpenTelemetryPluginEnd2EndTest::BuildAndRegisterOpenTelemetryPlugin(
|
||||
OpenTelemetryPluginEnd2EndTest::Options options) {
|
||||
grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder;
|
||||
// We are resetting the MeterProvider and OpenTelemetry plugin at the start
|
||||
// of each test to avoid test results from one test carrying over to another
|
||||
// test. (Some measurements can get arbitrarily delayed.)
|
||||
auto meter_provider =
|
||||
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>(
|
||||
std::make_unique<opentelemetry::sdk::metrics::ViewRegistry>(),
|
||||
*options.resource);
|
||||
std::shared_ptr<opentelemetry::sdk::metrics::MetricReader> reader =
|
||||
std::make_shared<grpc::testing::MockMetricReader>();
|
||||
meter_provider->AddMetricReader(reader);
|
||||
ot_builder.DisableAllMetrics();
|
||||
for (const auto& metric_name : options.metric_names) {
|
||||
ot_builder.EnableMetric(metric_name);
|
||||
}
|
||||
if (options.use_meter_provider) {
|
||||
auto meter_provider =
|
||||
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
|
||||
reader.reset(new grpc::testing::MockMetricReader);
|
||||
meter_provider->AddMetricReader(reader);
|
||||
ot_builder.SetMeterProvider(std::move(meter_provider));
|
||||
}
|
||||
ot_builder.SetTargetSelector(std::move(options.target_selector));
|
||||
ot_builder.SetServerSelector(std::move(options.server_selector));
|
||||
ot_builder.SetTargetAttributeFilter(
|
||||
std::move(options.target_attribute_filter));
|
||||
ot_builder.SetGenericMethodAttributeFilter(
|
||||
std::move(options.generic_method_attribute_filter));
|
||||
for (auto& option : options.plugin_options) {
|
||||
ot_builder.AddPluginOption(std::move(option));
|
||||
}
|
||||
for (auto& optional_label_key : options.optional_label_keys) {
|
||||
ot_builder.AddOptionalLabel(optional_label_key);
|
||||
}
|
||||
EXPECT_EQ(ot_builder.BuildAndRegisterGlobal(), absl::OkStatus());
|
||||
return reader;
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
|
|
|||
|
|
@ -114,6 +114,11 @@ class OpenTelemetryPluginEnd2EndTest : public ::testing::Test {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Options& add_optional_label(absl::string_view optional_label_key) {
|
||||
optional_label_keys.emplace(optional_label_key);
|
||||
return *this;
|
||||
}
|
||||
|
||||
absl::flat_hash_set<absl::string_view> metric_names;
|
||||
// TODO(yashykt): opentelemetry::sdk::resource::Resource doesn't have a copy
|
||||
// assignment operator so wrapping it in a unique_ptr till it is fixed.
|
||||
|
|
@ -135,6 +140,7 @@ class OpenTelemetryPluginEnd2EndTest : public ::testing::Test {
|
|||
std::vector<
|
||||
std::unique_ptr<grpc::internal::InternalOpenTelemetryPluginOption>>
|
||||
plugin_options;
|
||||
absl::flat_hash_set<absl::string_view> optional_label_keys;
|
||||
};
|
||||
|
||||
// Note that we can't use SetUp() here since we want to send in parameters.
|
||||
|
|
@ -147,6 +153,10 @@ class OpenTelemetryPluginEnd2EndTest : public ::testing::Test {
|
|||
void SendRPC();
|
||||
void SendGenericRPC();
|
||||
|
||||
std::shared_ptr<opentelemetry::sdk::metrics::MetricReader>
|
||||
BuildAndRegisterOpenTelemetryPlugin(
|
||||
OpenTelemetryPluginEnd2EndTest::Options options);
|
||||
|
||||
absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>
|
||||
|
|
@ -155,7 +165,8 @@ class OpenTelemetryPluginEnd2EndTest : public ::testing::Test {
|
|||
bool(const absl::flat_hash_map<
|
||||
std::string,
|
||||
std::vector<opentelemetry::sdk::metrics::PointDataAttributes>>&)>
|
||||
continue_predicate);
|
||||
continue_predicate,
|
||||
opentelemetry::sdk::metrics::MetricReader* reader = nullptr);
|
||||
|
||||
const absl::string_view kMethodName = "grpc.testing.EchoTestService/Echo";
|
||||
const absl::string_view kGenericMethodName = "foo/bar";
|
||||
|
|
|
|||
|
|
@ -2165,6 +2165,7 @@ src/core/lib/channel/metrics.h \
|
|||
src/core/lib/channel/promise_based_filter.cc \
|
||||
src/core/lib/channel/promise_based_filter.h \
|
||||
src/core/lib/channel/server_call_tracer_filter.cc \
|
||||
src/core/lib/channel/server_call_tracer_filter.h \
|
||||
src/core/lib/channel/status_util.cc \
|
||||
src/core/lib/channel/status_util.h \
|
||||
src/core/lib/channel/tcp_tracer.h \
|
||||
|
|
|
|||
|
|
@ -1937,6 +1937,7 @@ src/core/lib/channel/metrics.h \
|
|||
src/core/lib/channel/promise_based_filter.cc \
|
||||
src/core/lib/channel/promise_based_filter.h \
|
||||
src/core/lib/channel/server_call_tracer_filter.cc \
|
||||
src/core/lib/channel/server_call_tracer_filter.h \
|
||||
src/core/lib/channel/status_util.cc \
|
||||
src/core/lib/channel/status_util.h \
|
||||
src/core/lib/channel/tcp_tracer.h \
|
||||
|
|
|
|||
Loading…
Reference in New Issue