From aba8bbb6e3819b712885db211e78f1631cd6ab32 Mon Sep 17 00:00:00 2001 From: Julian Kornberger Date: Sat, 21 Jul 2018 21:55:08 +0100 Subject: [PATCH] Add collection of metrics Data can be retreived via D-Bus und U-Bus --- Makefile | 4 ++-- src/cache.c | 25 +++++++++++++------------ src/dbus.c | 31 +++++++++++++++++++++++++++++++ src/dnsmasq.h | 3 ++- src/forward.c | 8 ++++---- src/lease.c | 11 +++++++++-- src/rfc2131.c | 11 +++++++++++ 7 files changed, 72 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 583e33a..e71cf86 100644 --- a/Makefile +++ b/Makefile @@ -77,10 +77,10 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \ helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \ dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \ domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \ - poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o + poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o metrics.o hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \ - dns-protocol.h radv-protocol.h ip6addr.h + dns-protocol.h radv-protocol.h ip6addr.h metrics.h all : $(BUILDDIR) @cd $(BUILDDIR) && $(MAKE) \ diff --git a/src/cache.c b/src/cache.c index bdb998e..9e0923d 100644 --- a/src/cache.c +++ b/src/cache.c @@ -21,7 +21,7 @@ static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL; static struct crec *dhcp_spare = NULL; #endif static struct crec *new_chain = NULL; -static int cache_inserted = 0, cache_live_freed = 0, insert_error; +static int insert_error; static union bigname *big_free = NULL; static int bignames_left, hash_size; @@ -556,7 +556,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr, free_avail = 1; /* Must be free space now. */ cache_scan_free(cache_get_name(new), &free_addr, now, new->flags, NULL, NULL); - cache_live_freed++; + daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++; } else { @@ -641,7 +641,7 @@ void cache_end_insert(void) { cache_hash(new_chain); cache_link(new_chain); - cache_inserted++; + daemon->metrics[METRIC_DNS_CACHE_INSERTED]++; } new_chain = tmp; } @@ -1059,7 +1059,8 @@ void cache_reload(void) struct ds_config *ds; #endif - cache_inserted = cache_live_freed = 0; + daemon->metrics[METRIC_DNS_CACHE_INSERTED] = 0; + daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED] = 0; for (i=0; imetrics[METRIC_DNS_CACHE_INSERTED]); break; case TXT_STAT_EVICTIONS: - sprintf(buff+1, "%d", cache_live_freed); + sprintf(buff+1, "%d", daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]); break; case TXT_STAT_MISSES: - sprintf(buff+1, "%u", daemon->queries_forwarded); + sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]); break; case TXT_STAT_HITS: - sprintf(buff+1, "%u", daemon->local_answer); + sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]); break; #ifdef HAVE_AUTH case TXT_STAT_AUTH: - sprintf(buff+1, "%u", daemon->auth_answer); + sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_AUTH_ANSWERED]); break; #endif @@ -1446,11 +1447,11 @@ void dump_cache(time_t now) my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now); my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."), - daemon->cachesize, cache_live_freed, cache_inserted); + daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]); my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), - daemon->queries_forwarded, daemon->local_answer); + daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]); #ifdef HAVE_AUTH - my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->auth_answer); + my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]); #endif #ifdef HAVE_DNSSEC blockdata_report(); diff --git a/src/dbus.c b/src/dbus.c index 6a78b20..b8d5bec 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -85,6 +85,9 @@ const char* introspection_xml_template = " \n" " \n" #endif +" \n" +" \n" +" \n" " \n" "\n"; @@ -613,6 +616,30 @@ static DBusMessage *dbus_del_lease(DBusMessage* message) } #endif +static DBusMessage *dbus_get_metrics(DBusMessage* message) +{ + DBusMessage *reply = dbus_message_new_method_return(message); + DBusMessageIter array, dict, iter; + int i; + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{su}", &array); + + for (i = 0; i < __METRIC_MAX; i++) { + const char *key = get_metric_name(i); + dbus_uint32_t value = daemon->metrics[i]; + + dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict); + dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &key); + dbus_message_iter_append_basic(&dict, DBUS_TYPE_UINT32, &value); + dbus_message_iter_close_container(&array, &dict); + } + + dbus_message_iter_close_container(&iter, &array); + + return reply; +} + DBusHandlerResult message_handler(DBusConnection *connection, DBusMessage *message, void *user_data) @@ -680,6 +707,10 @@ DBusHandlerResult message_handler(DBusConnection *connection, reply = dbus_del_lease(message); } #endif + else if (strcmp(method, "GetMetrics") == 0) + { + reply = dbus_get_metrics(message); + } else if (strcmp(method, "ClearCache") == 0) clear_cache = 1; else diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 989a881..1d76552 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -57,6 +57,7 @@ #include "config.h" #include "ip6addr.h" +#include "metrics.h" typedef unsigned char u8; typedef unsigned short u16; @@ -1040,6 +1041,7 @@ extern struct daemon { char *dump_file; int dump_mask; unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; + u32 metrics[__METRIC_MAX]; #ifdef OPTION6_PREFIX_CLASS struct prefix_class *prefix_classes; #endif @@ -1060,7 +1062,6 @@ extern struct daemon { int dnssec_no_time_check; int back_to_the_future; #endif - unsigned int local_answer, queries_forwarded, auth_answer; struct frec *frec_list; struct serverfd *sfds; struct irec *interfaces; diff --git a/src/forward.c b/src/forward.c index 6581a4b..c692555 100644 --- a/src/forward.c +++ b/src/forward.c @@ -1553,7 +1553,7 @@ void receive_query(struct listener *listen, time_t now) { send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, m, &source_addr, &dst_addr, if_index); - daemon->auth_answer++; + daemon->metrics[METRIC_DNS_AUTH_ANSWERED]++; } } else @@ -1571,13 +1571,13 @@ void receive_query(struct listener *listen, time_t now) { send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, m, &source_addr, &dst_addr, if_index); - daemon->local_answer++; + daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++; } else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index, header, (size_t)n, now, NULL, ad_reqd, do_bit)) - daemon->queries_forwarded++; + daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]++; else - daemon->local_answer++; + daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]++; } } diff --git a/src/lease.c b/src/lease.c index 644af08..6012183 100644 --- a/src/lease.c +++ b/src/lease.c @@ -555,7 +555,9 @@ void lease_prune(struct dhcp_lease *target, time_t now) file_dirty = 1; if (lease->hostname) dns_dirty = 1; - + + daemon->metrics[lease->addr.s_addr ? METRIC_LEASES_PRUNED_4 : METRIC_LEASES_PRUNED_6]++; + *up = lease->next; /* unlink */ /* Put on old_leases list 'till we @@ -773,7 +775,10 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr) { struct dhcp_lease *lease = lease_allocate(); if (lease) - lease->addr = addr; + { + lease->addr = addr; + daemon->metrics[METRIC_LEASES_ALLOCATED_4]++; + } return lease; } @@ -788,6 +793,8 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type) lease->addr6 = *addrp; lease->flags |= lease_type; lease->iaid = 0; + + daemon->metrics[METRIC_LEASES_ALLOCATED_6]++; } return lease; diff --git a/src/rfc2131.c b/src/rfc2131.c index 8c418da..f68e702 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -626,6 +626,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, } } + daemon->metrics[METRIC_BOOTP]++; log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, message, mess->xid); return message ? 0 : dhcp_packet_size(mess, agent_id, real_end); @@ -928,6 +929,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, if ((pxe && !workaround) || !redirect4011) do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0); + daemon->metrics[METRIC_PXE]++; log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid); log_tags(tagif_netid, ntohl(mess->xid)); if (!ignore) @@ -962,6 +964,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ))) return 0; + daemon->metrics[METRIC_DHCPDECLINE]++; log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, NULL, daemon->dhcp_buff, mess->xid); if (lease && lease->addr.s_addr == option_addr(opt).s_addr) @@ -994,6 +997,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, else message = _("unknown lease"); + daemon->metrics[METRIC_DHCPRELEASE]++; log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, NULL, message, mess->xid); return 0; @@ -1060,6 +1064,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, message = _("no address available"); } + daemon->metrics[METRIC_DHCPDISCOVER]++; log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, NULL, message, mess->xid); if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid))) @@ -1080,6 +1085,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, goto rapid_commit; } + daemon->metrics[METRIC_DHCPOFFER]++; log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid); time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4)); @@ -1192,6 +1198,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, mess->yiaddr = mess->ciaddr; } + daemon->metrics[METRIC_DHCPREQUEST]++; log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid); rapid_commit: @@ -1265,6 +1272,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, if (message) { + daemon->metrics[rapid_commit ? METRIC_NOANSWER : METRIC_DHCPNAK]++; log_packet(rapid_commit ? "NOANSWER" : "DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid); /* rapid commit case: lease allocate failed but don't send DHCPNAK */ @@ -1426,6 +1434,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, else override = lease->override; + daemon->metrics[METRIC_DHCPACK]++; log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid); clear_packet(mess, end); @@ -1444,6 +1453,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, if (ignore || have_config(config, CONFIG_DISABLE)) message = _("ignored"); + daemon->metrics[METRIC_DHCPINFORM]++; log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, NULL, mess->xid); if (message || mess->ciaddr.s_addr == 0) @@ -1470,6 +1480,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, log_tags(tagif_netid, ntohl(mess->xid)); + daemon->metrics[METRIC_DHCPACK]++; log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid); if (lease)