1 // 2 // 3 // Copyright 2023 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPCPP_EXT_OTEL_PLUGIN_H 20 #define GRPCPP_EXT_OTEL_PLUGIN_H 21 22 #include <stddef.h> 23 #include <stdint.h> 24 25 #include <memory> 26 27 #include "absl/functional/any_invocable.h" 28 #include "absl/status/status.h" 29 #include "absl/strings/string_view.h" 30 #include "opentelemetry/metrics/meter_provider.h" 31 32 #include <grpc/support/metrics.h> 33 #include <grpc/support/port_platform.h> 34 35 namespace grpc { 36 37 namespace internal { 38 class OpenTelemetryPluginBuilderImpl; 39 class OpenTelemetryPlugin; 40 } // namespace internal 41 42 class OpenTelemetryPluginOption { 43 public: 44 virtual ~OpenTelemetryPluginOption() = default; 45 }; 46 47 /// The most common way to use this API is - 48 /// 49 /// OpenTelemetryPluginBuilder().SetMeterProvider(provider).BuildAndRegister(); 50 /// 51 /// The set of instruments available are - 52 /// grpc.client.attempt.started 53 /// grpc.client.attempt.duration 54 /// grpc.client.attempt.sent_total_compressed_message_size 55 /// grpc.client.attempt.rcvd_total_compressed_message_size 56 /// grpc.server.call.started 57 /// grpc.server.call.duration 58 /// grpc.server.call.sent_total_compressed_message_size 59 /// grpc.server.call.rcvd_total_compressed_message_size 60 class OpenTelemetryPluginBuilder { 61 public: 62 using ChannelScope = grpc_core::experimental::StatsPluginChannelScope; 63 64 /// Metrics 65 static constexpr absl::string_view kClientAttemptStartedInstrumentName = 66 "grpc.client.attempt.started"; 67 static constexpr absl::string_view kClientAttemptDurationInstrumentName = 68 "grpc.client.attempt.duration"; 69 static constexpr absl::string_view 70 kClientAttemptSentTotalCompressedMessageSizeInstrumentName = 71 "grpc.client.attempt.sent_total_compressed_message_size"; 72 static constexpr absl::string_view 73 kClientAttemptRcvdTotalCompressedMessageSizeInstrumentName = 74 "grpc.client.attempt.rcvd_total_compressed_message_size"; 75 static constexpr absl::string_view kServerCallStartedInstrumentName = 76 "grpc.server.call.started"; 77 static constexpr absl::string_view kServerCallDurationInstrumentName = 78 "grpc.server.call.duration"; 79 static constexpr absl::string_view 80 kServerCallSentTotalCompressedMessageSizeInstrumentName = 81 "grpc.server.call.sent_total_compressed_message_size"; 82 static constexpr absl::string_view 83 kServerCallRcvdTotalCompressedMessageSizeInstrumentName = 84 "grpc.server.call.rcvd_total_compressed_message_size"; 85 86 OpenTelemetryPluginBuilder(); 87 ~OpenTelemetryPluginBuilder(); 88 /// If `SetMeterProvider()` is not called, no metrics are collected. 89 OpenTelemetryPluginBuilder& SetMeterProvider( 90 std::shared_ptr<opentelemetry::metrics::MeterProvider> meter_provider); 91 /// If set, \a target_attribute_filter is called per channel to decide whether 92 /// to record the target attribute on client or to replace it with "other". 93 /// This helps reduce the cardinality on metrics in cases where many channels 94 /// are created with different targets in the same binary (which might happen 95 /// for example, if the channel target string uses IP addresses directly). 96 OpenTelemetryPluginBuilder& SetTargetAttributeFilter( 97 absl::AnyInvocable<bool(absl::string_view /*target*/) const> 98 target_attribute_filter); 99 /// If set, \a generic_method_attribute_filter is called per call with a 100 /// generic method type to decide whether to record the method name or to 101 /// replace it with "other". Non-generic or pre-registered methods remain 102 /// unaffected. If not set, by default, generic method names are replaced with 103 /// "other" when recording metrics. 104 OpenTelemetryPluginBuilder& SetGenericMethodAttributeFilter( 105 absl::AnyInvocable<bool(absl::string_view /*generic_method*/) const> 106 generic_method_attribute_filter); 107 // Methods to manipulate which instruments are enabled in the OpenTelemetry 108 // Stats Plugin. 109 OpenTelemetryPluginBuilder& EnableMetrics( 110 absl::Span<const absl::string_view> metric_names); 111 OpenTelemetryPluginBuilder& DisableMetrics( 112 absl::Span<const absl::string_view> metric_names); 113 OpenTelemetryPluginBuilder& DisableAllMetrics(); 114 /// Add a plugin option to add to the opentelemetry plugin being built. At 115 /// present, this type is an opaque type. Ownership of \a option is 116 /// transferred when `AddPluginOption` is invoked. A maximum of 64 plugin 117 /// options can be added. 118 OpenTelemetryPluginBuilder& AddPluginOption( 119 std::unique_ptr<OpenTelemetryPluginOption> option); 120 /// Records \a optional_label_key on all metrics that provide it. 121 OpenTelemetryPluginBuilder& AddOptionalLabel( 122 absl::string_view optional_label_key); 123 /// Set scope filter to choose which channels are recorded by this plugin. 124 /// Server-side recording remains unaffected. 125 OpenTelemetryPluginBuilder& SetChannelScopeFilter( 126 absl::AnyInvocable<bool(const ChannelScope& /*scope*/) const> 127 channel_scope_filter); 128 /// Registers a global plugin that acts on all channels and servers running on 129 /// the process. 130 absl::Status BuildAndRegisterGlobal(); 131 132 private: 133 std::unique_ptr<internal::OpenTelemetryPluginBuilderImpl> impl_; 134 }; 135 136 namespace experimental { 137 // TODO(yashykt): Delete this after the 1.62 release. 138 GRPC_DEPRECATED( 139 "Use grpc::OpenTelemetryPluginBuilder instead. The experimental version " 140 "will be deleted after the 1.62 release.") 141 typedef grpc::OpenTelemetryPluginBuilder OpenTelemetryPluginBuilder; 142 } // namespace experimental 143 144 } // namespace grpc 145 146 #endif // GRPCPP_EXT_OTEL_PLUGIN_H 147