1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
//
//
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#ifndef GRPC_SRC_CORE_LIB_CHANNEL_CALL_TRACER_H
#define GRPC_SRC_CORE_LIB_CHANNEL_CALL_TRACER_H
#include <grpc/support/port_platform.h>
#include <util/generic/string.h>
#include <util/string/cast.h>
#include "y_absl/status/status.h"
#include "y_absl/strings/string_view.h"
#include <grpc/support/time.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.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"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
// The interface hierarchy is as follows -
// CallTracerAnnotationInterface
// / \
// ClientCallTracer CallTracerInterface
// / \
// CallAttemptTracer ServerCallTracer
// The base class for all tracer implementations.
class CallTracerAnnotationInterface {
public:
virtual ~CallTracerAnnotationInterface() {}
// Records an annotation on the call attempt.
// TODO(yashykt): If needed, extend this to attach attributes with
// annotations.
virtual void RecordAnnotation(y_absl::string_view annotation) = 0;
virtual TString TraceId() = 0;
virtual TString SpanId() = 0;
virtual bool IsSampled() = 0;
};
// The base class for CallAttemptTracer and ServerCallTracer.
// TODO(yashykt): What's a better name for this?
class CallTracerInterface : public CallTracerAnnotationInterface {
public:
~CallTracerInterface() override {}
// Please refer to `grpc_transport_stream_op_batch_payload` for details on
// arguments.
virtual void RecordSendInitialMetadata(
grpc_metadata_batch* send_initial_metadata) = 0;
virtual void RecordSendTrailingMetadata(
grpc_metadata_batch* send_trailing_metadata) = 0;
virtual void RecordSendMessage(const SliceBuffer& send_message) = 0;
// Only invoked if message was actually compressed.
virtual void RecordSendCompressedMessage(
const SliceBuffer& send_compressed_message) = 0;
// The `RecordReceivedInitialMetadata()` and `RecordReceivedMessage()`
// methods should only be invoked when the metadata/message was
// successfully received, i.e., without any error.
virtual void RecordReceivedInitialMetadata(
grpc_metadata_batch* recv_initial_metadata) = 0;
virtual void RecordReceivedMessage(const SliceBuffer& recv_message) = 0;
// Only invoked if message was actually decompressed.
virtual void RecordReceivedDecompressedMessage(
const SliceBuffer& recv_decompressed_message) = 0;
virtual void RecordCancel(grpc_error_handle cancel_error) = 0;
};
// Interface for a tracer that records activities on a call. Actual attempts for
// this call are traced with CallAttemptTracer after invoking RecordNewAttempt()
// on the ClientCallTracer object.
class ClientCallTracer : public CallTracerAnnotationInterface {
public:
// Interface for a tracer that records activities on a particular call
// attempt.
// (A single RPC can have multiple attempts due to retry/hedging policies or
// as transparent retry attempts.)
class CallAttemptTracer : public CallTracerInterface {
public:
~CallAttemptTracer() override {}
// TODO(yashykt): The following two methods `RecordReceivedTrailingMetadata`
// and `RecordEnd` should be moved into CallTracerInterface.
// If the call was cancelled before the recv_trailing_metadata op
// was started, recv_trailing_metadata and transport_stream_stats
// will be null.
virtual void RecordReceivedTrailingMetadata(
y_absl::Status status, grpc_metadata_batch* recv_trailing_metadata,
const grpc_transport_stream_stats* transport_stream_stats) = 0;
// Should be the last API call to the object. Once invoked, the tracer
// library is free to destroy the object.
virtual void RecordEnd(const gpr_timespec& latency) = 0;
};
~ClientCallTracer() override {}
// Records a new attempt for the associated call. \a transparent denotes
// whether the attempt is being made as a transparent retry or as a
// non-transparent retry/heding attempt. (There will be at least one attempt
// even if the call is not being retried.) The `ClientCallTracer` object
// retains ownership to the newly created `CallAttemptTracer` object.
// RecordEnd() serves as an indication that the call stack is done with all
// API calls, and the tracer library is free to destroy it after that.
virtual CallAttemptTracer* StartNewAttempt(bool is_transparent_retry) = 0;
};
// Interface for a tracer that records activities on a server call.
class ServerCallTracer : public CallTracerInterface {
public:
~ServerCallTracer() override {}
// TODO(yashykt): The following two methods `RecordReceivedTrailingMetadata`
// and `RecordEnd` should be moved into CallTracerInterface.
virtual void RecordReceivedTrailingMetadata(
grpc_metadata_batch* recv_trailing_metadata) = 0;
// Should be the last API call to the object. Once invoked, the tracer
// library is free to destroy the object.
virtual void RecordEnd(const grpc_call_final_info* final_info) = 0;
};
// Interface for a factory that can create a ServerCallTracer object per
// server call.
class ServerCallTracerFactory {
public:
struct RawPointerChannelArgTag {};
virtual ~ServerCallTracerFactory() {}
virtual ServerCallTracer* CreateNewServerCallTracer(Arena* arena) = 0;
// Use this method to get the server call tracer factory from channel args,
// instead of directly fetching it with `GetObject`.
static ServerCallTracerFactory* Get(const ChannelArgs& channel_args);
// Registers a global ServerCallTracerFactory that wil be used by default if
// no corresponding channel arg was found. It is only valid to call this
// before grpc_init(). It is the responsibility of the caller to maintain
// this for the lifetime of the process.
static void RegisterGlobal(ServerCallTracerFactory* factory);
static y_absl::string_view ChannelArgName();
};
void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder);
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_CHANNEL_CALL_TRACER_H
|