--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+#include <atomic>
+#include <map>
+#include <string>
+
+#include "dnsname.hh"
+
+class ixfrdistStats {
+ public:
+ ixfrdistStats() {
+ progStats.startTime = time(nullptr);
+ }
+
+ std::string getStats() {
+ std::stringstream stats;
+ const std::string prefix = "ixfrdist_";
+
+ stats<<"# TYPE "<<prefix<<"uptime_seconds gauge"<<std::endl;
+ stats<<prefix<<"uptime_seconds "<<time(nullptr) - progStats.startTime<<std::endl;
+ stats<<"# TYPE "<<prefix<<"domains gauge"<<std::endl;
+ stats<<prefix<<"domains "<<domainStats.size()<<std::endl;
+
+ uint64_t numSOAinQueries{0}, numIXFRinQueries{0}, numAXFRinQueries{0}, numAXFRFailures{0}, numIXFRFailures{0};
+ for (auto const &d : domainStats) {
+ if(d.second.haveZone)
+ stats<<prefix<<"soa_serial{domain="<<d.first<<"} "<<d.second.currentSOA<<std::endl;
+ else
+ stats<<prefix<<"soa_serial{domain="<<d.first<<"} NaN"<<std::endl;
+
+ stats<<prefix<<"soa_inqueries{domain="<<d.first<<"} "<<d.second.numSOAinQueries<<std::endl;
+ numSOAinQueries += d.second.numSOAinQueries;
+
+ stats<<prefix<<"axfr_inqueries{domain="<<d.first<<"} "<<d.second.numAXFRinQueries<<std::endl;
+ numAXFRinQueries += d.second.numAXFRinQueries;
+
+ stats<<prefix<<"ixfr_inqueries{domain="<<d.first<<"} "<<d.second.numIXFRinQueries<<std::endl;
+ numIXFRinQueries += d.second.numIXFRinQueries;
+
+ stats<<prefix<<"axfr_failures{domain="<<d.first<<"} "<<d.second.numAXFRFailures<<std::endl;
+ numAXFRFailures += d.second.numAXFRFailures;
+
+ stats<<prefix<<"ixfr_failures{domain="<<d.first<<"} "<<d.second.numIXFRFailures<<std::endl;
+ numIXFRFailures += d.second.numIXFRFailures;
+ }
+
+ stats<<prefix<<"soa_inqueries "<<numSOAinQueries<<std::endl;
+ stats<<prefix<<"axfr_inqueries "<<numAXFRinQueries<<std::endl;
+ stats<<prefix<<"ixfr_inqueries "<<numIXFRinQueries<<std::endl;
+ stats<<prefix<<"axfr_failures "<<numAXFRFailures<<std::endl;
+ stats<<prefix<<"ixfr_failures "<<numIXFRFailures<<std::endl;
+ return stats.str();
+ }
+
+ void setSOASerial(const DNSName& d, const uint32_t serial) {
+ domainStats[d].currentSOA = serial;
+ domainStats[d].haveZone = true;
+ }
+ void incrementSOAChecks(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numSOAChecks += amount;
+ }
+ void incrementSOAChecksFailed(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numSOAChecksFailed += amount;
+ }
+ void incrementSOAinQueries(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numSOAinQueries += amount;
+ }
+ void incrementAXFRQueries(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numAXFRinQueries += amount;
+ }
+ void incrementIXFRQueries(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numIXFRinQueries += amount;
+ }
+ void incrementAXFRFailures(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numAXFRFailures += amount;
+ }
+ void incrementIXFRFailures(const DNSName& d, const uint64_t amount = 1) {
+ domainStats[d].numIXFRFailures += amount;
+ }
+ void registerDomain(const DNSName& d) {
+ domainStats[d].haveZone = false;
+ }
+ private:
+ class perDomainStat {
+ public:
+ bool haveZone;
+ std::atomic<uint32_t> currentSOA; // NOTE: this will wrongly be zero for unavailable zones
+
+ std::atomic<uint32_t> numSOAChecks;
+ std::atomic<uint32_t> numSOAChecksFailed;
+
+ std::atomic<uint64_t> numSOAinQueries;
+ std::atomic<uint64_t> numIXFRinQueries;
+ std::atomic<uint64_t> numAXFRinQueries;
+
+ std::atomic<uint64_t> numAXFRFailures;
+ std::atomic<uint64_t> numIXFRFailures;
+ };
+ class programStats {
+ public:
+ time_t startTime;
+ };
+
+ std::map<DNSName, perDomainStat> domainStats;
+ programStats progStats;
+};
#include "misc.hh"
#include "iputils.hh"
#include "logger.hh"
+#include "ixfrdist-stats.hh"
#include <yaml-cpp/yaml.h>
/* BEGIN Needed because of deeper dependencies */
static NetmaskGroup g_acl;
static bool g_compress = false;
+static ixfrdistStats g_stats;
+
static void handleSignal(int signum) {
g_log<<Logger::Notice<<"Got "<<strsignal(signum)<<" signal";
if (g_exiting) {
{
std::lock_guard<std::mutex> guard(g_soas_mutex);
g_soas[domain] = newInfo;
+ g_stats.setSOASerial(domain, newInfo->soa->d_st.serial);
}
void updateThread(const string& workdir, const uint16_t& keep, const uint16_t& axfrTimeout, const uint16_t& soaRetry) {
g_log<<Logger::Notice<<"Update Thread started"<<endl;
while (true) {
+ cout<<g_stats.getStats()<<endl;
if (g_exiting) {
g_log<<Logger::Notice<<"UpdateThread stopped"<<endl;
break;
set<ComboAddress> s;
s.insert(domain["master"].as<ComboAddress>());
g_domainConfigs[domain["domain"].as<DNSName>()].masters = s;
+ g_stats.registerDomain(domain["domain"].as<DNSName>());
}
for (const auto &addr : config["acl"].as<vector<string>>()) {