Support custom span name and attributes.
This commit is contained in:
parent
05bb09941d
commit
771aa40627
3 changed files with 111 additions and 4 deletions
|
|
@ -70,6 +70,16 @@ public:
|
|||
add(key)->mutable_value()->set_int_value(value);
|
||||
}
|
||||
|
||||
void addArray(StrView key, StrView value)
|
||||
{
|
||||
auto elems = add(key)->mutable_value()->mutable_array_value()->
|
||||
mutable_values();
|
||||
|
||||
auto elem = elems->size() > 0 ? elems->Mutable(0) : elems->Add();
|
||||
|
||||
elem->mutable_string_value()->assign(value.data(), value.size());
|
||||
}
|
||||
|
||||
void setError()
|
||||
{
|
||||
span->mutable_status()->set_code(
|
||||
|
|
|
|||
|
|
@ -26,12 +26,21 @@ struct MainConf {
|
|||
ngx_str_t serviceName;
|
||||
};
|
||||
|
||||
struct SpanAttr {
|
||||
ngx_str_t name;
|
||||
ngx_http_complex_value_t value;
|
||||
};
|
||||
|
||||
struct LocationConf {
|
||||
ngx_http_complex_value_t* trace;
|
||||
ngx_uint_t traceContext;
|
||||
|
||||
ngx_http_complex_value_t* spanName;
|
||||
ngx_array_t spanAttrs;
|
||||
};
|
||||
|
||||
char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
|
||||
char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
|
||||
|
||||
namespace Propagation {
|
||||
|
||||
|
|
@ -74,6 +83,17 @@ ngx_command_t gCommands[] = {
|
|||
offsetof(LocationConf, traceContext),
|
||||
&Propagation::Types },
|
||||
|
||||
{ ngx_string("otel_span_name"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_set_complex_value_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(LocationConf, spanName) },
|
||||
|
||||
{ ngx_string("otel_span_attr"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
|
||||
addSpanAttr,
|
||||
NGX_HTTP_LOC_CONF_OFFSET },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
|
@ -369,6 +389,48 @@ void addDefaultAttrs(BatchExporter::Span& span, ngx_http_request_t* r)
|
|||
span.add("net.sock.peer.port", ngx_inet_get_port(r->connection->sockaddr));
|
||||
}
|
||||
|
||||
StrView getSpanName(ngx_http_request_t* r)
|
||||
{
|
||||
auto lcf = getLocationConf(r);
|
||||
|
||||
if (lcf->spanName) {
|
||||
ngx_str_t result;
|
||||
if (ngx_http_complex_value(r, lcf->spanName, &result) != NGX_OK) {
|
||||
throw std::runtime_error("failed to compute complex value");
|
||||
}
|
||||
|
||||
return toStrView(result);
|
||||
} else {
|
||||
auto clcf = (ngx_http_core_loc_conf_t*)
|
||||
ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
return toStrView(clcf->name);
|
||||
}
|
||||
}
|
||||
|
||||
void addCustomAttrs(BatchExporter::Span& span, ngx_http_request_t* r)
|
||||
{
|
||||
auto lcf = getLocationConf(r);
|
||||
auto attrs = (SpanAttr*)lcf->spanAttrs.elts;
|
||||
|
||||
for (ngx_uint_t i = 0; i < lcf->spanAttrs.nelts; i++) {
|
||||
ngx_str_t value;
|
||||
if (ngx_http_complex_value(r, &attrs[i].value, &value) != NGX_OK) {
|
||||
throw std::runtime_error("failed to compute complex value");
|
||||
}
|
||||
|
||||
StrView name = toStrView(attrs[i].name);
|
||||
if (startsWith(name, "http.request.header.") ||
|
||||
startsWith(name, "http.response.header."))
|
||||
{
|
||||
//TODO: remove this once headers are supported natively
|
||||
span.addArray(name, toStrView(value));
|
||||
} else {
|
||||
span.add(name, toStrView(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngx_int_t onRequestEnd(ngx_http_request_t* r)
|
||||
{
|
||||
auto ctx = getOtelCtx(r);
|
||||
|
|
@ -376,9 +438,6 @@ ngx_int_t onRequestEnd(ngx_http_request_t* r)
|
|||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
auto clcf = (ngx_http_core_loc_conf_t*)ngx_http_get_module_loc_conf(
|
||||
r, ngx_http_core_module);
|
||||
|
||||
auto now = ngx_timeofday();
|
||||
|
||||
auto toNanoSec = [](time_t sec, ngx_msec_t msec) -> uint64_t {
|
||||
|
|
@ -387,12 +446,13 @@ ngx_int_t onRequestEnd(ngx_http_request_t* r)
|
|||
|
||||
try {
|
||||
BatchExporter::SpanInfo info{
|
||||
toStrView(clcf->name), ctx->current, ctx->parent.spanId,
|
||||
getSpanName(r), ctx->current, ctx->parent.spanId,
|
||||
toNanoSec(r->start_sec, r->start_msec),
|
||||
toNanoSec(now->sec, now->msec)};
|
||||
|
||||
bool ok = gExporter->add(info, [r](BatchExporter::Span& span) {
|
||||
addDefaultAttrs(span, r);
|
||||
addCustomAttrs(span, r);
|
||||
});
|
||||
|
||||
if (!ok) {
|
||||
|
|
@ -589,6 +649,32 @@ char* initMainConf(ngx_conf_t* cf, void* conf)
|
|||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
|
||||
{
|
||||
auto lcf = (LocationConf*)conf;
|
||||
|
||||
if (lcf->spanAttrs.elts == NULL && ngx_array_init(&lcf->spanAttrs,
|
||||
cf->pool, 4, sizeof(SpanAttr)) != NGX_OK) {
|
||||
return (char*)NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
auto attr = (SpanAttr*)ngx_array_push(&lcf->spanAttrs);
|
||||
if (attr == NULL) {
|
||||
return (char*)NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
auto args = (ngx_str_t*)cf->args->elts;
|
||||
|
||||
attr->name = args[1];
|
||||
|
||||
ngx_http_compile_complex_value_t ccv = { cf, &args[2], &attr->value };
|
||||
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
|
||||
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)
|
||||
|
|
@ -677,6 +763,7 @@ void* createLocationConf(ngx_conf_t* cf)
|
|||
|
||||
conf->trace = (ngx_http_complex_value_t*)NGX_CONF_UNSET_PTR;
|
||||
conf->traceContext = NGX_CONF_UNSET_UINT;
|
||||
conf->spanName = (ngx_http_complex_value_t*)NGX_CONF_UNSET_PTR;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
|
@ -688,6 +775,11 @@ char* mergeLocationConf(ngx_conf_t* cf, void* parent, void* child)
|
|||
|
||||
ngx_conf_merge_ptr_value(conf->trace, prev->trace, NULL);
|
||||
ngx_conf_merge_uint_value(conf->traceContext, prev->traceContext, 0);
|
||||
ngx_conf_merge_ptr_value(conf->spanName, prev->spanName, NULL);
|
||||
|
||||
if (conf->spanAttrs.elts == NULL) {
|
||||
conf->spanAttrs = prev->spanAttrs;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,3 +3,8 @@
|
|||
#include <opentelemetry/nostd/string_view.h>
|
||||
|
||||
typedef opentelemetry::nostd::string_view StrView;
|
||||
|
||||
inline bool startsWith(StrView str, StrView prefix)
|
||||
{
|
||||
return str.substr(0, prefix.size()) == prefix;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue