Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move env-var read logic to common dir, and optional reading of env-var #924

Merged
merged 9 commits into from
Aug 2, 2021
Merged
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
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,14 @@ option(WITH_ELASTICSEARCH

option(WITH_JAEGER "Whether to include the Jaeger exporter" OFF)

option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF)

option(BUILD_TESTING "Whether to enable tests" ON)

if(WITH_NO_GENENV)
add_definitions(-DNO_GETENV)
endif()

if(WIN32)
add_definitions(-DNOMINMAX)
if(BUILD_TESTING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,56 @@

#include "opentelemetry/sdk/trace/exporter.h"

#include "opentelemetry/sdk/common/env_variables.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace otlp
{

inline const std::string GetOtlpGrpcDefaultEndpoint()
{
constexpr char kOtlpGrpcEndpointEnv[] = "OTEL_EXPORTER_OTLP_GRPC_ENDPOINT";
constexpr char kOtlpGrpcEndpointDefault[] = "localhost:4317";

auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcEndpointEnv);
return endpoint.size() ? endpoint : kOtlpGrpcEndpointDefault;
}

inline const bool GetOtlpGrpcDefaultIsSslEnable()
{
constexpr char kOtlpGrpcIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE";
auto ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcIsSslEnableEnv);
if (ssl_enable == "True" || ssl_enable == "TRUE" || ssl_enable == "true" || ssl_enable == "1")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert it to lower case before comparison, to make the comparison case insensitive?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point will change that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I realize there is no method available in stdlib to perform this conversion. we have to iterate over the string to convert it. The existing comparison looks simple as compared to that :)

{
return true;
}
return false;
}

inline const std::string GetOtlpGrpcDefaultSslCertificate()
{
constexpr char kOtlpGrpcSslCertificate[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE";
auto ssl_cert = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpGrpcSslCertificate);
return ssl_cert.size() ? ssl_cert : "";
}

/**
* Struct to hold OTLP exporter options.
*/
struct OtlpGrpcExporterOptions
{
// The endpoint to export to. By default the OpenTelemetry Collector's default endpoint.
std::string endpoint = "localhost:4317";
std::string endpoint = GetOtlpGrpcDefaultEndpoint();
// By default when false, uses grpc::InsecureChannelCredentials(); If true,
// uses ssl_credentials_cacert_path if non-empty, else uses ssl_credentials_cacert_as_string
bool use_ssl_credentials = false;
bool use_ssl_credentials = GetOtlpGrpcDefaultIsSslEnable();
// ssl_credentials_cacert_path specifies path to .pem file to be used for SSL encryption.
std::string ssl_credentials_cacert_path = "";
// ssl_credentials_cacert_as_string in-memory string representation of .pem file to be used for
// SSL encryption.
std::string ssl_credentials_cacert_as_string = "";
std::string ssl_credentials_cacert_as_string = GetOtlpGrpcDefaultSslCertificate();
};

/**
Expand Down
32 changes: 32 additions & 0 deletions exporters/otlp/test/otlp_grpc_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,38 @@ TEST_F(OtlpGrpcExporterTestPeer, ConfigSslCredentialsTest)
EXPECT_EQ(GetOptions(exporter).ssl_credentials_cacert_as_string, cacert_str);
EXPECT_EQ(GetOptions(exporter).use_ssl_credentials, true);
}

# ifndef NO_GETENV
// Test exporter configuration options with use_ssl_credentials
TEST_F(OtlpGrpcExporterTestPeer, ConfigFromEnv)
{
const std::string cacert_str = "--begin and end fake cert--";
const std::string cacert_env = "OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE=" + cacert_str;
putenv(const_cast<char *>(cacert_env.data()));
char ssl_enable_env[] = "OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE=True";
putenv(ssl_enable_env);
const std::string endpoint = "http://localhost:9999";
const std::string endpoint_env = "OTEL_EXPORTER_OTLP_GRPC_ENDPOINT=" + endpoint;
putenv(const_cast<char *>(endpoint_env.data()));

std::unique_ptr<OtlpGrpcExporter> exporter(new OtlpGrpcExporter());
EXPECT_EQ(GetOptions(exporter).ssl_credentials_cacert_as_string, cacert_str);
EXPECT_EQ(GetOptions(exporter).use_ssl_credentials, true);
EXPECT_EQ(GetOptions(exporter).endpoint, endpoint);
# if defined(_MSC_VER)
putenv("OTEL_EXPORTER_OTLP_GRPC_ENDPOINT=");
putenv("OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE=");
putenv("OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE=");

# else
unsetenv("OTEL_EXPORTER_OTLP_GRPC_ENDPOINT");
unsetenv("OTEL_EXPORTER_OTLP_GRPC_SSL_CERTIFICATE");
unsetenv("OTEL_EXPORTER_OTLP_GRPC_SSL_ENABLE");

# endif
}
# endif

} // namespace otlp
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "opentelemetry/ext/http/client/http_client_factory.h"
#include "opentelemetry/ext/http/common/url_parser.h"
#include "opentelemetry/sdk/common/env_variables.h"
#include "opentelemetry/sdk/trace/exporter.h"
#include "opentelemetry/sdk/trace/span_data.h"

Expand All @@ -21,23 +22,9 @@ inline const std::string GetDefaultZipkinEndpoint()
const char *otel_exporter_zipkin_endpoint_env = "OTEL_EXPORTER_ZIPKIN_ENDPOINT";
const char *kZipkinEndpointDefault = "http://localhost:9411/api/v2/spans";

#if defined(_MSC_VER)
// avoid calling std::getenv which is deprecated in MSVC.
size_t required_size = 0;
getenv_s(&required_size, nullptr, 0, otel_exporter_zipkin_endpoint_env);
const char *endpoint_from_env = nullptr;
std::unique_ptr<char> endpoint_buffer;
if (required_size > 0)
{
endpoint_buffer = std::unique_ptr<char>{new char[required_size]};
getenv_s(&required_size, endpoint_buffer.get(), required_size,
otel_exporter_zipkin_endpoint_env);
endpoint_from_env = endpoint_buffer.get();
}
#else
auto endpoint_from_env = std::getenv(otel_exporter_zipkin_endpoint_env);
#endif
return std::string{endpoint_from_env ? endpoint_from_env : kZipkinEndpointDefault};
auto endpoint =
opentelemetry::sdk::common::GetEnvironmentVariable(otel_exporter_zipkin_endpoint_env);
return endpoint.size() ? endpoint : kZipkinEndpointDefault;
}

enum class TransportFormat
Expand Down
40 changes: 40 additions & 0 deletions sdk/include/opentelemetry/sdk/common/env_variables.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <string>
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace common
{

// Returns the env variable set.
inline const std::string GetEnvironmentVariable(const char *env_var_name)
{
const char *endpoint_from_env = nullptr;

#ifndef NO_GETENV
# if defined(_MSC_VER)
// avoid calling std::getenv which is deprecated in MSVC.
size_t required_size = 0;
getenv_s(&required_size, nullptr, 0, env_var_name);
std::unique_ptr<char> endpoint_buffer;
if (required_size > 0)
{
endpoint_buffer = std::unique_ptr<char>{new char[required_size]};
getenv_s(&required_size, endpoint_buffer.get(), required_size, env_var_name);
endpoint_from_env = endpoint_buffer.get();
}
# else
endpoint_from_env = std::getenv(env_var_name);
# endif
#endif
return endpoint_from_env == nullptr ? std::string() : endpoint_from_env;
}
} // namespace common
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
20 changes: 6 additions & 14 deletions sdk/src/resource/resource_detector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/sdk/resource/resource_detector.h"
#include <cstdlib>
#include "opentelemetry/sdk/common/env_variables.h"
#include "opentelemetry/sdk/resource/resource.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand All @@ -15,20 +15,12 @@ const char *OTEL_RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES";

Resource OTELResourceDetector::Detect() noexcept
{
#if defined(_MSC_VER)
size_t required_size = 0;
getenv_s(&required_size, nullptr, 0, OTEL_RESOURCE_ATTRIBUTES);
if (required_size == 0)
return Resource();
std::unique_ptr<char> attributes_buffer{new char[required_size]};
getenv_s(&required_size, attributes_buffer.get(), required_size, OTEL_RESOURCE_ATTRIBUTES);
char *attributes_str = attributes_buffer.get();
#else
char *attributes_str = std::getenv(OTEL_RESOURCE_ATTRIBUTES);
if (attributes_str == nullptr)
auto attributes_str =
opentelemetry::sdk::common::GetEnvironmentVariable(OTEL_RESOURCE_ATTRIBUTES);
if (attributes_str.size() == 0)
{
return Resource();
#endif

}
ResourceAttributes attributes;
std::istringstream iss(attributes_str);
std::string token;
Expand Down
14 changes: 8 additions & 6 deletions sdk/test/resource/resource_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ TEST(ResourceTest, MergeEmptyString)
EXPECT_EQ(received_attributes.size(), expected_attributes.size());
}

#ifndef NO_GETENV
TEST(ResourceTest, OtelResourceDetector)
{
std::map<std::string, std::string> expected_attributes = {{"k", "v"}};
Expand All @@ -175,21 +176,21 @@ TEST(ResourceTest, OtelResourceDetector)
}
}
EXPECT_EQ(received_attributes.size(), expected_attributes.size());
#if defined(_MSC_VER)
# if defined(_MSC_VER)
putenv("OTEL_RESOURCE_ATTRIBUTES=");
#else
# else
unsetenv("OTEL_RESOURCE_ATTRIBUTES");
#endif
# endif
}

TEST(ResourceTest, OtelResourceDetectorEmptyEnv)
{
std::map<std::string, std::string> expected_attributes = {};
#if defined(_MSC_VER)
# if defined(_MSC_VER)
putenv("OTEL_RESOURCE_ATTRIBUTES=");
#else
# else
unsetenv("OTEL_RESOURCE_ATTRIBUTES");
#endif
# endif
OTELResourceDetector detector;
auto resource = detector.Detect();
auto received_attributes = resource.GetAttributes();
Expand All @@ -204,3 +205,4 @@ TEST(ResourceTest, OtelResourceDetectorEmptyEnv)
}
EXPECT_EQ(received_attributes.size(), expected_attributes.size());
}
#endif