Skip to content

Commit c281184

Browse files
authored
[Geneva Metrics Exporter] - Add support for abstract socket (#264)
1 parent 1da2709 commit c281184

File tree

7 files changed

+650
-20
lines changed

7 files changed

+650
-20
lines changed

exporters/geneva/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,16 @@ if(BUILD_EXAMPLE)
9595
add_executable(example_metrics example/example_metrics.cc
9696
example/foo_library.cc)
9797
target_link_libraries(example_metrics opentelemetry_exporter_geneva_metrics)
98+
99+
add_executable(stress_test_linux example/stress_test_linux.cc)
100+
find_package(Boost QUIET)
101+
if(Boost_FOUND)
102+
include_directories(${Boost_INCLUDE_DIRS})
103+
target_compile_definitions(stress_test_linux PRIVATE HAVE_BOOST)
104+
endif()
105+
target_link_libraries(stress_test_linux opentelemetry_exporter_geneva_metrics)
98106
endif()
99107
if(MAIN_PROJECT AND BUILD_PACKAGE)
100108
include(cmake/package.cmake)
101109
include(CPack)
102-
endif()
110+
endif()

exporters/geneva/example/stress_test_linux.cc

Lines changed: 597 additions & 0 deletions
Large diffs are not rendered by default.

exporters/geneva/include/opentelemetry/exporters/geneva/metrics/connection_string_parser.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include "opentelemetry/exporters/geneva/metrics/macros.h"
77
#include "opentelemetry/exporters/geneva/metrics/socket_tools.h"
8-
#include "opentelemetry/ext/http/common/url_parser.h"
98
#include "opentelemetry/version.h"
109
#include <memory>
1110
#include <string>
@@ -26,8 +25,7 @@ class ConnectionStringParser {
2625

2726
public:
2827
ConnectionStringParser(const std::string &connection_string)
29-
: account_(""), namespace_(""),
30-
url_(nullptr), transport_protocol_{TransportProtocol::kUnknown} {
28+
: account_(""), namespace_(""), transport_protocol_{TransportProtocol::kUnknown} {
3129
std::string::size_type key_pos = 0;
3230
std::string::size_type key_end;
3331
std::string::size_type val_pos;
@@ -36,14 +34,16 @@ class ConnectionStringParser {
3634
while ((key_end = connection_string.find(kEqual, key_pos)) !=
3735
std::string::npos) {
3836
if ((val_pos = connection_string.find_first_not_of(kEqual, key_end)) ==
39-
std::string::npos) {
37+
std::string::npos)
38+
{
4039
break;
4140
}
4241
val_end = connection_string.find(kSemicolon, val_pos);
4342
auto key = connection_string.substr(key_pos, key_end - key_pos);
4443
auto value = connection_string.substr(val_pos, val_end - val_pos);
4544
key_pos = val_end;
46-
if (key_pos != std::string::npos) {
45+
if (key_pos != std::string::npos)
46+
{
4747
++key_pos;
4848
}
4949
if (key == kNamespace) {
@@ -52,22 +52,24 @@ class ConnectionStringParser {
5252
account_ = value;
5353
} else if (key == kEndpoint) {
5454
is_endpoint_found = true;
55-
url_ = std::unique_ptr<ext::http::common::UrlParser>(
56-
new ext::http::common::UrlParser(value));
57-
if (url_->success_) {
55+
size_t pos = value.find("://", 0);
56+
if (pos != std::string::npos)
57+
{
58+
auto scheme = std::string(value.begin(), value.begin() + pos);
59+
connection_string_ = value.substr(pos + strlen("://"));
5860
#ifdef HAVE_UNIX_DOMAIN
59-
if (url_->scheme_ == "unix") {
61+
if (scheme == "unix") {
6062
transport_protocol_ = TransportProtocol::kUNIX;
6163
}
6264
#else
63-
if (url_->scheme_ == "unix") {
65+
if (scheme == "unix") {
6466
LOG_ERROR("Unix domain socket not supported on this platform")
6567
}
6668
#endif
67-
if (url_->scheme_ == "tcp") {
69+
if (scheme == "tcp") {
6870
transport_protocol_ = TransportProtocol::kTCP;
6971
}
70-
if (url_->scheme_ == "udp") {
72+
if (scheme == "udp") {
7173
transport_protocol_ = TransportProtocol::kUDP;
7274
}
7375
}
@@ -84,8 +86,8 @@ class ConnectionStringParser {
8486

8587
std::string account_;
8688
std::string namespace_;
87-
std::unique_ptr<ext::http::common::UrlParser> url_;
8889
TransportProtocol transport_protocol_;
90+
std::string connection_string_;
8991
};
9092
} // namespace metrics
9193
} // namespace geneva

exporters/geneva/include/opentelemetry/exporters/geneva/metrics/socket_tools.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,15 @@ struct SocketAddr {
214214

215215
// Indicator that the sockaddr is sockaddr_un
216216
bool isUnixDomain;
217+
size_t abstract_socket_size;
217218

218219
/// <summary>
219220
/// SocketAddr constructor
220221
/// </summary>
221222
/// <returns>SocketAddr</returns>
222223
SocketAddr() {
223224
isUnixDomain = false;
225+
abstract_socket_size = 0;
224226
#ifdef HAVE_UNIX_DOMAIN
225227
memset(&m_data_un, 0, sizeof(m_data_un));
226228
#else
@@ -252,6 +254,12 @@ struct SocketAddr {
252254
// Max length of Unix domain filename is up to 108 chars
253255
strncpy_s(m_data_un.sun_path, sizeof(m_data_un.sun_path),
254256
unix_domain_path, sizeof(m_data_un.sun_path));
257+
// special handling for abstract socket - they should be
258+
// prefixed with '@' character.
259+
if (unix_domain_path[0] == '@') {
260+
m_data_un.sun_path[0] = '\0';
261+
abstract_socket_size = ipAddress.size();
262+
}
255263
return;
256264
}
257265
#endif
@@ -305,8 +313,10 @@ struct SocketAddr {
305313

306314
size_t size() const {
307315
#ifdef HAVE_UNIX_DOMAIN
308-
// Unix domain struct m_data_un
309-
if (isUnixDomain)
316+
if (isUnixDomain && abstract_socket_size)
317+
return sizeof(sa_family_t) + abstract_socket_size;
318+
else if(isUnixDomain)
319+
// Unix domain struct m_data_un
310320
return sizeof(m_data_un);
311321
#endif
312322
// IPv4 struct m_data_in

exporters/geneva/src/exporter.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Exporter::Exporter(const ExporterOptions &options)
2626
TransportProtocol::kUNIX) {
2727
data_transport_ =
2828
std::unique_ptr<DataTransport>(new UnixDomainSocketDataTransport(
29-
connection_string_parser_.url_->path_));
29+
connection_string_parser_.connection_string_));
3030
}
3131
#ifdef _WIN32
3232
else if (connection_string_parser_.transport_protocol_ ==

exporters/geneva/src/unix_domain_socket_data_transport.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ namespace geneva {
1010
namespace metrics {
1111

1212
UnixDomainSocketDataTransport::UnixDomainSocketDataTransport(
13-
const std::string &connection_string) {
13+
const std::string &connection_string)
14+
{
1415
addr_.reset(new SocketTools::SocketAddr(connection_string.c_str(), true));
1516
}
1617

exporters/geneva/test/metrics_exporter_test.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ using namespace kaitai;
1717
using namespace opentelemetry::sdk::metrics;
1818
using namespace opentelemetry::exporter::geneva::metrics;
1919

20-
const std::string kUnixDomainPath = "/tmp/ifx_unix_socket";
20+
std::string kUnixDomainPathUDS = "/tmp/ifx_unix_socket";
21+
std::string kUnixDomainPathAbstractSocket = "@/tmp/ifx_unix_socket";
22+
2123
const std::string kNamespaceName = "test_ns";
2224
const std::string kAccountName = "test_account";
2325

@@ -202,7 +204,12 @@ struct TestServer {
202204
}
203205
};
204206

205-
TEST(GenevaMetricsExporter, BasicTests) {
207+
class GenericMetricsExporterTextFixture: public ::testing::TestWithParam<std::string>
208+
{};
209+
210+
TEST_P(GenericMetricsExporterTextFixture, BasicTests) {
211+
212+
std::string kUnixDomainPath = GetParam();
206213
bool isRunning = true;
207214

208215
// Start test server
@@ -255,3 +262,8 @@ TEST(GenevaMetricsExporter, BasicTests) {
255262

256263
testServer.Stop();
257264
}
265+
266+
INSTANTIATE_TEST_SUITE_P(GenericMetricsExporterText, GenericMetricsExporterTextFixture,
267+
::testing::Values(kUnixDomainPathUDS, kUnixDomainPathAbstractSocket));
268+
269+

0 commit comments

Comments
 (0)