Add feature custom resource attributes

This commit is contained in:
puhre 2024-05-28 14:34:58 +02:00
parent d381713639
commit 158c55feff
2 changed files with 79 additions and 2 deletions

View file

@ -10,6 +10,11 @@
#include "trace_context.hpp"
#include "trace_service_client.hpp"
struct ResourceAttr {
ngx_str_t name;
ngx_http_complex_value_t value;
};
class BatchExporter {
public:
typedef TraceServiceClient::Request Request;
@ -112,7 +117,7 @@ public:
};
BatchExporter(StrView target,
size_t batchSize, size_t batchCount, StrView serviceName) :
size_t batchSize, size_t batchCount, StrView serviceName, ngx_array_t customResourceAttrs) :
batchSize(batchSize), client(std::string(target))
{
free.reserve(batchCount);
@ -124,6 +129,15 @@ public:
attr->set_key("service.name");
attr->mutable_value()->set_string_value(std::string(serviceName));
auto attrs = (ResourceAttr*)customResourceAttrs.elts;
for (ngx_uint_t i = 0; i < customResourceAttrs.nelts; i++) {
attr = resourceSpans->mutable_resource()->add_attributes();
StrView value = StrView((char*)attrs[i].value.value.data, attrs[i].value.value.len);
StrView name = StrView((char*)attrs[i].name.data, attrs[i].name.len);
attr->set_key(std::string(name));
attr->mutable_value()->set_string_value(std::string(value));
}
auto scopeSpans = resourceSpans->add_scope_spans();
scopeSpans->mutable_scope()->set_name("nginx");
scopeSpans->mutable_scope()->set_version(NGINX_VERSION);

View file

@ -22,6 +22,7 @@ struct MainConf {
size_t batchCount;
ngx_str_t serviceName;
ngx_array_t resourceAttrs;
};
struct SpanAttr {
@ -39,6 +40,7 @@ struct LocationConf {
char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addResourceAttrs(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
namespace Propagation {
@ -68,6 +70,12 @@ ngx_command_t gCommands[] = {
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(MainConf, serviceName) },
{ ngx_string("otel_resource_attr"),
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
addResourceAttrs,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(MainConf, resourceAttrs) },
{ ngx_string("otel_trace"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_set_complex_value_slot,
@ -455,6 +463,7 @@ void addCustomAttrs(BatchExporter::Span& span, ngx_http_request_t* r)
}
}
ngx_int_t onRequestEnd(ngx_http_request_t* r)
{
auto ctx = getOtelCtx(r);
@ -540,7 +549,9 @@ ngx_int_t initWorkerProcess(ngx_cycle_t* cycle)
toStrView(mcf->endpoint),
mcf->batchSize,
mcf->batchCount,
toStrView(mcf->serviceName)));
toStrView(mcf->serviceName),
mcf->resourceAttrs
));
} catch (const std::exception& e) {
ngx_log_error(NGX_LOG_CRIT, cycle->log, 0,
"OTel worker init error: %s", e.what());
@ -705,6 +716,58 @@ char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
return NGX_CONF_OK;
}
char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) {
auto mcf = (MainConf*)conf;
if (mcf->resourceAttrs.elts == NULL && ngx_array_init(&mcf->resourceAttrs,
cf->pool, 4, sizeof(ResourceAttr)) != NGX_OK) {
return (char*)NGX_CONF_ERROR;
}
auto attr = (ResourceAttr*)ngx_array_push(&mcf->resourceAttrs);
if (attr == NULL) {
return (char*)NGX_CONF_ERROR;
}
auto args = (ngx_str_t*)cf->args->elts;
attr->name = args[0];
ngx_http_compile_complex_value_t ccv = { cf, &args[1], &attr->value };
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return (char*)NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
char* addResourceAttrs(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
{
auto mcf = (MainConf*)conf;
if (mcf->resourceAttrs.elts == NULL && ngx_array_init(&mcf->resourceAttrs,
cf->pool, 4, sizeof(ResourceAttr)) != NGX_OK) {
return (char*)NGX_CONF_ERROR;
}
auto cfCopy = *cf;
cfCopy.handler = addResourceAttr;
cfCopy.handler_conf = mcf;
auto rv = ngx_conf_parse(&cfCopy, NULL);
if (rv != NGX_CONF_OK) {
return rv;
}
if (mcf->endpoint.len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"otel_exporter\" requires \"endpoint\"");
return (char*)NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
template <class Id>
ngx_int_t hexIdVar(ngx_http_request_t* r, ngx_http_variable_value_t* v,
uintptr_t data)