Skip to content

Commit

Permalink
Merge pull request #14956 from esensar/feat/metric-labels
Browse files Browse the repository at this point in the history
dnsdist: add support for labels on custom metrics
  • Loading branch information
rgacogne authored Dec 17, 2024
2 parents bd7b45a + b3f572f commit 34ede92
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 210 deletions.
5 changes: 5 additions & 0 deletions pdns/dnsdistdist/dnsdist-carbon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint)
{
auto entries = dnsdist::metrics::g_stats.entries.read_lock();
for (const auto& entry : *entries) {
// Skip non-empty labels, since labels are not supported in Carbon
if (!entry.d_labels.empty()) {
continue;
}

str << namespace_name << "." << hostname << "." << instance_name << "." << entry.d_name << ' ';
if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
str << (*val)->load();
Expand Down
31 changes: 17 additions & 14 deletions pdns/dnsdistdist/dnsdist-lua-ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const

const char* dnsdist_ffi_dnsquestion_get_tag(const dnsdist_ffi_dnsquestion_t* dq, const char* label)
{
const char * result = nullptr;
const char* result = nullptr;

if (dq != nullptr && dq->dq != nullptr && dq->dq->ids.qTag != nullptr) {
const auto it = dq->dq->ids.qTag->find(label);
Expand Down Expand Up @@ -456,7 +456,6 @@ size_t dnsdist_ffi_dnsquestion_get_tag_array(dnsdist_ffi_dnsquestion_t* dq, cons
++pos;
}


if (!dq->tagsVect->empty()) {
*out = dq->tagsVect->data();
}
Expand Down Expand Up @@ -1007,7 +1006,7 @@ static constexpr char s_lua_ffi_code[] = R"FFICodeContent(
ffi.cdef[[
)FFICodeContent"
#include "dnsdist-lua-ffi-interface.inc"
R"FFICodeContent(
R"FFICodeContent(
]]
)FFICodeContent";
Expand Down Expand Up @@ -1057,7 +1056,8 @@ size_t dnsdist_ffi_generate_proxy_protocol_payload(const size_t addrSize, const
if (valuesCount > 0) {
valuesVect.reserve(valuesCount);
for (size_t idx = 0; idx < valuesCount; idx++) {
valuesVect.push_back({ std::string(values[idx].value, values[idx].size), values[idx].type });
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
valuesVect.push_back({std::string(values[idx].value, values[idx].size), values[idx].type});
}
}

Expand Down Expand Up @@ -1086,7 +1086,8 @@ size_t dnsdist_ffi_dnsquestion_generate_proxy_protocol_payload(const dnsdist_ffi
if (valuesCount > 0) {
valuesVect.reserve(valuesCount);
for (size_t idx = 0; idx < valuesCount; idx++) {
valuesVect.push_back({ std::string(values[idx].value, values[idx].size), values[idx].type });
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
valuesVect.push_back({std::string(values[idx].value, values[idx].size), values[idx].type});
}
}

Expand All @@ -1113,7 +1114,7 @@ bool dnsdist_ffi_dnsquestion_add_proxy_protocol_values(dnsdist_ffi_dnsquestion_t
dnsQuestion->dq->proxyProtocolValues->reserve(dnsQuestion->dq->proxyProtocolValues->size() + valuesCount);
for (size_t idx = 0; idx < valuesCount; idx++) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): the Lua FFI API is a C API..
dnsQuestion->dq->proxyProtocolValues->push_back({ std::string(values[idx].value, values[idx].size), values[idx].type });
dnsQuestion->dq->proxyProtocolValues->push_back({std::string(values[idx].value, values[idx].size), values[idx].type});
}

return true;
Expand Down Expand Up @@ -1146,7 +1147,8 @@ struct dnsdist_ffi_domain_list_t
{
std::vector<std::string> d_domains;
};
struct dnsdist_ffi_address_list_t {
struct dnsdist_ffi_address_list_t
{
std::vector<std::string> d_addresses;
};

Expand Down Expand Up @@ -1476,7 +1478,8 @@ void dnsdist_ffi_ring_entry_list_free(dnsdist_ffi_ring_entry_list_t* list)
delete list;
}

template<typename T> static void addRingEntryToList(std::unique_ptr<dnsdist_ffi_ring_entry_list_t>& list, const struct timespec& now, const T& entry)
template <typename T>
static void addRingEntryToList(std::unique_ptr<dnsdist_ffi_ring_entry_list_t>& list, const struct timespec& now, const T& entry)
{
auto age = DiffTime(entry.when, now);

Expand Down Expand Up @@ -1805,45 +1808,45 @@ bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* ty
if (name == nullptr || nameLen == 0 || type == nullptr || description == nullptr) {
return false;
}
auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName != nullptr ? std::optional<std::string>(customName) : std::nullopt);
auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName != nullptr ? std::optional<std::string>(customName) : std::nullopt, false);
return !result;
}

void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen)
{
auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), 1U);
auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), 1U, {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return;
}
}

void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value)
{
auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), value);
auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), value, {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return;
}
}

void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen)
{
auto result = dnsdist::metrics::decrementCustomCounter(std::string_view(metricName, metricNameLen), 1U);
auto result = dnsdist::metrics::decrementCustomCounter(std::string_view(metricName, metricNameLen), 1U, {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return;
}
}

void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value)
{
auto result = dnsdist::metrics::setCustomGauge(std::string_view(metricName, metricNameLen), value);
auto result = dnsdist::metrics::setCustomGauge(std::string_view(metricName, metricNameLen), value, {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return;
}
}

double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter)
{
auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen));
auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen), {});
if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) {
return 0.;
}
Expand Down
120 changes: 68 additions & 52 deletions pdns/dnsdistdist/dnsdist-lua-ffi.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,31 @@

#include "dnsdist.hh"

extern "C" {
extern "C"
{
#include "dnsdist-lua-ffi-interface.h"
}

#include "ext/luawrapper/include/LuaContext.hpp"

// dnsdist_ffi_dnsquestion_t is a lightuserdata
template<>
struct LuaContext::Pusher<dnsdist_ffi_dnsquestion_t*> {
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_dnsquestion_t* ptr) noexcept {
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
template <>
struct LuaContext::Pusher<dnsdist_ffi_dnsquestion_t*>
{
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_dnsquestion_t* ptr) noexcept
{
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
};

struct dnsdist_ffi_dnsquestion_t
{
dnsdist_ffi_dnsquestion_t(DNSQuestion* dq_): dq(dq_)
dnsdist_ffi_dnsquestion_t(DNSQuestion* dq_) :
dq(dq_)
{
}

Expand All @@ -63,20 +67,23 @@ struct dnsdist_ffi_dnsquestion_t
};

// dnsdist_ffi_dnsresponse_t is a lightuserdata
template<>
struct LuaContext::Pusher<dnsdist_ffi_dnsresponse_t*> {
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_dnsresponse_t* ptr) noexcept {
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
template <>
struct LuaContext::Pusher<dnsdist_ffi_dnsresponse_t*>
{
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_dnsresponse_t* ptr) noexcept
{
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
};

struct dnsdist_ffi_dnsresponse_t
{
dnsdist_ffi_dnsresponse_t(DNSResponse* dr_): dr(dr_)
dnsdist_ffi_dnsresponse_t(DNSResponse* dr_) :
dr(dr_)
{
}

Expand All @@ -85,44 +92,50 @@ struct dnsdist_ffi_dnsresponse_t
};

// dnsdist_ffi_server_t is a lightuserdata
template<>
struct LuaContext::Pusher<dnsdist_ffi_server_t*> {
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_server_t* ptr) noexcept {
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
template <>
struct LuaContext::Pusher<dnsdist_ffi_server_t*>
{
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_server_t* ptr) noexcept
{
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
};

struct dnsdist_ffi_server_t
{
dnsdist_ffi_server_t(const std::shared_ptr<DownstreamState>& server_): server(server_)
dnsdist_ffi_server_t(const std::shared_ptr<DownstreamState>& server_) :
server(server_)
{
}

const std::shared_ptr<DownstreamState>& server;
};

// dnsdist_ffi_servers_list_t is a lightuserdata
template<>
struct LuaContext::Pusher<dnsdist_ffi_servers_list_t*> {
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_servers_list_t* ptr) noexcept {
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
template <>
struct LuaContext::Pusher<dnsdist_ffi_servers_list_t*>
{
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_servers_list_t* ptr) noexcept
{
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
};

struct dnsdist_ffi_servers_list_t
{
dnsdist_ffi_servers_list_t(const ServerPolicy::NumberedServerVector& servers_): servers(servers_)
dnsdist_ffi_servers_list_t(const ServerPolicy::NumberedServerVector& servers_) :
servers(servers_)
{
ffiServers.reserve(servers.size());
for (const auto& server: servers) {
for (const auto& server : servers) {
ffiServers.push_back(dnsdist_ffi_server_t(server.second));
}
}
Expand All @@ -132,20 +145,23 @@ struct dnsdist_ffi_servers_list_t
};

// dnsdist_ffi_network_message_t is a lightuserdata
template<>
struct LuaContext::Pusher<dnsdist_ffi_network_message_t*> {
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_network_message_t* ptr) noexcept {
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
template <>
struct LuaContext::Pusher<dnsdist_ffi_network_message_t*>
{
static const int minSize = 1;
static const int maxSize = 1;

static PushedObject push(lua_State* state, dnsdist_ffi_network_message_t* ptr) noexcept
{
lua_pushlightuserdata(state, ptr);
return PushedObject{state, 1};
}
};

struct dnsdist_ffi_network_message_t
{
dnsdist_ffi_network_message_t(const std::string& payload_ ,const std::string& from_, uint16_t endpointID_): payload(payload_), from(from_), endpointID(endpointID_)
dnsdist_ffi_network_message_t(const std::string& payload_, const std::string& from_, uint16_t endpointID_) :
payload(payload_), from(from_), endpointID(endpointID_)
{
}

Expand Down
14 changes: 11 additions & 3 deletions pdns/dnsdistdist/dnsdist-lua-inspection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <algorithm>
#include <fcntl.h>
#include <iterator>

#include "dnsdist.hh"
#include "dnsdist-console.hh"
Expand Down Expand Up @@ -811,12 +813,18 @@ void setupLuaInspection(LuaContext& luaCtx)
boost::format fmt("%-35s\t%+11s");
g_outputBuffer.clear();
auto entries = *dnsdist::metrics::g_stats.entries.read_lock();
sort(entries.begin(), entries.end(),

// Filter entries to just the ones without label, for clearer output
std::vector<std::reference_wrapper<decltype(entries)::value_type>> unlabeledEntries;
std::copy_if(entries.begin(), entries.end(), std::back_inserter(unlabeledEntries), [](const decltype(entries)::value_type& triple) { return triple.d_labels.empty(); });

sort(unlabeledEntries.begin(), unlabeledEntries.end(),
[](const decltype(entries)::value_type& lhs, const decltype(entries)::value_type& rhs) {
return lhs.d_name < rhs.d_name;
});
boost::format flt(" %9.1f");
for (const auto& entry : entries) {
for (const auto& entryRef : unlabeledEntries) {
const auto& entry = entryRef.get();
string second;
if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
second = std::to_string((*val)->load());
Expand All @@ -828,7 +836,7 @@ void setupLuaInspection(LuaContext& luaCtx)
second = std::to_string((*func)(entry.d_name));
}

if (leftcolumn.size() < entries.size() / 2) {
if (leftcolumn.size() < unlabeledEntries.size() / 2) {
leftcolumn.push_back((fmt % entry.d_name % second).str());
}
else {
Expand Down
Loading

0 comments on commit 34ede92

Please sign in to comment.