mirror of https://github.com/grpc/grpc.git
ObservabilityLogging: Add interface for logging and config parsing implementation for GCP observability (#31571)
* ObservabilityLogging: Add interface for logging and config parsing implementation for GCP observability * Trailing new lines * Fix naked include * clang-tidy * Reviewer comments * Reviewer commentspull/31602/head
parent
5dfd384655
commit
829f41b733
7 changed files with 599 additions and 0 deletions
@ -0,0 +1,47 @@ |
||||
# gRPC Bazel BUILD file. |
||||
# |
||||
# Copyright 2022 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. |
||||
|
||||
load( |
||||
"//bazel:grpc_build_system.bzl", |
||||
"grpc_cc_library", |
||||
) |
||||
|
||||
licenses(["reciprocal"]) |
||||
|
||||
package( |
||||
default_visibility = ["//visibility:public"], |
||||
features = [ |
||||
"layering_check", |
||||
], |
||||
) |
||||
|
||||
grpc_cc_library( |
||||
name = "logging_sink", |
||||
hdrs = [ |
||||
"logging_sink.h", |
||||
], |
||||
external_deps = [ |
||||
"absl/strings", |
||||
], |
||||
language = "c++", |
||||
visibility = [ |
||||
"//src/cpp/ext/gcp:__subpackages__", |
||||
"//test:__subpackages__", |
||||
], |
||||
deps = [ |
||||
"//:gpr_platform", |
||||
], |
||||
) |
@ -0,0 +1,61 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2022 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_INTERNAL_CPP_EXT_FILTERS_LOGGING_LOGGING_SINK_H |
||||
#define GRPC_INTERNAL_CPP_EXT_FILTERS_LOGGING_LOGGING_SINK_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "absl/strings/string_view.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
// Interface for a logging sink that will be used by the logging filter.
|
||||
class LoggingSink { |
||||
public: |
||||
class Config { |
||||
public: |
||||
Config(uint32_t max_metadata_bytes, uint32_t max_message_bytes) |
||||
: max_metadata_bytes_(max_metadata_bytes), |
||||
max_message_bytes_(max_message_bytes) {} |
||||
bool MetadataLoggingEnabled() { return max_metadata_bytes_ != 0; } |
||||
bool MessageLoggingEnabled() { return max_message_bytes_ != 0; } |
||||
bool ShouldLog() { |
||||
return MetadataLoggingEnabled() || MessageLoggingEnabled(); |
||||
} |
||||
|
||||
bool operator==(const Config& other) const { |
||||
return max_metadata_bytes_ == other.max_metadata_bytes_ && |
||||
max_message_bytes_ == other.max_message_bytes_; |
||||
} |
||||
|
||||
private: |
||||
uint32_t max_metadata_bytes_; |
||||
uint32_t max_message_bytes_; |
||||
}; |
||||
|
||||
virtual ~LoggingSink() = default; |
||||
|
||||
virtual Config FindMatch(bool is_client, absl::string_view path) = 0; |
||||
}; |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_INTERNAL_CPP_EXT_FILTERS_LOGGING_LOGGING_SINK_H
|
@ -0,0 +1,82 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2022 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 "src/cpp/ext/gcp/observability_logging_sink.h" |
||||
|
||||
#include <stddef.h> |
||||
|
||||
#include <algorithm> |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
ObservabilityLoggingSink::ObservabilityLoggingSink( |
||||
GcpObservabilityConfig::CloudLogging logging_config) { |
||||
for (auto& client_rpc_event_config : logging_config.client_rpc_events) { |
||||
client_configs.emplace_back(client_rpc_event_config); |
||||
} |
||||
for (auto& server_rpc_event_config : logging_config.server_rpc_events) { |
||||
server_configs.emplace_back(server_rpc_event_config); |
||||
} |
||||
} |
||||
|
||||
LoggingSink::Config ObservabilityLoggingSink::FindMatch( |
||||
bool is_client, absl::string_view path) { |
||||
size_t pos = path.find('/'); |
||||
if (pos == absl::string_view::npos) { |
||||
// bad path - did not find '/'
|
||||
return LoggingSink::Config(0, 0); |
||||
} |
||||
absl::string_view service = |
||||
path.substr(0, pos); // service name is before the '/'
|
||||
absl::string_view method = |
||||
path.substr(pos + 1); // method name starts after the '/'
|
||||
const auto& configs = is_client ? client_configs : server_configs; |
||||
for (const auto& config : configs) { |
||||
for (const auto& config_method : config.parsed_methods) { |
||||
if ((config_method.service == "*") || |
||||
((service == config_method.service) && |
||||
((config_method.method == "*") || |
||||
(method == config_method.method)))) { |
||||
if (config.exclude) { |
||||
return LoggingSink::Config(0, 0); |
||||
} |
||||
return LoggingSink::Config(config.max_metadata_bytes, |
||||
config.max_message_bytes); |
||||
} |
||||
} |
||||
} |
||||
return LoggingSink::Config(0, 0); |
||||
} |
||||
|
||||
ObservabilityLoggingSink::Configuration::Configuration( |
||||
const GcpObservabilityConfig::CloudLogging::RpcEventConfiguration& |
||||
rpc_event_config) |
||||
: exclude(rpc_event_config.exclude), |
||||
max_metadata_bytes(rpc_event_config.max_metadata_bytes), |
||||
max_message_bytes(rpc_event_config.max_message_bytes) { |
||||
for (auto& parsed_method : rpc_event_config.parsed_methods) { |
||||
parsed_methods.emplace_back(ParsedMethod{ |
||||
std::string(parsed_method.service), std::string(parsed_method.method)}); |
||||
} |
||||
} |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
@ -0,0 +1,70 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2022 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_INTERNAL_CPP_EXT_GCP_OBSERVABILITY_GCP_OBSERVABILITY_LOGGING_SINK_H |
||||
#define GRPC_INTERNAL_CPP_EXT_GCP_OBSERVABILITY_GCP_OBSERVABILITY_LOGGING_SINK_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include "absl/strings/string_view.h" |
||||
|
||||
#include "src/cpp/ext/filters/logging/logging_sink.h" |
||||
#include "src/cpp/ext/gcp/observability_config.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
// Interface for a logging sink that will be used by the logging filter.
|
||||
class ObservabilityLoggingSink : public LoggingSink { |
||||
public: |
||||
explicit ObservabilityLoggingSink( |
||||
GcpObservabilityConfig::CloudLogging logging_config); |
||||
|
||||
~ObservabilityLoggingSink() override = default; |
||||
|
||||
LoggingSink::Config FindMatch(bool is_client, |
||||
absl::string_view path) override; |
||||
|
||||
private: |
||||
struct Configuration { |
||||
explicit Configuration( |
||||
const GcpObservabilityConfig::CloudLogging::RpcEventConfiguration& |
||||
rpc_event_config); |
||||
struct ParsedMethod { |
||||
std::string service; |
||||
std::string method; |
||||
}; |
||||
std::vector<ParsedMethod> parsed_methods; |
||||
bool exclude = false; |
||||
uint32_t max_metadata_bytes = 0; |
||||
uint32_t max_message_bytes = 0; |
||||
}; |
||||
|
||||
std::vector<Configuration> client_configs; |
||||
std::vector<Configuration> server_configs; |
||||
}; |
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPC_INTERNAL_CPP_EXT_GCP_OBSERVABILITY_GCP_OBSERVABILITY_LOGGING_SINK_H
|
@ -0,0 +1,306 @@ |
||||
//
|
||||
// Copyright 2022 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 "src/cpp/ext/gcp/observability_logging_sink.h" |
||||
|
||||
#include "gmock/gmock.h" |
||||
#include "gtest/gtest.h" |
||||
|
||||
#include "test/core/util/test_config.h" |
||||
|
||||
namespace grpc { |
||||
namespace internal { |
||||
|
||||
namespace { |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigEmpty) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigClientWildCardEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"client_rpc_events": [ |
||||
{ |
||||
"methods": ["*"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigBadPath) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"client_rpc_events": [ |
||||
{ |
||||
"methods": ["*"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, |
||||
LoggingConfigClientWildCardServiceEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"client_rpc_events": [ |
||||
{ |
||||
"methods": ["service/*"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "service/bar"), |
||||
LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "service/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, |
||||
LoggingConfigClientMultipleMethodEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"client_rpc_events": [ |
||||
{ |
||||
"methods": ["foo/bar", "foo/baz"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/baz"), LoggingSink::Config(1024, 4096)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/baz"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigClientMultipleEventEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"client_rpc_events": [ |
||||
{ |
||||
"methods": ["foo/bar"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
}, |
||||
{ |
||||
"methods": ["foo/baz"], |
||||
"max_metadata_bytes": 512, |
||||
"max_message_bytes": 2048 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/baz"), LoggingSink::Config(512, 2048)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/baz"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigServerWildCardEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"server_rpc_events": [ |
||||
{ |
||||
"methods": ["*"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, |
||||
LoggingConfigServerWildCardServiceEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"server_rpc_events": [ |
||||
{ |
||||
"methods": ["service/*"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "service/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "service/bar"), |
||||
LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, |
||||
LoggingConfigServerMultipleMethodEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"server_rpc_events": [ |
||||
{ |
||||
"methods": ["foo/bar", "foo/baz"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/baz"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/baz"), LoggingSink::Config(1024, 4096)); |
||||
} |
||||
|
||||
TEST(GcpObservabilityLoggingSinkTest, LoggingConfigServerMultipleEventEntries) { |
||||
const char* json_str = R"json({ |
||||
"cloud_logging": { |
||||
"server_rpc_events": [ |
||||
{ |
||||
"methods": ["foo/bar"], |
||||
"max_metadata_bytes": 1024, |
||||
"max_message_bytes": 4096 |
||||
}, |
||||
{ |
||||
"methods": ["foo/baz"], |
||||
"max_metadata_bytes": 512, |
||||
"max_message_bytes": 2048 |
||||
} |
||||
] |
||||
} |
||||
})json"; |
||||
auto json = grpc_core::Json::Parse(json_str); |
||||
ASSERT_TRUE(json.ok()) << json.status(); |
||||
grpc_core::ValidationErrors errors; |
||||
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>( |
||||
*json, grpc_core::JsonArgs(), &errors); |
||||
ASSERT_TRUE(errors.ok()) << errors.status("unexpected errors"); |
||||
ObservabilityLoggingSink sink(config.cloud_logging.value()); |
||||
// client test
|
||||
EXPECT_EQ(sink.FindMatch(true, "foo/bar"), LoggingSink::Config(0, 0)); |
||||
EXPECT_EQ(sink.FindMatch(true, "foo/baz"), LoggingSink::Config(0, 0)); |
||||
// server test
|
||||
EXPECT_EQ(sink.FindMatch(false, "foo/bar"), LoggingSink::Config(1024, 4096)); |
||||
EXPECT_EQ(sink.FindMatch(false, "foo/baz"), LoggingSink::Config(512, 2048)); |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace internal
|
||||
} // namespace grpc
|
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc::testing::TestEnvironment env(&argc, argv); |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
Loading…
Reference in new issue