Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c4c31aa
Add environment-related logic
chusitoo Dec 24, 2024
ed07242
Update options with retry policy settings
chusitoo Dec 24, 2024
1dba246
Test config and retry mechanism
chusitoo Dec 24, 2024
ae47b20
Functional retry policy
chusitoo Dec 29, 2024
3c2c24a
Model exponential backoff after grpc retry policy
chusitoo Dec 29, 2024
2f9b629
Fix some neglected bits
chusitoo Dec 30, 2024
9cd4717
Reduce usage of decimal seconds to http client et al
chusitoo Dec 30, 2024
cec3b98
Fix overlook on iterator increment
chusitoo Dec 30, 2024
082597a
Unit test http retries with exponential backoff
chusitoo Dec 30, 2024
8008e8c
Update comments for clarity
chusitoo Dec 30, 2024
48402d9
Fix unit tests and minor touchups
chusitoo Dec 30, 2024
6de20c1
Make intent clear in options used by UTs
chusitoo Dec 31, 2024
4de2f81
Cleanup
chusitoo Dec 31, 2024
413b284
Fix to support windows macro
chusitoo Jan 4, 2025
14a2927
Merge branch 'main' into RetryableErrorHttp
marcalff Jan 6, 2025
25b332c
Code review feedback
chusitoo Jan 7, 2025
f511021
Code review feedback pt 2
chusitoo Jan 8, 2025
20b347f
Code review feedback pt 3
chusitoo Jan 8, 2025
da7c636
Change to strtoull to ensure portability on msvc
chusitoo Jan 8, 2025
cd816b6
Include errno
chusitoo Jan 8, 2025
169b4a6
Bail out earlier from retry list
chusitoo Jan 8, 2025
62e2a6a
Merge remote-tracking branch 'remotes/origin/main' into RetryableErro…
chusitoo Jan 8, 2025
2e3ec77
Fixes for iwyu
chusitoo Jan 9, 2025
cb60f09
Fixes for clang-tidy
chusitoo Jan 9, 2025
f8e10c7
Add to changelog
chusitoo Jan 9, 2025
0e33217
Make it an opt-in feature
chusitoo Jan 10, 2025
e8bdb66
Guard includes for iwyu
chusitoo Jan 10, 2025
904929a
Merge remote-tracking branch 'remotes/origin/main' into RetryableErro…
chusitoo Jan 11, 2025
f8b6a09
Slightly faster code, slightly clearer intent
chusitoo Jan 11, 2025
797fda1
Remove unused include
chusitoo Jan 11, 2025
472aa35
Merge remote-tracking branch 'remotes/origin/main' into RetryableErro…
chusitoo Jan 16, 2025
facc19d
Prevent background thread from exiting when pending retries
chusitoo Jan 17, 2025
d3c52fe
Merge remote-tracking branch 'remotes/origin/main' into RetryableErro…
chusitoo Jan 17, 2025
63d7d7d
Address nit and minor logic flaw
chusitoo Jan 17, 2025
905e7ae
Fix clang tidy warning
chusitoo Jan 17, 2025
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 @@ -24,6 +24,9 @@ Increment the:
* [EXPORTER] Fix scope attributes missing from otlp traces metrics
[#3185](https://github.com/open-telemetry/opentelemetry-cpp/pull/3185)

[EXPORTER] Support handling retry-able errors for OTLP/HTTP
[#3223](https://github.com/open-telemetry/opentelemetry-cpp/pull/3223)

## [1.18 2024-11-25]

* [EXPORTER] Fix crash in ElasticsearchLogRecordExporter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,22 @@ std::string GetOtlpDefaultTracesCompression();
std::string GetOtlpDefaultMetricsCompression();
std::string GetOtlpDefaultLogsCompression();

std::uint32_t GetOtlpDefaultTracesRetryMaxAttempts();
std::uint32_t GetOtlpDefaultMetricsRetryMaxAttempts();
std::uint32_t GetOtlpDefaultLogsRetryMaxAttempts();

std::chrono::duration<float> GetOtlpDefaultTracesRetryInitialBackoff();
std::chrono::duration<float> GetOtlpDefaultMetricsRetryInitialBackoff();
std::chrono::duration<float> GetOtlpDefaultLogsRetryInitialBackoff();

std::chrono::duration<float> GetOtlpDefaultTracesRetryMaxBackoff();
std::chrono::duration<float> GetOtlpDefaultMetricsRetryMaxBackoff();
std::chrono::duration<float> GetOtlpDefaultLogsRetryMaxBackoff();

float GetOtlpDefaultTracesRetryBackoffMultiplier();
float GetOtlpDefaultMetricsRetryBackoffMultiplier();
float GetOtlpDefaultLogsRetryBackoffMultiplier();

} // namespace otlp
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ struct OtlpHttpClientOptions
// Additional HTTP headers
OtlpHeaders http_headers;

// Retry policy for select failure codes
ext::http::client::RetryPolicy retry_policy;

// Concurrent requests
std::size_t max_concurrent_requests = 64;

Expand Down Expand Up @@ -102,6 +105,10 @@ struct OtlpHttpClientOptions
bool input_console_debug,
std::chrono::system_clock::duration input_timeout,
const OtlpHeaders &input_http_headers,
std::uint32_t input_retry_policy_max_attempts,
std::chrono::duration<float> input_retry_policy_initial_backoff,
std::chrono::duration<float> input_retry_policy_max_backoff,
float input_retry_policy_backoff_multiplier,
std::size_t input_concurrent_sessions = 64,
std::size_t input_max_requests_per_connection = 8,
nostd::string_view input_user_agent = GetOtlpDefaultUserAgent())
Expand All @@ -125,6 +132,8 @@ struct OtlpHttpClientOptions
console_debug(input_console_debug),
timeout(input_timeout),
http_headers(input_http_headers),
retry_policy{input_retry_policy_max_attempts, input_retry_policy_initial_backoff,
input_retry_policy_max_backoff, input_retry_policy_backoff_multiplier},
max_concurrent_requests(input_concurrent_sessions),
max_requests_per_connection(input_max_requests_per_connection),
user_agent(input_user_agent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <chrono>
#include <cstdint>
#include <string>

#include "opentelemetry/exporters/otlp/otlp_environment.h"
Expand Down Expand Up @@ -101,6 +102,18 @@ struct OPENTELEMETRY_EXPORT OtlpHttpExporterOptions

/** Compression type. */
std::string compression;

/** The maximum number of call attempts, including the original attempt. */
std::uint32_t retry_policy_max_attempts{};

/** The initial backoff delay between retry attempts, random between (0, initial_backoff). */
std::chrono::duration<float> retry_policy_initial_backoff{};

/** The maximum backoff places an upper limit on exponential backoff growth. */
std::chrono::duration<float> retry_policy_max_backoff{};

/** The backoff will be multiplied by this value after each retry attempt. */
float retry_policy_backoff_multiplier{};
};

} // namespace otlp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <chrono>
#include <cstdint>
#include <string>

#include "opentelemetry/exporters/otlp/otlp_environment.h"
Expand Down Expand Up @@ -101,6 +102,18 @@ struct OPENTELEMETRY_EXPORT OtlpHttpLogRecordExporterOptions

/** Compression type. */
std::string compression;

/** The maximum number of call attempts, including the original attempt. */
std::uint32_t retry_policy_max_attempts{};

/** The initial backoff delay between retry attempts, random between (0, initial_backoff). */
std::chrono::duration<float> retry_policy_initial_backoff{};

/** The maximum backoff places an upper limit on exponential backoff growth. */
std::chrono::duration<float> retry_policy_max_backoff{};

/** The backoff will be multiplied by this value after each retry attempt. */
float retry_policy_backoff_multiplier{};
};

} // namespace otlp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include <chrono>
#include <cstdint>
#include <string>

#include "opentelemetry/exporters/otlp/otlp_environment.h"
Expand Down Expand Up @@ -104,6 +105,18 @@ struct OPENTELEMETRY_EXPORT OtlpHttpMetricExporterOptions

/** Compression type. */
std::string compression;

/** The maximum number of call attempts, including the original attempt. */
std::uint32_t retry_policy_max_attempts{};

/** The initial backoff delay between retry attempts, random between (0, initial_backoff). */
std::chrono::duration<float> retry_policy_initial_backoff{};

/** The maximum backoff places an upper limit on exponential backoff growth. */
std::chrono::duration<float> retry_policy_max_backoff{};

/** The backoff will be multiplied by this value after each retry attempt. */
float retry_policy_backoff_multiplier{};
};

} // namespace otlp
Expand Down
201 changes: 201 additions & 0 deletions exporters/otlp/src/otlp_environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

#include <chrono>
#include <cstdint>
#include <map>
#include <string>
#include <unordered_set>
Expand Down Expand Up @@ -78,6 +79,38 @@ static bool GetStringDualEnvVar(const char *signal_name,
return exists;
}

static bool GetUintDualEnvVar(const char *signal_name,
const char *generic_name,
std::uint32_t &value)
{
bool exists;

exists = sdk_common::GetUintEnvironmentVariable(signal_name, value);
if (exists)
{
return true;
}

exists = sdk_common::GetUintEnvironmentVariable(generic_name, value);

return exists;
}

static bool GetFloatDualEnvVar(const char *signal_name, const char *generic_name, float &value)
{
bool exists;

exists = sdk_common::GetFloatEnvironmentVariable(signal_name, value);
if (exists)
{
return true;
}

exists = sdk_common::GetFloatEnvironmentVariable(generic_name, value);

return exists;
}

std::string GetOtlpDefaultGrpcTracesEndpoint()
{
constexpr char kSignalEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
Expand Down Expand Up @@ -1123,6 +1156,174 @@ std::string GetOtlpDefaultLogsCompression()
return std::string{"none"};
}

std::uint32_t GetOtlpDefaultTracesRetryMaxAttempts()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_TRACES_RETRY_MAX_ATTEMPTS";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_ATTEMPTS";
std::uint32_t value{};

if (GetUintDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 5U;
}

std::uint32_t GetOtlpDefaultMetricsRetryMaxAttempts()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_METRICS_RETRY_MAX_ATTEMPTS";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_ATTEMPTS";
std::uint32_t value{};

if (GetUintDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 5U;
}

std::uint32_t GetOtlpDefaultLogsRetryMaxAttempts()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_LOGS_RETRY_MAX_ATTEMPTS";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_ATTEMPTS";
std::uint32_t value{};

if (GetUintDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 5U;
}

std::chrono::duration<float> GetOtlpDefaultTracesRetryInitialBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_TRACES_RETRY_INITIAL_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_INITIAL_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{1.0f};
}

std::chrono::duration<float> GetOtlpDefaultMetricsRetryInitialBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_METRICS_RETRY_INITIAL_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_INITIAL_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{1.0f};
}

std::chrono::duration<float> GetOtlpDefaultLogsRetryInitialBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_LOGS_RETRY_INITIAL_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_INITIAL_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{1.0f};
}

std::chrono::duration<float> GetOtlpDefaultTracesRetryMaxBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_TRACES_RETRY_MAX_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{5.0f};
}

std::chrono::duration<float> GetOtlpDefaultMetricsRetryMaxBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_METRICS_RETRY_MAX_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{5.0f};
}

std::chrono::duration<float> GetOtlpDefaultLogsRetryMaxBackoff()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_LOGS_RETRY_MAX_BACKOFF";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_MAX_BACKOFF";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return std::chrono::duration<float>{value};
}

return std::chrono::duration<float>{5.0f};
}

float GetOtlpDefaultTracesRetryBackoffMultiplier()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_TRACES_RETRY_BACKOFF_MULTIPLIER";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_BACKOFF_MULTIPLIER";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 1.5f;
}

float GetOtlpDefaultMetricsRetryBackoffMultiplier()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_METRICS_RETRY_BACKOFF_MULTIPLIER";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_BACKOFF_MULTIPLIER";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 1.5f;
}

float GetOtlpDefaultLogsRetryBackoffMultiplier()
{
constexpr char kSignalEnv[] = "OTEL_CPP_EXPORTER_OTLP_LOGS_RETRY_BACKOFF_MULTIPLIER";
constexpr char kGenericEnv[] = "OTEL_CPP_EXPORTER_OTLP_RETRY_BACKOFF_MULTIPLIER";
float value{};

if (GetFloatDualEnvVar(kSignalEnv, kGenericEnv, value))
{
return value;
}

return 1.5f;
}

} // namespace otlp
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
1 change: 1 addition & 0 deletions exporters/otlp/src/otlp_http_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,7 @@ OtlpHttpClient::createSession(
request->ReplaceHeader("Content-Type", content_type);
request->ReplaceHeader("User-Agent", options_.user_agent);
request->EnableLogging(options_.console_debug);
request->SetRetryPolicy(options_.retry_policy);

if (options_.compression == "gzip")
{
Expand Down
Loading
Loading