xref: /dragonfly/sbin/hammer/cmd_stats.c (revision 348a405d)
1 /*
2  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $DragonFly: src/sbin/hammer/cmd_stats.c,v 1.3 2008/07/14 20:28:07 dillon Exp $
35  */
36 
37 #include <math.h>
38 
39 #include "hammer.h"
40 
41 static void loaddelay(struct timespec *ts, const char *arg);
42 
43 #define bstats_title	\
44 "  elements iterations    lookups    inserts    deletes     splits"
45 #define iostats_title	\
46 "  file-rd   file-wr  dev-read dev-write  ino_rops  ino_wops ino_flush    commit      undo"
47 
48 static __inline
49 void
50 print_bstats(const struct libhammer_btree_stats *p1,
51 	     const struct libhammer_btree_stats *p2)
52 {
53 	printf("%10jd %10jd %10jd %10jd %10jd %10jd",
54 		(intmax_t)(p1->elements - p2->elements),
55 		(intmax_t)(p1->iterations - p2->iterations),
56 		(intmax_t)(p1->lookups - p2->lookups),
57 		(intmax_t)(p1->inserts - p2->inserts),
58 		(intmax_t)(p1->deletes - p2->deletes),
59 		(intmax_t)(p1->splits - p2->splits));
60 		/* no trailing \n */
61 }
62 
63 static __inline
64 void
65 print_iostats(const struct libhammer_io_stats *p1,
66 	      const struct libhammer_io_stats *p2)
67 {
68 	printf("%9jd %9jd %9jd %9jd %9jd %9jd %9jd %9jd %9jd",
69 		(intmax_t)(p1->file_reads - p2->file_reads),
70 		(intmax_t)(p1->file_writes - p2->file_writes),
71 		(intmax_t)(p1->dev_reads - p2->dev_reads),
72 		(intmax_t)(p1->dev_writes - p2->dev_writes),
73 		(intmax_t)(p1->file_iop_reads - p2->file_iop_reads),
74 		(intmax_t)(p1->file_iop_writes - p2->file_iop_writes),
75 		(intmax_t)(p1->inode_flushes - p2->inode_flushes),
76 		(intmax_t)(p1->commits - p2->commits),
77 		(intmax_t)(p1->undo - p2->undo));
78 		/* no trailing \n */
79 }
80 
81 void
82 hammer_cmd_bstats(char **av, int ac)
83 {
84 	struct libhammer_btree_stats bs, bsc;
85 	struct timespec delay = { 1, 0 };
86 	int count;
87 
88 	if (ac > 0)
89 		loaddelay(&delay, av[0]);
90 
91 	bzero(&bsc, sizeof(bsc));
92 	for (count = 0; ; ++count) {
93 		if (libhammer_btree_stats(&bs) < 0)
94 			err(1, "Failed to get information from HAMMER sysctls");
95 		if (count) {
96 			if ((count & 15) == 1)
97 				printf(bstats_title"\n");
98 			print_bstats(&bs, &bsc);
99 			printf("\n");
100 		}
101 		bcopy(&bs, &bsc, sizeof(bs));
102 		nanosleep(&delay, NULL);
103 	}
104 }
105 
106 void
107 hammer_cmd_iostats(char **av, int ac)
108 {
109 	struct libhammer_io_stats ios, iosc;
110 	struct timespec delay = { 1, 0 };
111 	int count;
112 
113 	if (ac > 0)
114 		loaddelay(&delay, av[0]);
115 
116 	bzero(&iosc, sizeof(iosc));
117 	for (count = 0; ; ++count) {
118 		if (libhammer_io_stats(&ios) < 0)
119 			err(1, "Failed to get information from HAMMER sysctls");
120 		if (count) {
121 			if ((count & 15) == 1)
122 				printf(iostats_title"\n");
123 			print_iostats(&ios, &iosc);
124 			printf("\n");
125 		}
126 		nanosleep(&delay, NULL);
127 		bcopy(&ios, &iosc, sizeof(ios));
128 	}
129 }
130 
131 void
132 hammer_cmd_stats(char **av, int ac)
133 {
134 	struct libhammer_btree_stats bs, bsc;
135 	struct libhammer_io_stats ios, iosc;
136 	struct timespec delay = { 1, 0 };
137 	int count;
138 
139 	if (ac > 0)
140 		loaddelay(&delay, av[0]);
141 
142 	bzero(&bsc, sizeof(bsc));
143 	bzero(&iosc, sizeof(iosc));
144 
145 	for (count = 0; ; ++count) {
146 		if (libhammer_btree_stats(&bs) || libhammer_io_stats(&ios))
147 			err(1, "Failed to get information from HAMMER sysctls");
148 		if (count) {
149 			if ((count & 15) == 1) {
150 				printf(bstats_title"\t"iostats_title"\n");
151 			}
152 			print_bstats(&bs, &bsc);
153 			printf("\t");
154 			print_iostats(&ios, &iosc);
155 			printf("\n");
156 		}
157 		bcopy(&bs, &bsc, sizeof(bs));
158 		bcopy(&ios, &iosc, sizeof(ios));
159 		nanosleep(&delay, NULL);
160 	}
161 }
162 
163 /*
164  * Convert a delay string (e.g. "0.1") into a timespec.
165  */
166 static
167 void
168 loaddelay(struct timespec *ts, const char *arg)
169 {
170 	double d;
171 
172 	d = strtod(arg, NULL);
173 	if (d < 0.001)
174 		d = 0.001;
175 	ts->tv_sec = (int)d;
176 	ts->tv_nsec = (int)(modf(d, &d) * 1000000000.0);
177 }
178