Support export via TLS (fix #12).

This commit is contained in:
Nikita Vakula 2024-11-15 11:39:30 +01:00 committed by p-pautov
parent da2e4eb11b
commit 6c1659a20b
3 changed files with 55 additions and 8 deletions

View file

@ -111,10 +111,10 @@ public:
int attrSize{0}; int attrSize{0};
}; };
BatchExporter(StrView target, BatchExporter(StrView target, bool ssl, const std::string& trustedCert,
size_t batchSize, size_t batchCount, size_t batchSize, size_t batchCount,
const std::map<StrView, StrView>& resourceAttrs) : const std::map<StrView, StrView>& resourceAttrs) :
batchSize(batchSize), client(std::string(target)) batchSize(batchSize), client(std::string(target), ssl, trustedCert)
{ {
free.reserve(batchCount); free.reserve(batchCount);
while (batchCount-- > 0) { while (batchCount-- > 0) {

View file

@ -6,6 +6,8 @@
#include "trace_context.hpp" #include "trace_context.hpp"
#include "batch_exporter.hpp" #include "batch_exporter.hpp"
#include <fstream>
extern ngx_module_t gHttpModule; extern ngx_module_t gHttpModule;
namespace { namespace {
@ -26,6 +28,8 @@ struct MainConfBase {
struct MainConf : MainConfBase { struct MainConf : MainConfBase {
std::map<StrView, StrView> resourceAttrs; std::map<StrView, StrView> resourceAttrs;
bool ssl;
std::string trustedCert;
}; };
struct SpanAttr { struct SpanAttr {
@ -44,6 +48,7 @@ struct LocationConf {
char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf); char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* setTrustedCertificate(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
namespace Propagation { namespace Propagation {
@ -111,6 +116,10 @@ ngx_command_t gExporterCommands[] = {
0, 0,
offsetof(MainConfBase, endpoint) }, offsetof(MainConfBase, endpoint) },
{ ngx_string("trusted_certificate"),
NGX_CONF_TAKE1,
setTrustedCertificate },
{ ngx_string("interval"), { ngx_string("interval"),
NGX_CONF_TAKE1, NGX_CONF_TAKE1,
ngx_conf_set_msec_slot, ngx_conf_set_msec_slot,
@ -569,6 +578,8 @@ ngx_int_t initWorkerProcess(ngx_cycle_t* cycle)
try { try {
gExporter.reset(new BatchExporter( gExporter.reset(new BatchExporter(
toStrView(mcf->endpoint), toStrView(mcf->endpoint),
mcf->ssl,
mcf->trustedCert,
mcf->batchSize, mcf->batchSize,
mcf->batchCount, mcf->batchCount,
mcf->resourceAttrs)); mcf->resourceAttrs));
@ -671,9 +682,7 @@ char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
} }
if (iremovePrefix(&mcf->endpoint, "https://")) { if (iremovePrefix(&mcf->endpoint, "https://")) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, mcf->ssl = true;
"\"otel_exporter\" doesn't support \"https\" endpoints");
return (char*)NGX_CONF_ERROR;
} else { } else {
iremovePrefix(&mcf->endpoint, "http://"); iremovePrefix(&mcf->endpoint, "http://");
} }
@ -702,6 +711,36 @@ char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
return NGX_CONF_OK; return NGX_CONF_OK;
} }
char* setTrustedCertificate(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) {
auto path = ((ngx_str_t*)cf->args->elts)[1];
auto mcf = getMainConf(cf);
if (ngx_get_full_name(cf->pool, &cf->cycle->conf_prefix, &path) != NGX_OK) {
return (char*)NGX_CONF_ERROR;
}
try {
std::ifstream file{(const char*)path.data, std::ios::binary};
if (!file.is_open()) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
"failed to open \"%V\"", &path);
return (char*)NGX_CONF_ERROR;
}
file.exceptions(std::ios::failbit | std::ios::badbit);
file.seekg(0, std::ios::end);
size_t size = file.tellg();
mcf->trustedCert.resize(size);
file.seekg(0);
file.read(&mcf->trustedCert[0], mcf->trustedCert.size());
} catch (const std::exception& e) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"failed to read \"%V\": %s", &path, e.what());
return (char*)NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
void* createMainConf(ngx_conf_t* cf) void* createMainConf(ngx_conf_t* cf)
{ {
auto cln = ngx_pool_cleanup_add(cf->pool, sizeof(MainConf)); auto cln = ngx_pool_cleanup_add(cf->pool, sizeof(MainConf));

View file

@ -17,10 +17,18 @@ public:
typedef std::function<void (Request, Response, grpc::Status)> typedef std::function<void (Request, Response, grpc::Status)>
ResponseCb; ResponseCb;
TraceServiceClient(const std::string& target) TraceServiceClient(const std::string& target, bool ssl,
const std::string& trustedCert)
{ {
auto channel = grpc::CreateChannel( std::shared_ptr<grpc::ChannelCredentials> creds;
target, grpc::InsecureChannelCredentials()); if (ssl) {
grpc::SslCredentialsOptions options;
options.pem_root_certs = trustedCert;
creds = grpc::SslCredentials(options);
} else {
creds = grpc::InsecureChannelCredentials();
}
auto channel = grpc::CreateChannel(target, creds);
channel->GetState(true); // trigger 'connecting' state channel->GetState(true); // trigger 'connecting' state
stub = TraceService::NewStub(channel); stub = TraceService::NewStub(channel);