Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Increment the:

## [Unreleased]

* [OTLP/gRPC] Support VSOCK endpoints on Linux
[#4706](https://github.com/open-telemetry/opentelemetry-cpp/issues/4706)

* [SDK] `BatchLogRecordProcessor` now exports at most one batch on normal
wakeups instead of continuously draining the buffer, matching
`BatchSpanProcessor`
Expand Down
5 changes: 5 additions & 0 deletions exporters/otlp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ auto exporter = std::make_unique<otlp::OtlpFileExporter>(options);
|`metadata` |`OTEL_EXPORTER_OTLP_HEADERS` | | Custom metadata for GRPC |
| |`OTEL_EXPORTER_OTLP_TRACES_HEADERS` | | |

On Linux, the OTLP gRPC exporter supports VSOCK endpoints with gRPC 1.57.0 or
later. Set `vsock://<cid>:<port>` as the endpoint; the exporter converts it
to the `vsock:<cid>:<port>` target format expected by gRPC. A raw
`vsock:<cid>:<port>` target is also accepted.

### Configuration options ( OTLP HTTP Exporter )

| Option | Env Variable | Default | Description |
Expand Down
10 changes: 10 additions & 0 deletions exporters/otlp/src/otlp_grpc_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ OtlpGrpcClient::~OtlpGrpcClient()

std::string OtlpGrpcClient::GetGrpcTarget(const std::string &endpoint)
{
// A raw VSOCK target is already in the format expected by gRPC.
if (endpoint.rfind("vsock:", 0) == 0 && endpoint.rfind("vsock://", 0) != 0)
{
return endpoint;
}

//
// Scheme is allowed in OTLP endpoint definition, but is not allowed for creating gRPC
// channel. Passing URI with scheme to grpc::CreateChannel could resolve the endpoint to some
Expand All @@ -327,6 +333,10 @@ std::string OtlpGrpcClient::GetGrpcTarget(const std::string &endpoint)
{
grpc_target = "unix:" + url.path_;
}
else if (url.scheme_ == "vsock")
{
Comment thread
Amanpal9 marked this conversation as resolved.
Resolved
grpc_target = "vsock:" + url.host_ + ":" + std::to_string(url.port_);
}
else
{
grpc_target = url.host_ + ":" + std::to_string(static_cast<int>(url.port_));
Expand Down
7 changes: 7 additions & 0 deletions exporters/otlp/test/otlp_grpc_target_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ TEST(OtlpGrpcClientEndpointTest, GrpcClientTest)
EXPECT_EQ(target3, "localhost:4317");
}

TEST(OtlpGrpcClientEndpointTest, VsockEndpoints)
{
EXPECT_EQ(OtlpGrpcClient::GetGrpcTarget("vsock:3:1234"), "vsock:3:1234");
EXPECT_EQ(OtlpGrpcClient::GetGrpcTarget("vsock://3:1234"), "vsock:3:1234");
EXPECT_EQ(OtlpGrpcClient::GetGrpcTarget("vsock://3:100000"), "vsock:3:100000");
}

TEST_F(OtlpGrpcClientTestPeer, ChannelArgumentsOptionTest)
{
OtlpGrpcClientOptions options;
Expand Down
18 changes: 11 additions & 7 deletions ext/include/opentelemetry/ext/http/common/url_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <string>
#include <utility>

Expand All @@ -32,7 +33,7 @@ class UrlParser
std::string host_;
std::string scheme_;
std::string path_;
uint16_t port_{};
std::uint32_t port_{};
std::string query_;
bool success_{true};

Expand Down Expand Up @@ -171,18 +172,21 @@ class UrlParser
return std::string::npos;
}

std::uint16_t GetPort(const std::string &s)
std::uint32_t GetPort(const std::string &s)
{
char *e = nullptr;
errno = 0;
auto port = std::strtol(s.c_str(), &e, 10);
if (e == s.c_str() || e != s.c_str() + s.size() || errno == ERANGE || port < 0 || port > 65535)
char *e = nullptr;
errno = 0;
auto port = std::strtoull(s.c_str(), &e, 10);
auto max_port = scheme_ == "vsock" ? std::numeric_limits<std::uint32_t>::max()
: std::numeric_limits<std::uint16_t>::max();
if (e == s.c_str() || e != s.c_str() + s.size() || errno == ERANGE || s[0] == '-' ||
port > max_port)
{
success_ = false;
return 0;
}

return static_cast<uint16_t>(port);
return static_cast<std::uint32_t>(port);
}
};

Expand Down
8 changes: 6 additions & 2 deletions ext/test/http/url_parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct ParsedUrl
{
std::string scheme;
std::string host;
std::uint16_t port{};
std::uint32_t port{};
std::string path;
std::string query;
bool success{};
Expand Down Expand Up @@ -104,7 +104,11 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple("https://example.com:80a/some/path",
ParsedUrl{"https", "example.com", 0, "/some/path", "", false}),
std::make_tuple("https://example.com:18446744073709551616/some/path",
ParsedUrl{"https", "example.com", 0, "/some/path", "", false})));
ParsedUrl{"https", "example.com", 0, "/some/path", "", false}),
std::make_tuple("vsock://3:100000",
ParsedUrl{"vsock", "3", 100000, "/", "", true}),
std::make_tuple("vsock://3:4294967296",
ParsedUrl{"vsock", "3", 0, "/", "", false})));

TEST_P(UrlParserTests, BasicTests)
{
Expand Down
Loading