Skip to content

Commit 269ff8f

Browse files
committed
1. Add otlp_environment.h to maintain shared codes of OtlpGrpcExporter and OtlpHttpExporter
2. Add `timeout` and `metadata` options for `OtlpGrpcExporter` 3. Load environment variables `OTEL_EXPORTER_OTLP_TIMEOUT` , `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` , `OTEL_EXPORTER_OTLP_HEADERS` , `OTEL_EXPORTER_OTLP_TRACES_HEADERS` to initialize default options of `OtlpGrpcExporter` and `OtlpHttpExporter` 4. Load environment variables `OTEL_EXPORTER_OTLP_ENDPOINT` , `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` to initialize default options of `OtlpHttpExporter` Signed-off-by: owentou <[email protected]>
1 parent 74d4be4 commit 269ff8f

10 files changed

+354
-80
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Increment the:
1515

1616
## [Unreleased]
1717

18+
* Support environment variables for both `OtlpGrpcExporter` and `OtlpHttpExporter` ([#983](https://github.com/open-telemetry/opentelemetry-cpp/pull/983))
19+
1820
## [1.0.0] 2021-09-16
1921

2022
### API

exporters/otlp/BUILD

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ cc_library(
4040
"src/otlp_grpc_exporter.cc",
4141
],
4242
hdrs = [
43+
"include/opentelemetry/exporters/otlp/otlp_environment.h",
4344
"include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h",
4445
"include/opentelemetry/exporters/otlp/protobuf_include_prefix.h",
4546
"include/opentelemetry/exporters/otlp/protobuf_include_suffix.h",
@@ -61,6 +62,7 @@ cc_library(
6162
"src/otlp_http_exporter.cc",
6263
],
6364
hdrs = [
65+
"include/opentelemetry/exporters/otlp/otlp_environment.h",
6466
"include/opentelemetry/exporters/otlp/otlp_http_exporter.h",
6567
"include/opentelemetry/exporters/otlp/protobuf_include_prefix.h",
6668
"include/opentelemetry/exporters/otlp/protobuf_include_suffix.h",

exporters/otlp/README.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,24 @@ auto exporter = std::unique_ptr<sdktrace::SpanExporter>(new otlp::OtlpHttpExport
5454
| | `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | | |
5555
| `ssl_credentials_cacert_as_string` | `OTEL_EXPORTER_OTLP_CERTIFICATE_STRING` | `""` | SSL Certifcate as in-memory string |
5656
| | `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE_STRING` | | | |
57+
| `timeout` | `OTEL_EXPORTER_OTLP_TIMEOUT` | `10s` | GRPC deadline |
58+
| | `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | | |
59+
| `metadata` | `OTEL_EXPORTER_OTLP_HEADERS` | | Custom metadata for GRPC |
60+
| | `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | | |
5761

5862
### Configuration options ( OTLP HTTP Exporter )
5963

6064
| Option | Env Variable |Default | Description |
6165
| ------------ |-----|------------ |------|
62-
| `url` | n/a | `http://localhost:4317/v1/traces` | The OTLP HTTP endpoint to connect to |
66+
| `url` | `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4317/v1/traces` | The OTLP HTTP endpoint to connect to |
67+
| | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | | |
6368
| `content_type` | n/a | `application/json` | Data format used - JSON or Binary |
6469
| `json_bytes_mapping` | n/a | `JsonBytesMappingKind::kHexId` | Encoding used for trace_id and span_id |
6570
| `use_json_name` | n/a | `false` | Whether to use json name of protobuf field to set the key of json |
66-
| `timeout` | n/a | `30000 ms` | http timeout |
71+
| `timeout` | `OTEL_EXPORTER_OTLP_TIMEOUT` | `10s` | http timeout |
72+
| | `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | |
73+
| `http_headers` | `OTEL_EXPORTER_OTLP_HEADERS` | | http headers |
74+
| | `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | | |
6775

6876
## Example
6977

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#pragma once
5+
6+
#include <algorithm>
7+
#include <chrono>
8+
#include <map>
9+
#include <string>
10+
11+
#include "opentelemetry/nostd/string_view.h"
12+
13+
#include "opentelemetry/sdk/common/attribute_utils.h"
14+
#include "opentelemetry/sdk/common/env_variables.h"
15+
16+
OPENTELEMETRY_BEGIN_NAMESPACE
17+
namespace exporter
18+
{
19+
namespace otlp
20+
{
21+
22+
inline const std::string GetOtlpDefaultGrpcEndpoint()
23+
{
24+
constexpr char kOtlpTracesEndpointEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
25+
constexpr char kOtlpEndpointEnv[] = "OTEL_EXPORTER_OTLP_ENDPOINT";
26+
constexpr char kOtlpEndpointDefault[] = "http://localhost:4317";
27+
28+
auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesEndpointEnv);
29+
if (endpoint.empty())
30+
{
31+
endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpEndpointEnv);
32+
}
33+
return endpoint.size() ? endpoint : kOtlpEndpointDefault;
34+
}
35+
36+
inline const std::string GetOtlpDefaultHttpEndpoint()
37+
{
38+
constexpr char kOtlpTracesEndpointEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
39+
constexpr char kOtlpEndpointEnv[] = "OTEL_EXPORTER_OTLP_ENDPOINT";
40+
constexpr char kOtlpEndpointDefault[] = "http://localhost:4317/v1/traces";
41+
42+
auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesEndpointEnv);
43+
if (endpoint.empty())
44+
{
45+
endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpEndpointEnv);
46+
}
47+
return endpoint.size() ? endpoint : kOtlpEndpointDefault;
48+
}
49+
50+
inline const bool GetOtlpDefaultIsSslEnable()
51+
{
52+
constexpr char kOtlpTracesIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_TRACES_SSL_ENABLE";
53+
constexpr char kOtlpIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_SSL_ENABLE";
54+
55+
auto ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesIsSslEnableEnv);
56+
if (ssl_enable.empty())
57+
{
58+
ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpIsSslEnableEnv);
59+
}
60+
if (ssl_enable == "True" || ssl_enable == "TRUE" || ssl_enable == "true" || ssl_enable == "1")
61+
{
62+
return true;
63+
}
64+
return false;
65+
}
66+
67+
inline const std::string GetOtlpDefaultSslCertificatePath()
68+
{
69+
constexpr char kOtlpTracesSslCertificate[] = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE";
70+
constexpr char kOtlpSslCertificate[] = "OTEL_EXPORTER_OTLP_CERTIFICATE ";
71+
auto ssl_cert_path =
72+
opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesSslCertificate);
73+
if (ssl_cert_path.empty())
74+
{
75+
ssl_cert_path = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpSslCertificate);
76+
}
77+
return ssl_cert_path.size() ? ssl_cert_path : "";
78+
}
79+
80+
inline const std::string GetOtlpDefaultSslCertificateString()
81+
{
82+
constexpr char kOtlpTracesSslCertificateString[] = "OTEL_EXPORTER_OTLP_CERTIFICATE_STRING";
83+
constexpr char kOtlpSslCertificateString[] = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE_STRING ";
84+
auto ssl_cert =
85+
opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesSslCertificateString);
86+
if (ssl_cert.empty())
87+
{
88+
ssl_cert = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpSslCertificateString);
89+
}
90+
return ssl_cert.size() ? ssl_cert : "";
91+
}
92+
93+
inline const std::chrono::system_clock::duration GetOtlpTimeoutFromString(const char *input)
94+
{
95+
if (nullptr == input || 0 == *input)
96+
{
97+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
98+
std::chrono::seconds{10});
99+
}
100+
101+
std::chrono::system_clock::duration::rep result = 0;
102+
// Skip spaces
103+
for (; *input && (' ' == *input || '\t' == *input || '\r' == *input || '\n' == *input); ++input)
104+
;
105+
106+
for (; *input && (*input >= '0' && *input <= '9'); ++input)
107+
{
108+
result = result * 10 + (*input - '0');
109+
}
110+
111+
opentelemetry::nostd::string_view unit{input};
112+
if ("ns" == unit)
113+
{
114+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
115+
std::chrono::nanoseconds{result});
116+
}
117+
else if ("us" == unit)
118+
{
119+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
120+
std::chrono::microseconds{result});
121+
}
122+
else if ("ms" == unit)
123+
{
124+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
125+
std::chrono::milliseconds{result});
126+
}
127+
else if ("m" == unit)
128+
{
129+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
130+
std::chrono::minutes{result});
131+
}
132+
else if ("h" == unit)
133+
{
134+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
135+
std::chrono::hours{result});
136+
}
137+
else
138+
{
139+
return std::chrono::duration_cast<std::chrono::system_clock::duration>(
140+
std::chrono::seconds{result});
141+
}
142+
}
143+
144+
inline const std::chrono::system_clock::duration GetOtlpDefaultTimeout()
145+
{
146+
constexpr char kOtlpTracesTimeoutEnv[] = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";
147+
constexpr char kOtlpTimeoutEnv[] = "OTEL_EXPORTER_OTLP_TIMEOUT";
148+
149+
auto timeout = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesTimeoutEnv);
150+
if (timeout.empty())
151+
{
152+
timeout = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTimeoutEnv);
153+
}
154+
return GetOtlpTimeoutFromString(timeout.c_str());
155+
}
156+
157+
struct cmp_ic
158+
{
159+
bool operator()(const std::string &s1, const std::string &s2) const
160+
{
161+
return std::lexicographical_compare(
162+
s1.begin(), s1.end(), s2.begin(), s2.end(),
163+
[](char c1, char c2) { return ::tolower(c1) < ::tolower(c2); });
164+
}
165+
};
166+
using OtlpHeaders = std::multimap<std::string, std::string, cmp_ic>;
167+
168+
inline void DumpOtlpHeaders(OtlpHeaders &output, const char *env_var_name)
169+
{
170+
auto value = opentelemetry::sdk::common::GetEnvironmentVariable(env_var_name);
171+
if (value.empty())
172+
{
173+
return;
174+
}
175+
176+
opentelemetry::common::KeyValueStringTokenizer tokenizer{value};
177+
opentelemetry::nostd::string_view header_key;
178+
opentelemetry::nostd::string_view header_value;
179+
bool header_valid = true;
180+
181+
while (tokenizer.next(header_valid, header_key, header_value))
182+
{
183+
if (header_valid)
184+
{
185+
output.emplace(std::make_pair((std::string)header_key, (std::string)header_value));
186+
}
187+
}
188+
}
189+
190+
inline OtlpHeaders GetOtlpDefaultHeaders()
191+
{
192+
constexpr char kOtlpTracesHeadersEnv[] = "OTEL_EXPORTER_OTLP_TRACES_HEADERS";
193+
constexpr char kOtlpHeadersEnv[] = "OTEL_EXPORTER_OTLP_HEADERS";
194+
195+
OtlpHeaders result;
196+
DumpOtlpHeaders(result, kOtlpHeadersEnv);
197+
DumpOtlpHeaders(result, kOtlpTracesHeadersEnv);
198+
return result;
199+
}
200+
201+
} // namespace otlp
202+
} // namespace exporter
203+
OPENTELEMETRY_END_NAMESPACE

exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h

+8-59
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#pragma once
55

6+
#include <chrono>
7+
68
#include "opentelemetry/exporters/otlp/protobuf_include_prefix.h"
79

810
#include "opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.h"
@@ -11,78 +13,21 @@
1113

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

14-
#include "opentelemetry/sdk/common/env_variables.h"
16+
#include "opentelemetry/exporters/otlp/otlp_environment.h"
1517

1618
OPENTELEMETRY_BEGIN_NAMESPACE
1719
namespace exporter
1820
{
1921
namespace otlp
2022
{
2123

22-
inline const std::string GetOtlpDefaultEndpoint()
23-
{
24-
constexpr char kOtlpTracesEndpointEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
25-
constexpr char kOtlpEndpointEnv[] = "OTEL_EXPORTER_OTLP_ENDPOINT";
26-
constexpr char kOtlpEndpointDefault[] = "http://localhost:4317";
27-
28-
auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesEndpointEnv);
29-
if (endpoint.size() == 0)
30-
{
31-
endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpEndpointEnv);
32-
}
33-
return endpoint.size() ? endpoint : kOtlpEndpointDefault;
34-
}
35-
36-
inline const bool GetOtlpDefaultIsSslEnable()
37-
{
38-
constexpr char kOtlpTracesIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_TRACES_SSL_ENABLE";
39-
constexpr char kOtlpIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_SSL_ENABLE";
40-
41-
auto ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesIsSslEnableEnv);
42-
if (ssl_enable.size() == 0)
43-
{
44-
ssl_enable = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpIsSslEnableEnv);
45-
}
46-
if (ssl_enable == "True" || ssl_enable == "TRUE" || ssl_enable == "true" || ssl_enable == "1")
47-
{
48-
return true;
49-
}
50-
return false;
51-
}
52-
53-
inline const std::string GetOtlpDefaultSslCertificatePath()
54-
{
55-
constexpr char kOtlpTracesSslCertificate[] = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE";
56-
constexpr char kOtlpSslCertificate[] = "OTEL_EXPORTER_OTLP_CERTIFICATE ";
57-
auto ssl_cert_path =
58-
opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesSslCertificate);
59-
if (ssl_cert_path.size() == 0)
60-
{
61-
ssl_cert_path = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpSslCertificate);
62-
}
63-
return ssl_cert_path.size() ? ssl_cert_path : "";
64-
}
65-
66-
inline const std::string GetOtlpDefaultSslCertificateString()
67-
{
68-
constexpr char kOtlpTracesSslCertificateString[] = "OTEL_EXPORTER_OTLP_CERTIFICATE_STRING";
69-
constexpr char kOtlpSslCertificateString[] = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE_STRING ";
70-
auto ssl_cert =
71-
opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpTracesSslCertificateString);
72-
if (ssl_cert.size() == 0)
73-
{
74-
ssl_cert = opentelemetry::sdk::common::GetEnvironmentVariable(kOtlpSslCertificateString);
75-
}
76-
return ssl_cert.size() ? ssl_cert : "";
77-
}
78-
7924
/**
8025
* Struct to hold OTLP exporter options.
8126
*/
8227
struct OtlpGrpcExporterOptions
8328
{
8429
// The endpoint to export to. By default the OpenTelemetry Collector's default endpoint.
85-
std::string endpoint = GetOtlpDefaultEndpoint();
30+
std::string endpoint = GetOtlpDefaultGrpcEndpoint();
8631
// By default when false, uses grpc::InsecureChannelCredentials(); If true,
8732
// uses ssl_credentials_cacert_path if non-empty, else uses ssl_credentials_cacert_as_string
8833
bool use_ssl_credentials = GetOtlpDefaultIsSslEnable();
@@ -91,6 +36,10 @@ struct OtlpGrpcExporterOptions
9136
// ssl_credentials_cacert_as_string in-memory string representation of .pem file to be used for
9237
// SSL encryption.
9338
std::string ssl_credentials_cacert_as_string = GetOtlpDefaultSslCertificateString();
39+
// Timeout for grpc deadline
40+
std::chrono::system_clock::duration timeout = GetOtlpDefaultTimeout();
41+
// Additional HTTP headers
42+
OtlpHeaders metadata = GetOtlpDefaultHeaders();
9443
};
9544

9645
/**

0 commit comments

Comments
 (0)