(Census client filter: use current span and tags. original_author=g-easy)

pull/21249/head
Alex Amato 5 years ago
parent 58e0fc8f08
commit 2e958cf01b
  1. 2
      BUILD
  2. 20
      bazel/grpc_deps.bzl
  3. 21
      src/cpp/ext/filters/census/client_filter.cc
  4. 17
      src/cpp/ext/filters/census/context.cc
  5. 28
      src/cpp/ext/filters/census/context.h
  6. 2
      test/cpp/ext/filters/census/BUILD
  7. 67
      test/cpp/ext/filters/census/stats_plugin_end2end_test.cc

@ -2300,7 +2300,9 @@ grpc_cc_library(
"absl-base",
"absl-time",
"opencensus-trace",
"opencensus-trace-context_util",
"opencensus-stats",
"opencensus-context",
],
language = "c++",
deps = [

@ -81,11 +81,21 @@ def grpc_deps():
actual = "@com_github_grpc_grpc//:grpc++_codegen_proto",
)
native.bind(
name = "opencensus-context",
actual = "@io_opencensus_cpp//opencensus/context:context",
)
native.bind(
name = "opencensus-trace",
actual = "@io_opencensus_cpp//opencensus/trace:trace",
)
native.bind(
name = "opencensus-trace-context_util",
actual = "@io_opencensus_cpp//opencensus/trace:context_util",
)
native.bind(
name = "opencensus-stats",
actual = "@io_opencensus_cpp//opencensus/stats:stats",
@ -96,6 +106,16 @@ def grpc_deps():
actual = "@io_opencensus_cpp//opencensus/stats:test_utils",
)
native.bind(
name = "opencensus-with-tag-map",
actual = "@io_opencensus_cpp//opencensus/tags:with_tag_map",
)
native.bind(
name = "opencensus-tags",
actual = "@io_opencensus_cpp//opencensus/tags:tags",
)
if "boringssl" not in native.existing_rules():
http_archive(
name = "boringssl",

@ -18,11 +18,17 @@
#include <grpc/support/port_platform.h>
#include <string>
#include <utility>
#include <vector>
#include "src/cpp/ext/filters/census/client_filter.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "opencensus/stats/stats.h"
#include "opencensus/tags/tag_key.h"
#include "opencensus/tags/tag_map.h"
#include "src/core/lib/surface/call.h"
#include "src/cpp/ext/filters/census/grpc_plugin.h"
#include "src/cpp/ext/filters/census/measures.h"
@ -152,6 +158,13 @@ void CensusClientCallData::Destroy(grpc_call_element* elem,
const uint64_t request_size = GetOutgoingDataSize(final_info);
const uint64_t response_size = GetIncomingDataSize(final_info);
double latency_ms = absl::ToDoubleMilliseconds(absl::Now() - start_time_);
std::vector<std::pair<opencensus::tags::TagKey, std::string>> tags =
context_.tags().tags();
std::string method = absl::StrCat(method_);
tags.emplace_back(ClientMethodTagKey(), method);
std::string final_status =
absl::StrCat(StatusCodeToString(final_info->final_status));
tags.emplace_back(ClientStatusTagKey(), final_status);
::opencensus::stats::Record(
{{RpcClientSentBytesPerRpc(), static_cast<double>(request_size)},
{RpcClientReceivedBytesPerRpc(), static_cast<double>(response_size)},
@ -160,9 +173,13 @@ void CensusClientCallData::Destroy(grpc_call_element* elem,
ToDoubleMilliseconds(absl::Nanoseconds(elapsed_time_))},
{RpcClientSentMessagesPerRpc(), sent_message_count_},
{RpcClientReceivedMessagesPerRpc(), recv_message_count_}},
{{ClientMethodTagKey(), method_},
{ClientStatusTagKey(), StatusCodeToString(final_info->final_status)}});
tags);
grpc_slice_unref_internal(path_);
if (final_info->final_status != GRPC_STATUS_OK) {
// TODO: Map grpc_status_code to trace::StatusCode.
context_.Span().SetStatus(opencensus::trace::StatusCode::UNKNOWN,
StatusCodeToString(final_info->final_status));
}
context_.EndSpan();
}

@ -18,10 +18,13 @@
#include <grpc/support/port_platform.h>
#include "opencensus/tags/context_util.h"
#include "opencensus/trace/context_util.h"
#include "src/cpp/ext/filters/census/context.h"
namespace grpc {
using ::opencensus::tags::TagMap;
using ::opencensus::trace::Span;
using ::opencensus::trace::SpanContext;
@ -40,7 +43,7 @@ void GenerateServerContext(absl::string_view tracing, absl::string_view stats,
return;
}
}
new (context) CensusContext(method);
new (context) CensusContext(method, TagMap{});
}
void GenerateClientContext(absl::string_view method, CensusContext* ctxt,
@ -52,11 +55,19 @@ void GenerateClientContext(absl::string_view method, CensusContext* ctxt,
SpanContext span_ctxt = parent_ctxt->Context();
Span span = parent_ctxt->Span();
if (span_ctxt.IsValid()) {
new (ctxt) CensusContext(method, &span);
new (ctxt) CensusContext(method, &span, TagMap{});
return;
}
}
new (ctxt) CensusContext(method);
const Span& span = opencensus::trace::GetCurrentSpan();
const TagMap& tags = opencensus::tags::GetCurrentTagMap();
if (span.context().IsValid()) {
// Create span with parent.
new (ctxt) CensusContext(method, &span, tags);
return;
}
// Create span without parent.
new (ctxt) CensusContext(method, tags);
}
size_t TraceContextSerialize(const ::opencensus::trace::SpanContext& context,

@ -25,6 +25,9 @@
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "opencensus/context/context.h"
#include "opencensus/tags/tag_map.h"
#include "opencensus/trace/context_util.h"
#include "opencensus/trace/span.h"
#include "opencensus/trace/span_context.h"
#include "opencensus/trace/trace_params.h"
@ -41,25 +44,32 @@ namespace grpc {
// Thread compatible.
class CensusContext {
public:
CensusContext() : span_(::opencensus::trace::Span::BlankSpan()) {}
CensusContext() : span_(::opencensus::trace::Span::BlankSpan()), tags_({}) {}
explicit CensusContext(absl::string_view name)
: span_(::opencensus::trace::Span::StartSpan(name)) {}
explicit CensusContext(absl::string_view name,
const ::opencensus::tags::TagMap& tags)
: span_(::opencensus::trace::Span::StartSpan(name)), tags_(tags) {}
CensusContext(absl::string_view name, const ::opencensus::trace::Span* parent)
: span_(::opencensus::trace::Span::StartSpan(name, parent)) {}
CensusContext(absl::string_view name, const ::opencensus::trace::Span* parent,
const ::opencensus::tags::TagMap& tags)
: span_(::opencensus::trace::Span::StartSpan(name, parent)),
tags_(tags) {}
CensusContext(absl::string_view name,
const ::opencensus::trace::SpanContext& parent_ctxt)
: span_(::opencensus::trace::Span::StartSpanWithRemoteParent(
name, parent_ctxt)) {}
name, parent_ctxt)),
tags_({}) {}
::opencensus::trace::SpanContext Context() const { return span_.context(); }
::opencensus::trace::Span Span() const { return span_; }
void EndSpan() { span_.End(); }
const ::opencensus::trace::Span& Span() const { return span_; }
const ::opencensus::tags::TagMap& tags() const { return tags_; }
::opencensus::trace::SpanContext Context() const { return Span().context(); }
void EndSpan() { Span().End(); }
private:
::opencensus::trace::Span span_;
::opencensus::tags::TagMap tags_;
};
// Serializes the outgoing trace context. Field IDs are 1 byte followed by

@ -27,6 +27,8 @@ grpc_cc_test(
external_deps = [
"gtest",
"opencensus-stats-test",
"opencensus-tags",
"opencensus-with-tag-map",
],
language = "C++",
tags = ["no_windows"], # TODO(jtattermusch): fix test on windows

@ -27,7 +27,10 @@
#include "include/grpc++/grpc++.h"
#include "include/grpcpp/opencensus.h"
#include "opencensus/stats/stats.h"
#include "opencensus/stats/tag_key.h"
#include "opencensus/stats/testing/test_utils.h"
#include "opencensus/tags/tag_map.h"
#include "opencensus/tags/with_tag_map.h"
#include "src/cpp/ext/filters/census/grpc_plugin.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/test_config.h"
@ -41,6 +44,12 @@ using ::opencensus::stats::Distribution;
using ::opencensus::stats::View;
using ::opencensus::stats::ViewDescriptor;
using ::opencensus::stats::testing::TestUtils;
using ::opencensus::tags::TagKey;
using ::opencensus::tags::TagMap;
using ::opencensus::tags::WithTagMap;
static const auto TEST_TAG_KEY = TagKey::Register("my_key");
static const auto TEST_TAG_VALUE = "my_value";
class EchoServer final : public EchoTestService::Service {
::grpc::Status Echo(::grpc::ServerContext* context,
@ -104,7 +113,8 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
.set_measure(kRpcClientRoundtripLatencyMeasureName)
.set_name("client_method")
.set_aggregation(Aggregation::Count())
.add_column(ClientMethodTagKey());
.add_column(ClientMethodTagKey())
.add_column(TEST_TAG_KEY);
View client_method_view(client_method_descriptor);
const auto server_method_descriptor =
ViewDescriptor()
@ -112,6 +122,7 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
.set_name("server_method")
.set_aggregation(Aggregation::Count())
.add_column(ServerMethodTagKey());
//.add_column(TEST_TAG_KEY);
View server_method_view(server_method_descriptor);
const auto client_status_descriptor =
@ -119,7 +130,8 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
.set_measure(kRpcClientRoundtripLatencyMeasureName)
.set_name("client_status")
.set_aggregation(Aggregation::Count())
.add_column(ClientStatusTagKey());
.add_column(ClientStatusTagKey())
.add_column(TEST_TAG_KEY);
View client_status_view(client_status_descriptor);
const auto server_status_descriptor =
ViewDescriptor()
@ -136,19 +148,56 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
request.mutable_param()->mutable_expected_error()->set_code(i);
EchoResponse response;
::grpc::ClientContext context;
::grpc::Status status = stub_->Echo(&context, request, &response);
{
WithTagMap tags({{TEST_TAG_KEY, TEST_TAG_VALUE}});
::grpc::Status status = stub_->Echo(&context, request, &response);
}
}
absl::SleepFor(absl::Milliseconds(500));
TestUtils::Flush();
EXPECT_THAT(client_method_view.GetData().int_data(),
::testing::UnorderedElementsAre(::testing::Pair(
::testing::ElementsAre(client_method_name_), 17)));
// Client side views can be tagged with custom tags.
EXPECT_THAT(
client_method_view.GetData().int_data(),
::testing::UnorderedElementsAre(::testing::Pair(
::testing::ElementsAre(client_method_name_, TEST_TAG_VALUE), 17)));
// TODO: Implement server view tagging with custom tags.
EXPECT_THAT(server_method_view.GetData().int_data(),
::testing::UnorderedElementsAre(::testing::Pair(
::testing::ElementsAre(server_method_name_), 17)));
auto codes = {
// Client side views can be tagged with custom tags.
auto client_tags = {
::testing::Pair(::testing::ElementsAre("OK", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("CANCELLED", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("UNKNOWN", TEST_TAG_VALUE), 1),
::testing::Pair(
::testing::ElementsAre("INVALID_ARGUMENT", TEST_TAG_VALUE), 1),
::testing::Pair(
::testing::ElementsAre("DEADLINE_EXCEEDED", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("NOT_FOUND", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("ALREADY_EXISTS", TEST_TAG_VALUE),
1),
::testing::Pair(
::testing::ElementsAre("PERMISSION_DENIED", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("UNAUTHENTICATED", TEST_TAG_VALUE),
1),
::testing::Pair(
::testing::ElementsAre("RESOURCE_EXHAUSTED", TEST_TAG_VALUE), 1),
::testing::Pair(
::testing::ElementsAre("FAILED_PRECONDITION", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("ABORTED", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("OUT_OF_RANGE", TEST_TAG_VALUE),
1),
::testing::Pair(::testing::ElementsAre("UNIMPLEMENTED", TEST_TAG_VALUE),
1),
::testing::Pair(::testing::ElementsAre("INTERNAL", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("UNAVAILABLE", TEST_TAG_VALUE), 1),
::testing::Pair(::testing::ElementsAre("DATA_LOSS", TEST_TAG_VALUE), 1),
};
// TODO: Implement server view tagging with custom tags.
auto server_tags = {
::testing::Pair(::testing::ElementsAre("OK"), 1),
::testing::Pair(::testing::ElementsAre("CANCELLED"), 1),
::testing::Pair(::testing::ElementsAre("UNKNOWN"), 1),
@ -169,9 +218,9 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
};
EXPECT_THAT(client_status_view.GetData().int_data(),
::testing::UnorderedElementsAreArray(codes));
::testing::UnorderedElementsAreArray(client_tags));
EXPECT_THAT(server_status_view.GetData().int_data(),
::testing::UnorderedElementsAreArray(codes));
::testing::UnorderedElementsAreArray(server_tags));
}
TEST_F(StatsPluginEnd2EndTest, RequestReceivedBytesPerRpc) {

Loading…
Cancel
Save