1 // Copyright 2023 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_PYTHON_OPENCENSUS_CLIENT_CALL_TRACER_H 16 #define GRPC_PYTHON_OPENCENSUS_CLIENT_CALL_TRACER_H 17 18 #include <stdint.h> 19 20 #include <string> 21 22 #include "absl/base/thread_annotations.h" 23 #include "absl/status/status.h" 24 #include "absl/strings/escaping.h" 25 #include "absl/strings/string_view.h" 26 #include "absl/time/time.h" 27 #include "python_census_context.h" 28 29 #include <grpc/support/time.h> 30 31 #include "src/core/lib/channel/call_tracer.h" 32 33 namespace grpc_observability { 34 35 class PythonOpenCensusCallTracer : public grpc_core::ClientCallTracer { 36 public: 37 class PythonOpenCensusCallAttemptTracer : public CallAttemptTracer { 38 public: 39 PythonOpenCensusCallAttemptTracer(PythonOpenCensusCallTracer* parent, 40 uint64_t attempt_num, 41 bool is_transparent_retry); TraceId()42 std::string TraceId() override { 43 return absl::BytesToHexString( 44 absl::string_view(context_.GetSpanContext().TraceId())); 45 } 46 SpanId()47 std::string SpanId() override { 48 return absl::BytesToHexString( 49 absl::string_view(context_.GetSpanContext().SpanId())); 50 } 51 IsSampled()52 bool IsSampled() override { return context_.GetSpanContext().IsSampled(); } 53 54 void RecordSendInitialMetadata( 55 grpc_metadata_batch* send_initial_metadata) override; RecordSendTrailingMetadata(grpc_metadata_batch *)56 void RecordSendTrailingMetadata( 57 grpc_metadata_batch* /*send_trailing_metadata*/) override {} 58 void RecordSendMessage( 59 const grpc_core::SliceBuffer& /*send_message*/) override; RecordSendCompressedMessage(const grpc_core::SliceBuffer &)60 void RecordSendCompressedMessage( 61 const grpc_core::SliceBuffer& /*send_compressed_message*/) override {} RecordReceivedInitialMetadata(grpc_metadata_batch *)62 void RecordReceivedInitialMetadata( 63 grpc_metadata_batch* /*recv_initial_metadata*/) override {} 64 void RecordReceivedMessage( 65 const grpc_core::SliceBuffer& /*recv_message*/) override; RecordReceivedDecompressedMessage(const grpc_core::SliceBuffer &)66 void RecordReceivedDecompressedMessage( 67 const grpc_core::SliceBuffer& /*recv_decompressed_message*/) override {} 68 void RecordReceivedTrailingMetadata( 69 absl::Status status, grpc_metadata_batch* recv_trailing_metadata, 70 const grpc_transport_stream_stats* transport_stream_stats) override; 71 void RecordCancel(grpc_error_handle cancel_error) override; 72 void RecordEnd(const gpr_timespec& /*latency*/) override; 73 void RecordAnnotation(absl::string_view annotation) override; 74 void RecordAnnotation(const Annotation& annotation) override; 75 std::shared_ptr<grpc_core::TcpTracerInterface> StartNewTcpTrace() override; SetOptionalLabel(OptionalLabelKey,grpc_core::RefCountedStringValue)76 void SetOptionalLabel(OptionalLabelKey /*key*/, 77 grpc_core::RefCountedStringValue /*value*/) override { 78 } 79 80 private: 81 // Maximum size of trace context is sent on the wire. 82 static constexpr uint32_t kMaxTraceContextLen = 64; 83 // Maximum size of tags that are sent on the wire. 84 static constexpr uint32_t kMaxTagsLen = 2048; 85 PythonOpenCensusCallTracer* parent_; 86 PythonCensusContext context_; 87 // Start time (for measuring latency). 88 absl::Time start_time_; 89 // Number of messages in this RPC. 90 uint64_t recv_message_count_ = 0; 91 uint64_t sent_message_count_ = 0; 92 // End status code 93 absl::StatusCode status_code_; 94 }; 95 96 explicit PythonOpenCensusCallTracer(const char* method, const char* target, 97 const char* trace_id, 98 const char* parent_span_id, 99 bool tracing_enabled); 100 ~PythonOpenCensusCallTracer() override; 101 TraceId()102 std::string TraceId() override { 103 return absl::BytesToHexString( 104 absl::string_view(context_.GetSpanContext().TraceId())); 105 } 106 SpanId()107 std::string SpanId() override { 108 return absl::BytesToHexString( 109 absl::string_view(context_.GetSpanContext().SpanId())); 110 } 111 IsSampled()112 bool IsSampled() override { return context_.GetSpanContext().IsSampled(); } 113 114 void GenerateContext(); 115 PythonOpenCensusCallAttemptTracer* StartNewAttempt( 116 bool is_transparent_retry) override; 117 118 void RecordAnnotation(absl::string_view annotation) override; 119 void RecordAnnotation(const Annotation& annotation) override; 120 121 private: 122 PythonCensusContext CreateCensusContextForCallAttempt(); 123 124 // Client method. 125 absl::string_view method_; 126 // Client target. 127 absl::string_view target_; 128 PythonCensusContext context_; 129 bool tracing_enabled_; 130 mutable grpc_core::Mutex mu_; 131 // Non-transparent attempts per call 132 uint64_t retries_ ABSL_GUARDED_BY(&mu_) = 0; 133 // Transparent retries per call 134 uint64_t transparent_retries_ ABSL_GUARDED_BY(&mu_) = 0; 135 // Retry delay 136 absl::Duration retry_delay_ ABSL_GUARDED_BY(&mu_); 137 absl::Time time_at_last_attempt_end_ ABSL_GUARDED_BY(&mu_); 138 uint64_t num_active_rpcs_ ABSL_GUARDED_BY(&mu_) = 0; 139 }; 140 141 } // namespace grpc_observability 142 143 #endif // GRPC_PYTHON_OPENCENSUS_CLIENT_CALL_TRACER_H 144