Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
72f8cce
[EXPORTER] Add WITH_CUSTOM_HTTP_CLIENT option
ltowarek May 8, 2026
8fa2072
Fix formatting
ltowarek May 11, 2026
87a12da
Add opentelemetry_http_client interface library
ltowarek May 11, 2026
135c213
Add example and test
ltowarek May 12, 2026
53debbe
Use WITH_HTTP_CLIENT_CURL=OFF
ltowarek May 12, 2026
33f0e4d
Improve the custom_http_client example
ltowarek May 12, 2026
fba51be
Link opentelemetry_exporter_otlp_http_client with CURL
ltowarek May 13, 2026
516c51b
Include custom_http_client example only in build-time
ltowarek May 13, 2026
235c596
Install http_client
ltowarek May 14, 2026
b8eb45d
Make HttpClientFactory virtual
ltowarek May 14, 2026
b424e86
Fix http_client_factory_curl.h
ltowarek May 15, 2026
5695f7d
Support HttpClientFactory in logs and metrics
ltowarek May 15, 2026
db50030
Remove old HttpClientFactory calls
ltowarek May 15, 2026
ffa0d3e
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
ltowarek May 15, 2026
a790ade
Support options, runtime_options and factory in the Create method
ltowarek May 16, 2026
864d706
Add unit tests
ltowarek May 16, 2026
316a8ba
Fix warnings
ltowarek May 16, 2026
e308513
Increase test coverage
ltowarek May 16, 2026
2dd13e4
Fix formatting
ltowarek May 16, 2026
9c3dd33
Fix Bazel
ltowarek May 17, 2026
2c64733
Fix IWYU
ltowarek May 17, 2026
6ca4b37
Fix clang-tidy
ltowarek May 17, 2026
397cf92
Merge remote-tracking branch 'upstream/main' into fix/issue-24-custom…
ltowarek May 19, 2026
ad89717
Fix IWYU
ltowarek May 21, 2026
9c2035d
Merge branch 'main' of github.com:open-telemetry/opentelemetry-cpp in…
ltowarek May 21, 2026
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
16 changes: 7 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,13 @@ include(GNUInstallDirs)
# Do we need HTTP CLIENT CURL ?
#

if(WITH_OTLP_HTTP
OR WITH_ELASTICSEARCH
OR WITH_ZIPKIN
OR BUILD_W3CTRACECONTEXT_TEST
OR WITH_EXAMPLES_HTTP)
set(WITH_HTTP_CLIENT_CURL ON)
else()
set(WITH_HTTP_CLIENT_CURL OFF)
endif()
include(CMakeDependentOption)
cmake_dependent_option(
WITH_HTTP_CLIENT_CURL
"Use the curl HTTP client backend. Defaults to ON when any HTTP exporter is enabled; set OFF to supply a custom transport."
ON
"WITH_OTLP_HTTP OR WITH_ELASTICSEARCH OR WITH_ZIPKIN OR BUILD_W3CTRACECONTEXT_TEST OR WITH_EXAMPLES_HTTP"
OFF)

#
# Do we need ZLIB ?
Expand Down
1 change: 1 addition & 0 deletions ci/do_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ elif [[ "$1" == "cmake.install.test" ]]; then
"sdk"
"configuration"
"ext_common"
"ext_http"
"ext_http_curl"
"exporters_in_memory"
"exporters_ostream"
Expand Down
4 changes: 4 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ endif()
if(WITH_CONFIGURATION)
add_subdirectory(configuration)
endif()

if(NOT WITH_HTTP_CLIENT_CURL AND WITH_OTLP_HTTP)
add_subdirectory(custom_http_client)
endif()
11 changes: 11 additions & 0 deletions examples/custom_http_client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

add_library(custom_http_client_stub STATIC custom_http_client.cc)
target_link_libraries(custom_http_client_stub PUBLIC opentelemetry_ext
opentelemetry_sdk)

add_executable(example_custom_http_client main.cc)
target_link_libraries(
example_custom_http_client PRIVATE custom_http_client_stub
opentelemetry-cpp::otlp_http_exporter)
149 changes: 149 additions & 0 deletions examples/custom_http_client/custom_http_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <iostream>
#include <string>

#include "opentelemetry/ext/http/client/http_client.h"
#include "opentelemetry/ext/http/client/http_client_factory.h"
#include "opentelemetry/sdk/common/thread_instrumentation.h"

#include "custom_http_client.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace ext
{
namespace http
{
namespace client
{

namespace
{

class LoggingRequest : public Request
{
public:
void SetMethod(Method method) noexcept override
{
switch (method)
{
case Method::Get:
method_ = "GET";
break;
case Method::Post:
method_ = "POST";
break;
case Method::Put:
method_ = "PUT";
break;
default:
method_ = "OTHER";
break;
}
}

void SetUri(nostd::string_view uri) noexcept override { uri_ = std::string(uri); }

void SetBody(Body &body) noexcept override { body_size_ = body.size(); }

void SetSslOptions(const HttpSslOptions &) noexcept override {}
void AddHeader(nostd::string_view, nostd::string_view) noexcept override {}
void ReplaceHeader(nostd::string_view, nostd::string_view) noexcept override {}
void SetTimeoutMs(std::chrono::milliseconds) noexcept override {}
void SetCompression(const Compression &) noexcept override {}
void EnableLogging(bool) noexcept override {}
void SetRetryPolicy(const RetryPolicy &) noexcept override {}

const std::string &GetMethod() const { return method_; }
const std::string &GetUri() const { return uri_; }
std::size_t GetBodySize() const { return body_size_; }

private:
std::string method_;
std::string uri_;
std::size_t body_size_ = 0;
};

class OkResponse : public NoopResponse
{
public:
StatusCode GetStatusCode() const noexcept override { return 200; }
};

class LoggingSession : public Session
{
public:
std::shared_ptr<Request> CreateRequest() noexcept override
{
request_ = std::make_shared<LoggingRequest>();
return request_;
}

void SendRequest(std::shared_ptr<EventHandler> handler) noexcept override
{
if (request_)
{
std::cout << "Custom HTTP client: " << request_->GetMethod() << " " << request_->GetUri()
<< " (" << request_->GetBodySize() << " bytes)\n";
}
if (!handler)
{
return;
}
OkResponse response;
handler->OnResponse(response);
handler->OnEvent(SessionState::Response, {});
std::cout << "Custom HTTP client: export acknowledged\n";
}

bool IsSessionActive() noexcept override { return false; }
bool CancelSession() noexcept override { return true; }
bool FinishSession() noexcept override { return true; }

private:
std::shared_ptr<LoggingRequest> request_;
};

class LoggingHttpClient : public HttpClient
{
public:
std::shared_ptr<Session> CreateSession(nostd::string_view url) noexcept override
{
std::cout << "Custom HTTP client: creating session for " << std::string(url) << "\n";
return std::make_shared<LoggingSession>();
}

bool CancelAllSessions() noexcept override { return true; }
bool FinishAllSessions() noexcept override { return true; }
void SetMaxSessionsPerConnection(std::size_t) noexcept override {}
};

} // namespace

std::shared_ptr<HttpClient> LoggingHttpClientFactory::Create()
{
return std::make_shared<LoggingHttpClient>();
}

std::shared_ptr<HttpClient> LoggingHttpClientFactory::Create(
const std::shared_ptr<sdk::common::ThreadInstrumentation> &)
{
return std::make_shared<LoggingHttpClient>();
}

std::shared_ptr<HttpClientSync> LoggingHttpClientFactory::CreateSync()
{
return nullptr;
}

std::shared_ptr<HttpClientFactory> GetDefaultHttpClientFactory()
{
static auto instance = std::make_shared<LoggingHttpClientFactory>();
return instance;
}

} // namespace client
} // namespace http
} // namespace ext
OPENTELEMETRY_END_NAMESPACE
31 changes: 31 additions & 0 deletions examples/custom_http_client/custom_http_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <memory>

#include "opentelemetry/ext/http/client/http_client_factory.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace ext
{
namespace http
{
namespace client
{

class LoggingHttpClientFactory : public HttpClientFactory
{
public:
std::shared_ptr<HttpClientSync> CreateSync() override;
std::shared_ptr<HttpClient> Create() override;
std::shared_ptr<HttpClient> Create(
const std::shared_ptr<sdk::common::ThreadInstrumentation> &thread_instrumentation) override;
};

} // namespace client
} // namespace http
} // namespace ext
OPENTELEMETRY_END_NAMESPACE
35 changes: 35 additions & 0 deletions examples/custom_http_client/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <memory>

#include "custom_http_client.h"
#include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"

namespace trace_sdk = opentelemetry::sdk::trace;
namespace otlp = opentelemetry::exporter::otlp;
namespace http_client = opentelemetry::ext::http::client;

int main()
{
otlp::OtlpHttpExporterOptions options;
options.url = "http://localhost:4318/v1/traces";

auto factory = std::make_shared<http_client::LoggingHttpClientFactory>();
auto exporter = otlp::OtlpHttpExporterFactory::Create(options, factory);
auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));

std::shared_ptr<trace_sdk::TracerProvider> provider =
trace_sdk::TracerProviderFactory::Create(std::move(processor));

auto tracer = provider->GetTracer("custom-http-client-example");
auto span = tracer->StartSpan("custom-span");
span->SetAttribute("example.key", "value");
span->End();

provider->ForceFlush();
return 0;
}
22 changes: 12 additions & 10 deletions examples/http/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

add_executable(http_client client.cc)
add_executable(http_server server.cc)
if(WITH_HTTP_CLIENT_CURL)
add_executable(http_client client.cc)
add_executable(http_server server.cc)

target_link_libraries(
http_client
PRIVATE opentelemetry-cpp::trace opentelemetry-cpp::http_client_curl
opentelemetry-cpp::ostream_span_exporter CURL::libcurl)
target_link_libraries(
http_client
PRIVATE opentelemetry-cpp::trace opentelemetry-cpp::http_client_curl
opentelemetry-cpp::ostream_span_exporter CURL::libcurl)

target_link_libraries(
http_server
PRIVATE opentelemetry-cpp::trace opentelemetry-cpp::http_client_curl
opentelemetry-cpp::ostream_span_exporter)
target_link_libraries(
http_server
PRIVATE opentelemetry-cpp::trace opentelemetry-cpp::http_client_curl
opentelemetry-cpp::ostream_span_exporter)
endif()
2 changes: 1 addition & 1 deletion examples/http/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace semconv = opentelemetry::semconv;

void sendRequest(const std::string &url)
{
auto http_client = http_client::HttpClientFactory::CreateSync();
auto http_client = http_client::GetDefaultHttpClientFactory()->CreateSync();

// start active span
StartSpanOptions options;
Expand Down
2 changes: 1 addition & 1 deletion exporters/elasticsearch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ target_include_directories(

target_link_libraries(
opentelemetry_exporter_elasticsearch_logs
PUBLIC opentelemetry_trace opentelemetry_logs opentelemetry_http_client_curl
PUBLIC opentelemetry_trace opentelemetry_logs opentelemetry_http_client
nlohmann_json::nlohmann_json)

otel_add_component(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>

#include "opentelemetry/ext/http/client/http_client.h"
#include "opentelemetry/ext/http/client/http_client_factory.h"
#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/sdk/logs/exporter.h"
#include "opentelemetry/version.h"
Expand Down Expand Up @@ -87,6 +88,23 @@ class ElasticsearchLogRecordExporter final : public opentelemetry::sdk::logs::Lo
*/
ElasticsearchLogRecordExporter(const ElasticsearchExporterOptions &options);

/**
* Create an ElasticsearchLogRecordExporter with user specified options and HTTP client factory.
* @param options An object containing the user's configuration options.
* @param factory the HTTP client factory used to create the underlying HTTP client
*/
ElasticsearchLogRecordExporter(
const ElasticsearchExporterOptions &options,
const std::shared_ptr<ext::http::client::HttpClientFactory> &factory);

/**
* Create an ElasticsearchLogRecordExporter with user specified options and HTTP client.
* @param options An object containing the user's configuration options.
* @param http_client the HTTP client to be used for exporting
*/
ElasticsearchLogRecordExporter(const ElasticsearchExporterOptions &options,
std::shared_ptr<ext::http::client::HttpClient> http_client);

/**
* Creates a recordable that stores the data in a JSON object
* @return a newly initialized Recordable object.
Expand Down
14 changes: 13 additions & 1 deletion exporters/elasticsearch/src/es_log_record_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,20 @@ ElasticsearchLogRecordExporter::ElasticsearchLogRecordExporter()

ElasticsearchLogRecordExporter::ElasticsearchLogRecordExporter(
const ElasticsearchExporterOptions &options)
: ElasticsearchLogRecordExporter(options, ext::http::client::GetDefaultHttpClientFactory())
{}

ElasticsearchLogRecordExporter::ElasticsearchLogRecordExporter(
const ElasticsearchExporterOptions &options,
const std::shared_ptr<ext::http::client::HttpClientFactory> &factory)
: ElasticsearchLogRecordExporter(options, factory->Create())
{}

ElasticsearchLogRecordExporter::ElasticsearchLogRecordExporter(
const ElasticsearchExporterOptions &options,
std::shared_ptr<ext::http::client::HttpClient> http_client)
: options_{options},
http_client_{ext::http::client::HttpClientFactory::Create()}
http_client_{std::move(http_client)}
#ifdef ENABLE_ASYNC_EXPORT
,
synchronization_data_(new SynchronizationData())
Expand Down
8 changes: 8 additions & 0 deletions exporters/elasticsearch/test/es_log_record_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ namespace logs_api = opentelemetry::logs;
namespace nostd = opentelemetry::nostd;
namespace logs_exporter = opentelemetry::exporter::logs;

TEST(ElasticsearchLogsExporterTests, CustomClientConstructionSucceeds)
{
logs_exporter::ElasticsearchExporterOptions opts;
auto exporter = std::unique_ptr<sdklogs::LogRecordExporter>(
new logs_exporter::ElasticsearchLogRecordExporter(opts));
ASSERT_NE(exporter, nullptr);
}

// Attempt to write a log to an invalid host/port, test that the Export() returns failure
TEST(DISABLED_ElasticsearchLogsExporterTests, InvalidEndpoint)
{
Expand Down
Loading