mirror of https://github.com/grpc/grpc.git
OpenCensus: Use new CallTracer interfaces (#32618)
This change mostly aims to get OpenCensus to use the new ServerCallTracer interface. Note that the interfaces nor the code are in their final states. There are a bunch of moving pieces, but I thought this might be a nice mid-step to check-in and make sure that our internal traces can also work with these changes. Overall changes - 1) call_tracer.h shows what the hierarchy of new call tracer interfaces looks like. Open to renaming suggestions. 2) Moved most of the common interface between `CallAttemptTracer` and `ServerCallTracer` into a common `CallTracerInterface`. We should be able to eventually move `RecordReceivedTrailingMetadata` and `RecordEnd` as well to these common interfaces, but it requires some additional work. 3) The compression filter is now responsible for recording the recv and send messages for both the subchannel call and the server, and adds in ability to record compressed and decompressed messages as well. 4) The OpenCensus server filter now uses the new `ServerCallTracer` interface, and so doesn't need to be a filter anymore. 5) A new ServerCallTracerFilter was added. Ideally, we should be able to move it to the current connected filter, but it is in a bit of an interesting state right now, so I would prefer making those changes in a separate PR with Craig's eyes on it. 6) A new context element `GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE` was created that replaces the old `GRPC_CONTEXT_CALL_TRACER`, and the new `GRPC_CONTEXT_CALL_TRACER` is mainly to pass the `CallAttemptTracer` down the stack. This should go away in the new promise-based world. <!-- 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. --> <!-- Reviewable:start --> - - - This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/grpc/grpc/32618) <!-- Reviewable:end -->pull/32359/head^2
parent
d025d50b54
commit
5029af9578
36 changed files with 508 additions and 440 deletions
@ -1,97 +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_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_H |
||||
#define GRPC_SRC_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "absl/status/status.h" |
||||
#include "absl/strings/string_view.h" |
||||
|
||||
#include <grpc/support/time.h> |
||||
|
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/iomgr/error.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 { |
||||
|
||||
// Interface for a tracer that records activities on a server call.
|
||||
class ServerCallTracer { |
||||
public: |
||||
virtual ~ServerCallTracer() {} |
||||
// 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; |
||||
// 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, uint32_t flags) = 0; |
||||
virtual void RecordReceivedMessage(const SliceBuffer& recv_message) = 0; |
||||
// 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( |
||||
absl::Status status, grpc_metadata_batch* recv_trailing_metadata, |
||||
const grpc_transport_stream_stats* transport_stream_stats) = 0; |
||||
virtual void RecordCancel(grpc_error_handle cancel_error) = 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; |
||||
// Records an annotation on the call attempt.
|
||||
// TODO(yashykt): If needed, extend this to attach attributes with
|
||||
// annotations.
|
||||
virtual void RecordAnnotation(absl::string_view annotation) = 0; |
||||
}; |
||||
|
||||
// Interface for a factory that can create a ServerCallTracer object per server
|
||||
// call.
|
||||
class ServerCallTracerFactory { |
||||
public: |
||||
struct RawPointerChannelArgTag {}; |
||||
|
||||
virtual ~ServerCallTracerFactory() {} |
||||
|
||||
virtual ServerCallTracer* CreateNewServerCallTracer() = 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 absl::string_view ChannelArgName(); |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_CHANNEL_SERVER_CALL_TRACER_H
|
@ -0,0 +1,110 @@ |
||||
//
|
||||
// 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 <functional> |
||||
#include <utility> |
||||
|
||||
#include "absl/status/status.h" |
||||
#include "absl/status/statusor.h" |
||||
|
||||
#include "src/core/lib/channel/call_finalization.h" |
||||
#include "src/core/lib/channel/call_tracer.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/channel/channel_fwd.h" |
||||
#include "src/core/lib/channel/channel_stack.h" |
||||
#include "src/core/lib/channel/channel_stack_builder.h" |
||||
#include "src/core/lib/channel/context.h" |
||||
#include "src/core/lib/channel/promise_based_filter.h" |
||||
#include "src/core/lib/config/core_configuration.h" |
||||
#include "src/core/lib/promise/arena_promise.h" |
||||
#include "src/core/lib/promise/cancel_callback.h" |
||||
#include "src/core/lib/promise/context.h" |
||||
#include "src/core/lib/promise/map.h" |
||||
#include "src/core/lib/promise/pipe.h" |
||||
#include "src/core/lib/promise/poll.h" |
||||
#include "src/core/lib/surface/channel_init.h" |
||||
#include "src/core/lib/surface/channel_stack_type.h" |
||||
#include "src/core/lib/transport/transport.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
namespace { |
||||
|
||||
// TODO(yashykt): This filter is not really needed. We should be able to move
|
||||
// this to the connected filter.
|
||||
class ServerCallTracerFilter : public ChannelFilter { |
||||
public: |
||||
static const grpc_channel_filter kFilter; |
||||
|
||||
static absl::StatusOr<ServerCallTracerFilter> Create( |
||||
const ChannelArgs& /*args*/, ChannelFilter::Args /*filter_args*/); |
||||
|
||||
ArenaPromise<ServerMetadataHandle> MakeCallPromise( |
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) override; |
||||
}; |
||||
|
||||
const grpc_channel_filter ServerCallTracerFilter::kFilter = |
||||
MakePromiseBasedFilter<ServerCallTracerFilter, FilterEndpoint::kServer, |
||||
kFilterExaminesServerInitialMetadata>( |
||||
"server_call_tracer"); |
||||
|
||||
absl::StatusOr<ServerCallTracerFilter> ServerCallTracerFilter::Create( |
||||
const ChannelArgs& /*args*/, ChannelFilter::Args /*filter_args*/) { |
||||
return ServerCallTracerFilter(); |
||||
} |
||||
|
||||
ArenaPromise<ServerMetadataHandle> ServerCallTracerFilter::MakeCallPromise( |
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) { |
||||
auto* call_context = GetContext<grpc_call_context_element>(); |
||||
auto* call_tracer = static_cast<ServerCallTracer*>( |
||||
call_context[GRPC_CONTEXT_CALL_TRACER].value); |
||||
if (call_tracer == nullptr) { |
||||
return next_promise_factory(std::move(call_args)); |
||||
} |
||||
call_tracer->RecordReceivedInitialMetadata( |
||||
call_args.client_initial_metadata.get()); |
||||
call_args.server_initial_metadata->InterceptAndMap( |
||||
[call_tracer](ServerMetadataHandle metadata) { |
||||
call_tracer->RecordSendInitialMetadata(metadata.get()); |
||||
return metadata; |
||||
}); |
||||
GetContext<CallFinalization>()->Add( |
||||
[call_tracer](const grpc_call_final_info* final_info) { |
||||
call_tracer->RecordEnd(final_info); |
||||
}); |
||||
return OnCancel( |
||||
Map(next_promise_factory(std::move(call_args)), |
||||
[call_tracer](ServerMetadataHandle md) { |
||||
call_tracer->RecordSendTrailingMetadata(md.get()); |
||||
return md; |
||||
}), |
||||
[call_tracer]() { call_tracer->RecordCancel(absl::CancelledError()); }); |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterServerCallTracerFilter(CoreConfiguration::Builder* builder) { |
||||
builder->channel_init()->RegisterStage( |
||||
GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, |
||||
[](ChannelStackBuilder* builder) { |
||||
builder->AppendFilter(&ServerCallTracerFilter::kFilter); |
||||
return true; |
||||
}); |
||||
} |
||||
|
||||
} // namespace grpc_core
|
@ -0,0 +1,40 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2018 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_FILTERS_CENSUS_SERVER_CALL_TRACER_H |
||||
#define GRPC_SRC_CPP_EXT_FILTERS_CENSUS_SERVER_CALL_TRACER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/channel/call_tracer.h" |
||||
#include "src/core/lib/resource_quota/arena.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
class OpenCensusServerCallTracerFactory |
||||
: public grpc_core::ServerCallTracerFactory { |
||||
public: |
||||
grpc_core::ServerCallTracer* CreateNewServerCallTracer( |
||||
grpc_core::Arena* arena) override; |
||||
}; |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CPP_EXT_FILTERS_CENSUS_SERVER_CALL_TRACER_H
|
@ -1,54 +0,0 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2018 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_FILTERS_CENSUS_SERVER_FILTER_H |
||||
#define GRPC_SRC_CPP_EXT_FILTERS_CENSUS_SERVER_FILTER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "absl/status/statusor.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" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
class OpenCensusServerFilter : public grpc_core::ChannelFilter { |
||||
public: |
||||
static const grpc_channel_filter kFilter; |
||||
|
||||
static absl::StatusOr<OpenCensusServerFilter> Create( |
||||
const grpc_core::ChannelArgs& /*args*/, |
||||
grpc_core::ChannelFilter::Args /*filter_args*/); |
||||
|
||||
grpc_core::ArenaPromise<grpc_core::ServerMetadataHandle> MakeCallPromise( |
||||
grpc_core::CallArgs call_args, |
||||
grpc_core::NextPromiseFactory next_promise_factory) override; |
||||
|
||||
private: |
||||
OpenCensusServerFilter() = default; |
||||
}; |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_SRC_CPP_EXT_FILTERS_CENSUS_SERVER_FILTER_H
|
Loading…
Reference in new issue