• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
20 #define GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
21 
22 #include <grpc/support/port_platform.h>
23 #include <grpc/support/time.h>
24 #include <stdint.h>
25 
26 #include <memory>
27 #include <string>
28 
29 #include "absl/base/thread_annotations.h"
30 #include "absl/status/status.h"
31 #include "absl/strings/string_view.h"
32 #include "absl/time/time.h"
33 #include "src/core/lib/iomgr/error.h"
34 #include "src/core/lib/resource_quota/arena.h"
35 #include "src/core/lib/slice/slice.h"
36 #include "src/core/lib/slice/slice_buffer.h"
37 #include "src/core/lib/transport/metadata_batch.h"
38 #include "src/core/lib/transport/transport.h"
39 #include "src/core/telemetry/call_tracer.h"
40 #include "src/core/telemetry/tcp_tracer.h"
41 #include "src/core/util/sync.h"
42 #include "src/cpp/ext/otel/otel_plugin.h"
43 
44 namespace grpc {
45 namespace internal {
46 
47 class OpenTelemetryPluginImpl::ClientCallTracer
48     : public grpc_core::ClientCallTracer {
49  public:
50   class CallAttemptTracer
51       : public grpc_core::ClientCallTracer::CallAttemptTracer {
52    public:
53     CallAttemptTracer(const OpenTelemetryPluginImpl::ClientCallTracer* parent,
54                       bool arena_allocated);
55 
TraceId()56     std::string TraceId() override {
57       // Not implemented
58       return "";
59     }
60 
SpanId()61     std::string SpanId() override {
62       // Not implemented
63       return "";
64     }
65 
IsSampled()66     bool IsSampled() override {
67       // Not implemented
68       return false;
69     }
70 
71     void RecordSendInitialMetadata(
72         grpc_metadata_batch* send_initial_metadata) override;
RecordSendTrailingMetadata(grpc_metadata_batch *)73     void RecordSendTrailingMetadata(
74         grpc_metadata_batch* /*send_trailing_metadata*/) override {}
75     void RecordSendMessage(const grpc_core::SliceBuffer& send_message) override;
76     void RecordSendCompressedMessage(
77         const grpc_core::SliceBuffer& send_compressed_message) override;
78     void RecordReceivedInitialMetadata(
79         grpc_metadata_batch* recv_initial_metadata) override;
80     void RecordReceivedMessage(
81         const grpc_core::SliceBuffer& recv_message) override;
82     void RecordReceivedDecompressedMessage(
83         const grpc_core::SliceBuffer& recv_decompressed_message) override;
84     void RecordReceivedTrailingMetadata(
85         absl::Status status, grpc_metadata_batch* recv_trailing_metadata,
86         const grpc_transport_stream_stats* transport_stream_stats) override;
87     void RecordIncomingBytes(
88         const TransportByteSize& transport_byte_size) override;
89     void RecordOutgoingBytes(
90         const TransportByteSize& transport_byte_size) override;
91     void RecordCancel(grpc_error_handle cancel_error) override;
92     void RecordEnd(const gpr_timespec& /*latency*/) override;
93     void RecordAnnotation(absl::string_view /*annotation*/) override;
94     void RecordAnnotation(const Annotation& /*annotation*/) override;
95     std::shared_ptr<grpc_core::TcpTracerInterface> StartNewTcpTrace() override;
96     void SetOptionalLabel(OptionalLabelKey key,
97                           grpc_core::RefCountedStringValue value) override;
98 
99    private:
100     void PopulateLabelInjectors(grpc_metadata_batch* metadata);
101 
102     const ClientCallTracer* parent_;
103     const bool arena_allocated_;
104     // Start time (for measuring latency).
105     absl::Time start_time_;
106     std::unique_ptr<LabelsIterable> injected_labels_;
107     // Avoid std::map to avoid per-call allocations.
108     std::array<grpc_core::RefCountedStringValue,
109                static_cast<size_t>(OptionalLabelKey::kSize)>
110         optional_labels_;
111     std::vector<std::unique_ptr<LabelsIterable>>
112         injected_labels_from_plugin_options_;
113     bool is_trailers_only_ = false;
114     // TODO(roth, ctiller): Won't need atomic here once chttp2 is migrated
115     // to promises, after which we can ensure that the transport invokes
116     // the RecordIncomingBytes() and RecordOutgoingBytes() methods inside
117     // the call's party.
118     std::atomic<uint64_t> incoming_bytes_{0};
119     std::atomic<uint64_t> outgoing_bytes_{0};
120   };
121 
122   ClientCallTracer(
123       const grpc_core::Slice& path, grpc_core::Arena* arena,
124       bool registered_method, OpenTelemetryPluginImpl* otel_plugin,
125       std::shared_ptr<OpenTelemetryPluginImpl::ClientScopeConfig> scope_config);
126   ~ClientCallTracer() override;
127 
TraceId()128   std::string TraceId() override {
129     // Not implemented
130     return "";
131   }
132 
SpanId()133   std::string SpanId() override {
134     // Not implemented
135     return "";
136   }
137 
IsSampled()138   bool IsSampled() override {
139     // Not implemented
140     return false;
141   }
142 
143   CallAttemptTracer* StartNewAttempt(bool is_transparent_retry) override;
144   void RecordAnnotation(absl::string_view /*annotation*/) override;
145   void RecordAnnotation(const Annotation& /*annotation*/) override;
146 
147  private:
148   absl::string_view MethodForStats() const;
149 
150   // Client method.
151   grpc_core::Slice path_;
152   grpc_core::Arena* arena_;
153   const bool registered_method_;
154   OpenTelemetryPluginImpl* otel_plugin_;
155   std::shared_ptr<OpenTelemetryPluginImpl::ClientScopeConfig> scope_config_;
156   grpc_core::Mutex mu_;
157   // Non-transparent attempts per call
158   uint64_t retries_ ABSL_GUARDED_BY(&mu_) = 0;
159   // Transparent retries per call
160   uint64_t transparent_retries_ ABSL_GUARDED_BY(&mu_) = 0;
161 };
162 
163 }  // namespace internal
164 }  // namespace grpc
165 
166 #endif  // GRPC_SRC_CPP_EXT_OTEL_OTEL_CLIENT_CALL_TRACER_H
167