stats.h revision 285206
118334Speter/*
2169689Skan * daemon/stats.h - collect runtime performance indicators.
3169689Skan *
4132718Skan * Copyright (c) 2007, NLnet Labs. All rights reserved.
518334Speter *
690075Sobrien * This software is open source.
718334Speter *
890075Sobrien * Redistribution and use in source and binary forms, with or without
990075Sobrien * modification, are permitted provided that the following conditions
1090075Sobrien * are met:
1190075Sobrien *
1218334Speter * Redistributions of source code must retain the above copyright notice,
1390075Sobrien * this list of conditions and the following disclaimer.
1490075Sobrien *
1590075Sobrien * Redistributions in binary form must reproduce the above copyright notice,
1690075Sobrien * this list of conditions and the following disclaimer in the documentation
1718334Speter * and/or other materials provided with the distribution.
1818334Speter *
1990075Sobrien * Neither the name of the NLNET LABS nor the names of its contributors may
20169689Skan * be used to endorse or promote products derived from this software without
21169689Skan * specific prior written permission.
2218334Speter *
2318334Speter * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24132718Skan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2550397Sobrien * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26132718Skan * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27132718Skan * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2818334Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2990075Sobrien * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3090075Sobrien * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31169689Skan * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32169689Skan * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3318334Speter * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3418334Speter */
35132718Skan
3618334Speter/**
3718334Speter * \file
3818334Speter *
3918334Speter * This file describes the data structure used to collect runtime performance
4018334Speter * numbers. These 'statistics' may be of interest to the operator.
4118334Speter */
4218334Speter
4318334Speter#ifndef DAEMON_STATS_H
44169689Skan#define DAEMON_STATS_H
45169689Skan#include "util/timehist.h"
4618334Speterstruct worker;
4718334Speterstruct config_file;
48169689Skanstruct comm_point;
49169689Skanstruct comm_reply;
50169689Skanstruct edns_data;
51169689Skanstruct sldns_buffer;
52169689Skan
5318334Speter/** number of qtype that is stored for in array */
5418334Speter#define STATS_QTYPE_NUM 256
5518334Speter/** number of qclass that is stored for in array */
5618334Speter#define STATS_QCLASS_NUM 256
57169689Skan/** number of rcodes in stats */
5818334Speter#define STATS_RCODE_NUM 16
5918334Speter/** number of opcodes in stats */
6018334Speter#define STATS_OPCODE_NUM 16
6118334Speter
6218334Speter/** per worker statistics */
6318334Speterstruct server_stats {
64169689Skan	/** number of queries from clients received. */
6518334Speter	size_t num_queries;
6618334Speter	/** number of queries that had a cache-miss. */
67169689Skan	size_t num_queries_missed_cache;
68169689Skan	/** number of prefetch queries - cachehits with prefetch */
6990075Sobrien	size_t num_queries_prefetch;
70169689Skan
71169689Skan	/**
7218334Speter	 * Sum of the querylistsize of the worker for
73169689Skan	 * every query that missed cache. To calculate average.
74169689Skan	 */
7518334Speter	size_t sum_query_list_size;
76169689Skan	/** max value of query list size reached. */
77169689Skan	size_t max_query_list_size;
78169689Skan
79169689Skan	/** Extended stats below (bool) */
80169689Skan	int extended;
81169689Skan
82169689Skan	/** qtype stats */
8318334Speter	size_t qtype[STATS_QTYPE_NUM];
84169689Skan	/** bigger qtype values not in array */
85169689Skan	size_t qtype_big;
8618334Speter	/** qclass stats */
8718334Speter	size_t qclass[STATS_QCLASS_NUM];
88169689Skan	/** bigger qclass values not in array */
8918334Speter	size_t qclass_big;
9090075Sobrien	/** query opcodes */
91169689Skan	size_t qopcode[STATS_OPCODE_NUM];
9290075Sobrien	/** number of queries over TCP */
9390075Sobrien	size_t qtcp;
94169689Skan	/** number of outgoing queries over TCP */
9518334Speter	size_t qtcp_outgoing;
96169689Skan	/** number of queries over IPv6 */
97169689Skan	size_t qipv6;
98169689Skan	/** number of queries with QR bit */
99169689Skan	size_t qbit_QR;
10018334Speter	/** number of queries with AA bit */
10118334Speter	size_t qbit_AA;
10218334Speter	/** number of queries with TC bit */
10318334Speter	size_t qbit_TC;
10418334Speter	/** number of queries with RD bit */
105169689Skan	size_t qbit_RD;
10618334Speter	/** number of queries with RA bit */
10718334Speter	size_t qbit_RA;
10818334Speter	/** number of queries with Z bit */
109169689Skan	size_t qbit_Z;
110169689Skan	/** number of queries with AD bit */
111169689Skan	size_t qbit_AD;
11218334Speter	/** number of queries with CD bit */
11318334Speter	size_t qbit_CD;
114169689Skan	/** number of queries with EDNS OPT record */
11518334Speter	size_t qEDNS;
11618334Speter	/** number of queries with EDNS with DO flag */
11750397Sobrien	size_t qEDNS_DO;
11818334Speter	/** answer rcodes */
119169689Skan	size_t ans_rcode[STATS_RCODE_NUM];
120169689Skan	/** answers with pseudo rcode 'nodata' */
121169689Skan	size_t ans_rcode_nodata;
122169689Skan	/** answers that were secure (AD) */
12318334Speter	size_t ans_secure;
12418334Speter	/** answers that were bogus (withheld as SERVFAIL) */
12518334Speter	size_t ans_bogus;
12618334Speter	/** rrsets marked bogus by validator */
12718334Speter	size_t rrset_bogus;
128169689Skan	/** unwanted traffic received on server-facing ports */
129169689Skan	size_t unwanted_replies;
130169689Skan	/** unwanted traffic received on client-facing ports */
131169689Skan	size_t unwanted_queries;
132169689Skan
133169689Skan	/** histogram data exported to array
134169689Skan	 * if the array is the same size, no data is lost, and
13518334Speter	 * if all histograms are same size (is so by default) then
136169689Skan	 * adding up works well. */
13718334Speter	size_t hist[NUM_BUCKETS_HIST];
13818334Speter
139169689Skan	/** number of message cache entries */
140169689Skan	size_t msg_cache_count;
141169689Skan	/** number of rrset cache entries */
14218334Speter	size_t rrset_cache_count;
14318334Speter	/** number of infra cache entries */
144169689Skan	size_t infra_cache_count;
14518334Speter	/** number of key cache entries */
14618334Speter	size_t key_cache_count;
14718334Speter};
14818334Speter
14918334Speter/**
150169689Skan * Statistics to send over the control pipe when asked
15118334Speter * This struct is made to be memcpied, sent in binary.
15218334Speter */
153169689Skanstruct stats_info {
154169689Skan	/** the thread stats */
15518334Speter	struct server_stats svr;
156169689Skan
157169689Skan	/** mesh stats: current number of states */
158169689Skan	size_t mesh_num_states;
159169689Skan	/** mesh stats: current number of reply (user) states */
16018334Speter	size_t mesh_num_reply_states;
16118334Speter	/** mesh stats: number of reply states overwritten with a new one */
16218334Speter	size_t mesh_jostled;
16318334Speter	/** mesh stats: number of incoming queries dropped */
16418334Speter	size_t mesh_dropped;
16518334Speter	/** mesh stats: replies sent */
16618334Speter	size_t mesh_replies_sent;
167169689Skan	/** mesh stats: sum of waiting times for the replies */
168169689Skan	struct timeval mesh_replies_sum_wait;
169169689Skan	/** mesh stats: median of waiting times for replies (in sec) */
17018334Speter	double mesh_time_median;
171169689Skan};
172169689Skan
173169689Skan/**
174169689Skan * Initialize server stats to 0.
175169689Skan * @param stats: what to init (this is alloced by the caller).
176169689Skan * @param cfg: with extended statistics option.
177169689Skan */
178169689Skanvoid server_stats_init(struct server_stats* stats, struct config_file* cfg);
179169689Skan
18018334Speter/** add query if it missed the cache */
18118334Spetervoid server_stats_querymiss(struct server_stats* stats, struct worker* worker);
182169689Skan
183169689Skan/** add query if was cached and also resulted in a prefetch */
184169689Skanvoid server_stats_prefetch(struct server_stats* stats, struct worker* worker);
185169689Skan
18618334Speter/** display the stats to the log */
187169689Skanvoid server_stats_log(struct server_stats* stats, struct worker* worker,
18818334Speter	int threadnum);
189169689Skan
190169689Skan/**
191169689Skan * Obtain the stats info for a given thread. Uses pipe to communicate.
192169689Skan * @param worker: the worker that is executing (the first worker).
193169689Skan * @param who: on who to get the statistics info.
194169689Skan * @param s: the stats block to fill in.
195169689Skan * @param reset: if stats can be reset.
196169689Skan */
197169689Skanvoid server_stats_obtain(struct worker* worker, struct worker* who,
198169689Skan	struct stats_info* s, int reset);
199169689Skan
200169689Skan/**
201169689Skan * Compile stats into structure for this thread worker.
202169689Skan * Also clears the statistics counters (if that is set by config file).
203169689Skan * @param worker: the worker to compile stats for, also the executing worker.
204169689Skan * @param s: stats block.
205169689Skan * @param reset: if true, depending on config stats are reset.
206169689Skan * 	if false, statistics are not reset.
207169689Skan */
208169689Skanvoid server_stats_compile(struct worker* worker, struct stats_info* s,
209169689Skan	int reset);
210169689Skan
211169689Skan/**
212169689Skan * Send stats over comm tube in reply to query cmd
213169689Skan * @param worker: this worker.
214169689Skan * @param reset: if true, depending on config stats are reset.
215169689Skan * 	if false, statistics are not reset.
216169689Skan */
21790075Sobrienvoid server_stats_reply(struct worker* worker, int reset);
218169689Skan
21990075Sobrien/**
22018334Speter * Addup stat blocks.
22118334Speter * @param total: sum of the two entries.
22218334Speter * @param a: to add to it.
22318334Speter */
22418334Spetervoid server_stats_add(struct stats_info* total, struct stats_info* a);
22518334Speter
22618334Speter/**
22718334Speter * Add stats for this query
22818334Speter * @param stats: the stats
22918334Speter * @param c: commpoint with type and buffer.
23018334Speter * @param qtype: query type
23118334Speter * @param qclass: query class
23218334Speter * @param edns: edns record
23318334Speter * @param repinfo: reply info with remote address
23418334Speter */
235169689Skanvoid server_stats_insquery(struct server_stats* stats, struct comm_point* c,
236169689Skan	uint16_t qtype, uint16_t qclass, struct edns_data* edns,
23718334Speter	struct comm_reply* repinfo);
23818334Speter
239169689Skan/**
240169689Skan * Add rcode for this query.
241169689Skan * @param stats: the stats
242169689Skan * @param buf: buffer with rcode. If buffer is length0: not counted.
243169689Skan */
244169689Skanvoid server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf);
245169689Skan
246169689Skan#endif /* DAEMON_STATS_H */
247169689Skan