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);
+ // TODO: add labels options?
+ auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName != nullptr ? std::optional<std::string>(customName) : std::nullopt, false);
return !result;
}
using std::thread;
-using update_metric_opts_t = LuaAssociativeTable<boost::variant<uint64_t, double, LuaAssociativeTable<std::string>>>;
+using update_metric_opts_t = LuaAssociativeTable<boost::variant<uint64_t, LuaAssociativeTable<std::string>>>;
+using declare_metric_opts_t = LuaAssociativeTable<boost::variant<bool, std::string>>;
static boost::tribool s_noLuaSideEffect;
newThread.detach();
});
- luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type, const std::string& description, boost::optional<std::string> customName) {
- auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional<std::string>(*customName) : std::nullopt);
+ luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type, const std::string& description, boost::optional<boost::variant<std::string, boost::optional<declare_metric_opts_t>>> opts) {
+ bool withLabels = false;
+ std::optional<std::string> customName = std::nullopt;
+ if (opts) {
+ auto* optCustomName = boost::get<std::string>(&opts.get());
+ if (optCustomName) {
+ customName = std::optional(*optCustomName);
+ }
+ if (!customName) {
+ boost::optional<declare_metric_opts_t> vars = boost::get<boost::optional<declare_metric_opts_t>>(opts.get());
+ getOptionalValue<std::string>(vars, "customName", customName);
+ getOptionalValue<bool>(vars, "withLabels", withLabels);
+ checkAllParametersConsumed("declareMetric", vars);
+ }
+ }
+ auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName, withLabels);
if (result) {
g_outputBuffer += *result + "\n";
errlog("Error in declareMetric: %s", *result);
struct Stats g_stats;
-std::optional<std::string> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName)
+std::optional<std::string> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName, bool withLabels)
{
if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) {
return std::string("Unable to declare metric '") + std::string(name) + std::string("': invalid name\n");
auto customCounters = s_customCounters.write_lock();
auto itp = customCounters->emplace(name, std::map<std::string, MutableCounter>());
if (itp.second) {
+ if (!withLabels) {
+ auto counter = itp.first->second.emplace("", MutableCounter());
+ g_stats.entries.write_lock()->emplace_back(Stats::EntryTriple{name, "", &counter.first->second.d_value});
+ }
dnsdist::prometheus::PrometheusMetricDefinition def{name, type, description, finalCustomName};
dnsdist::webserver::addMetricDefinition(def);
}
auto customGauges = s_customGauges.write_lock();
auto itp = customGauges->emplace(name, std::map<std::string, MutableGauge>());
if (itp.second) {
+ if (!withLabels) {
+ auto gauge = itp.first->second.emplace("", MutableGauge());
+ g_stats.entries.write_lock()->emplace_back(Stats::EntryTriple{name, "", &gauge.first->second.d_value});
+ }
dnsdist::prometheus::PrometheusMetricDefinition def{name, type, description, finalCustomName};
dnsdist::webserver::addMetricDefinition(def);
}
{
using Error = std::string;
-[[nodiscard]] std::optional<Error> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName);
+[[nodiscard]] std::optional<Error> declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional<std::string> customName, bool withLabels);
[[nodiscard]] std::variant<uint64_t, Error> incrementCustomCounter(const std::string_view& name, uint64_t step, const std::unordered_map<std::string, std::string>& labels);
[[nodiscard]] std::variant<uint64_t, Error> decrementCustomCounter(const std::string_view& name, uint64_t step, const std::unordered_map<std::string, std::string>& labels);
[[nodiscard]] std::variant<double, Error> setCustomGauge(const std::string_view& name, const double value, const std::unordered_map<std::string, std::string>& labels);