]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stat.cc
Fixes to remove queue length for fddn/ipcache
[thirdparty/squid.git] / src / stat.cc
CommitLineData
e5f6c5c2 1
30a4f2a8 2/*
e13ee7ad 3 * $Id: stat.cc,v 1.299 1998/11/13 21:02:10 rousskov Exp $
30a4f2a8 4 *
5 * DEBUG: section 18 Cache Manager Statistics
6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
30a4f2a8 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
019dd986 34 */
ed43818f 35
234967c9 36
44a47c6e 37#include "squid.h"
090089c4 38
ae94d28e 39#define DEBUG_OPENFD 1
40
1da3b90b 41typedef int STOBJFLT(const StoreEntry *);
42typedef struct {
43 StoreEntry *sentry;
44 int bucket;
45 STOBJFLT *filter;
46} StatObjectsState;
47
67508012 48/* LOCALS */
f5b8bbc4 49static const char *describeStatuses(const StoreEntry *);
f5b8bbc4 50static const char *describeTimestamps(const StoreEntry *);
f2908497 51static void statAvgTick(void *notused);
a0f32775 52static void statAvgDump(StoreEntry *, int minutes, int hours);
01aebf31 53#if STAT_GRAPHS
54static void statGraphDump(StoreEntry *);
55#endif
12cf1be2 56static void statCountersInit(StatCounters *);
1d803566 57static void statCountersInitSpecial(StatCounters *);
12cf1be2 58static void statCountersClean(StatCounters *);
2ac76861 59static void statCountersCopy(StatCounters * dest, const StatCounters * orig);
7d94ae33 60static double statMedianSvc(int, int);
a5a5de87 61static void statStoreEntry(StoreEntry * s, StoreEntry * e);
49ad0a8c 62static double statCPUUsage(int minutes);
ed7f5615 63static OBJH stat_io_get;
64static OBJH stat_objects_get;
65static OBJH stat_vmobjects_get;
ae94d28e 66#if DEBUG_OPENFD
67static OBJH statOpenfdObj;
68#endif
1da3b90b 69static EVH statObjects;
ed7f5615 70static OBJH info_get;
71static OBJH statFiledescriptors;
071a3ae7 72static OBJH statCountersDump;
a1e927f6 73static OBJH statPeerSelect;
26b164ac 74static OBJH statDigestBlob;
ed7f5615 75static OBJH statAvg5min;
45eb7f49 76static OBJH statAvg60min;
e9b5ead4 77static OBJH statUtilization;
ba4f8e5a 78static OBJH statCountersHistograms;
491a980b 79static double statRequestHitRatio(int minutes);
80static double statByteHitRatio(int minutes);
20882fb1 81
20882fb1 82#ifdef XMALLOC_STATISTICS
f5b8bbc4 83static void info_get_mallstat(int, int, StoreEntry *);
20882fb1 84#endif
30a4f2a8 85
a9113eb0 86StatCounters CountHist[N_COUNT_HIST];
d5649d9f 87static int NCountHist = 0;
a0f32775 88static StatCounters CountHourHist[N_COUNT_HOUR_HIST];
89static int NCountHourHist = 0;
90
5e29a294 91static void
e9b5ead4 92statUtilization(StoreEntry * e)
a0f32775 93{
94 storeAppendPrintf(e, "Cache Utilisation:\n");
95 storeAppendPrintf(e, "\n");
96 storeAppendPrintf(e, "Last 5 minutes:\n");
97 if (NCountHist >= 5)
98 statAvgDump(e, 5, 0);
99 else
100 storeAppendPrintf(e, "(no values recorded yet)\n");
101 storeAppendPrintf(e, "\n");
102 storeAppendPrintf(e, "Last 15 minutes:\n");
103 if (NCountHist >= 15)
104 statAvgDump(e, 15, 0);
105 else
106 storeAppendPrintf(e, "(no values recorded yet)\n");
107 storeAppendPrintf(e, "\n");
108 storeAppendPrintf(e, "Last hour:\n");
109 if (NCountHist >= 60)
110 statAvgDump(e, 60, 0);
111 else
112 storeAppendPrintf(e, "(no values recorded yet)\n");
113 storeAppendPrintf(e, "\n");
114 storeAppendPrintf(e, "Last 8 hours:\n");
115 if (NCountHourHist >= 8)
116 statAvgDump(e, 0, 8);
117 else
118 storeAppendPrintf(e, "(no values recorded yet)\n");
119 storeAppendPrintf(e, "\n");
120 storeAppendPrintf(e, "Last day:\n");
121 if (NCountHourHist >= 24)
122 statAvgDump(e, 0, 24);
123 else
124 storeAppendPrintf(e, "(no values recorded yet)\n");
125 storeAppendPrintf(e, "\n");
126 storeAppendPrintf(e, "Last 3 days:\n");
127 if (NCountHourHist >= 72)
128 statAvgDump(e, 0, 72);
129 else
130 storeAppendPrintf(e, "(no values recorded yet)\n");
131 storeAppendPrintf(e, "\n");
132 storeAppendPrintf(e, "Totals since cache startup:\n");
133 statCountersDump(e);
134}
f2908497 135
5e29a294 136static void
b8d8561b 137stat_io_get(StoreEntry * sentry)
30a4f2a8 138{
139 int i;
140
15576b6a 141 storeAppendPrintf(sentry, "HTTP I/O\n");
142 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Http.reads);
15576b6a 143 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 144 for (i = 0; i < 16; i++) {
15576b6a 145 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 146 i ? (1 << (i - 1)) + 1 : 1,
147 1 << i,
148 IOStats.Http.read_hist[i],
149 percent(IOStats.Http.read_hist[i], IOStats.Http.reads));
150 }
151
15576b6a 152 storeAppendPrintf(sentry, "\n");
153 storeAppendPrintf(sentry, "FTP I/O\n");
154 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Ftp.reads);
15576b6a 155 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 156 for (i = 0; i < 16; i++) {
15576b6a 157 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 158 i ? (1 << (i - 1)) + 1 : 1,
159 1 << i,
160 IOStats.Ftp.read_hist[i],
161 percent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads));
162 }
163
15576b6a 164 storeAppendPrintf(sentry, "\n");
165 storeAppendPrintf(sentry, "Gopher I/O\n");
166 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Gopher.reads);
15576b6a 167 storeAppendPrintf(sentry, "Read Histogram:\n");
56fa4cad 168 for (i = 0; i < 16; i++) {
15576b6a 169 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
56fa4cad 170 i ? (1 << (i - 1)) + 1 : 1,
171 1 << i,
172 IOStats.Gopher.read_hist[i],
173 percent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads));
174 }
175
15576b6a 176 storeAppendPrintf(sentry, "\n");
177 storeAppendPrintf(sentry, "WAIS I/O\n");
178 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Wais.reads);
15576b6a 179 storeAppendPrintf(sentry, "Read Histogram:\n");
56fa4cad 180 for (i = 0; i < 16; i++) {
15576b6a 181 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
56fa4cad 182 i ? (1 << (i - 1)) + 1 : 1,
183 1 << i,
184 IOStats.Wais.read_hist[i],
185 percent(IOStats.Wais.read_hist[i], IOStats.Wais.reads));
186 }
090089c4 187}
188
0ee4272b 189static const char *
fe4e214f 190describeStatuses(const StoreEntry * entry)
d1a43e28 191{
192 LOCAL_ARRAY(char, buf, 256);
56878878 193 snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
d1a43e28 194 storeStatusStr[entry->store_status],
195 memStatusStr[entry->mem_status],
196 swapStatusStr[entry->swap_status],
197 pingStatusStr[entry->ping_status]);
198 return buf;
199}
200
415e0dd2 201const char *
202storeEntryFlags(const StoreEntry * entry)
d1a43e28 203{
204 LOCAL_ARRAY(char, buf, 256);
315005bd 205 int flags = (int) entry->flags;
d1a43e28 206 char *t;
207 buf[0] = '\0';
7d94ae33 208 if (EBIT_TEST(flags, ENTRY_SPECIAL))
977c1c5b 209 strcat(buf, "SPECIAL,");
7d94ae33 210 if (EBIT_TEST(flags, ENTRY_REVALIDATE))
977c1c5b 211 strcat(buf, "REVALIDATE,");
7d94ae33 212 if (EBIT_TEST(flags, DELAY_SENDING))
977c1c5b 213 strcat(buf, "DELAY_SENDING,");
7d94ae33 214 if (EBIT_TEST(flags, RELEASE_REQUEST))
977c1c5b 215 strcat(buf, "RELEASE_REQUEST,");
7d94ae33 216 if (EBIT_TEST(flags, REFRESH_REQUEST))
977c1c5b 217 strcat(buf, "REFRESH_REQUEST,");
7d94ae33 218 if (EBIT_TEST(flags, ENTRY_CACHABLE))
977c1c5b 219 strcat(buf, "CACHABLE,");
7d94ae33 220 if (EBIT_TEST(flags, ENTRY_DISPATCHED))
977c1c5b 221 strcat(buf, "DISPATCHED,");
7d94ae33 222 if (EBIT_TEST(flags, KEY_PRIVATE))
977c1c5b 223 strcat(buf, "PRIVATE,");
7d94ae33 224 if (EBIT_TEST(flags, ENTRY_NEGCACHED))
977c1c5b 225 strcat(buf, "NEGCACHED,");
7d94ae33 226 if (EBIT_TEST(flags, ENTRY_VALIDATED))
977c1c5b 227 strcat(buf, "VALIDATED,");
7d94ae33 228 if (EBIT_TEST(flags, ENTRY_BAD_LENGTH))
977c1c5b 229 strcat(buf, "BAD_LENGTH,");
d1a43e28 230 if ((t = strrchr(buf, ',')))
231 *t = '\0';
232 return buf;
233}
234
0ee4272b 235static const char *
fe4e214f 236describeTimestamps(const StoreEntry * entry)
d1a43e28 237{
238 LOCAL_ARRAY(char, buf, 256);
56878878 239 snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
d1a43e28 240 (int) entry->timestamp,
241 (int) entry->lastref,
242 (int) entry->lastmod,
243 (int) entry->expires);
244 return buf;
245}
246
b8d8561b 247static void
a5a5de87 248statStoreEntry(StoreEntry * s, StoreEntry * e)
090089c4 249{
a5a5de87 250 MemObject *mem = e->mem_obj;
637ed800 251 int i;
252 struct _store_client *sc;
a5a5de87 253 storeAppendPrintf(s, "KEY %s\n", storeKeyText(e->key));
254 if (mem)
255 storeAppendPrintf(s, "\t%s %s\n",
256 RequestMethodStr[mem->method], mem->log_url);
257 storeAppendPrintf(s, "\t%s\n", describeStatuses(e));
415e0dd2 258 storeAppendPrintf(s, "\t%s\n", storeEntryFlags(e));
a5a5de87 259 storeAppendPrintf(s, "\t%s\n", describeTimestamps(e));
260 storeAppendPrintf(s, "\t%d locks, %d clients, %d refs\n",
261 (int) e->lock_count,
262 storePendingNClients(e),
263 (int) e->refcount);
264 storeAppendPrintf(s, "\tSwap File %#08X\n",
265 e->swap_file_number);
266 if (mem != NULL) {
267 storeAppendPrintf(s, "\tinmem_lo: %d\n", (int) mem->inmem_lo);
268 storeAppendPrintf(s, "\tinmem_hi: %d\n", (int) mem->inmem_hi);
269 storeAppendPrintf(s, "\tswapout: %d bytes done, %d queued, FD %d\n",
5f6ac48b 270 (int) mem->swapout.done_offset,
271 (int) mem->swapout.queue_offset,
637ed800 272 mem->swapout.fd);
49c0f46d 273 for (i = 0, sc = &mem->clients[i]; sc != NULL; sc = sc->next, i++) {
637ed800 274 if (sc->callback_data == NULL)
275 continue;
a5a5de87 276 storeAppendPrintf(s, "\tClient #%d\n", i);
277 storeAppendPrintf(s, "\t\tcopy_offset: %d\n",
637ed800 278 (int) sc->copy_offset);
a5a5de87 279 storeAppendPrintf(s, "\t\tseen_offset: %d\n",
637ed800 280 (int) sc->seen_offset);
a5a5de87 281 storeAppendPrintf(s, "\t\tcopy_size: %d\n",
637ed800 282 (int) sc->copy_size);
a5a5de87 283 storeAppendPrintf(s, "\t\tswapin_fd: %d\n",
637ed800 284 (int) sc->swapin_fd);
285 }
a5a5de87 286 }
287 storeAppendPrintf(s, "\n");
288}
289
290/* process objects list */
291static void
1da3b90b 292statObjects(void *data)
a5a5de87 293{
1da3b90b 294 StatObjectsState *state = data;
295 StoreEntry *e;
296 hash_link *link_ptr = NULL;
297 hash_link *link_next = NULL;
634b97dc 298 if (state->bucket >= store_hash_buckets) {
1da3b90b 299 storeComplete(state->sentry);
300 storeUnlockObject(state->sentry);
301 cbdataFree(state);
302 return;
7d9e8f15 303 } else if (state->sentry->store_status == STORE_ABORTED) {
304 storeUnlockObject(state->sentry);
305 cbdataFree(state);
306 return;
562b34ae 307 } else if (fwdCheckDeferRead(-1, state->sentry)) {
48a0f016 308 eventAdd("statObjects", statObjects, state, 0.1, 1);
562b34ae 309 return;
1da3b90b 310 }
311 storeBuffer(state->sentry);
312 debug(49, 3) ("statObjects: Bucket #%d\n", state->bucket);
313 link_next = hash_get_bucket(store_table, state->bucket);
314 while (NULL != (link_ptr = link_next)) {
315 link_next = link_ptr->next;
316 e = (StoreEntry *) link_ptr;
317 if (state->filter && 0 == state->filter(e))
a5a5de87 318 continue;
1da3b90b 319 statStoreEntry(state->sentry, e);
a5a5de87 320 }
634b97dc 321 state->bucket++;
1da3b90b 322 eventAdd("statObjects", statObjects, state, 0.0, 1);
323 storeBufferFlush(state->sentry);
a5a5de87 324}
325
5e29a294 326static void
1da3b90b 327statObjectsStart(StoreEntry * sentry, STOBJFLT * filter)
328{
329 StatObjectsState *state = xcalloc(1, sizeof(*state));
330 state->sentry = sentry;
331 state->filter = filter;
332 storeLockObject(sentry);
333 cbdataAdd(state, MEM_NONE);
334 eventAdd("statObjects", statObjects, state, 0.0, 1);
335}
336
337static void
338stat_objects_get(StoreEntry * sentry)
339{
340 statObjectsStart(sentry, NULL);
341}
342
343static int
344statObjectsVmFilter(const StoreEntry * e)
090089c4 345{
1da3b90b 346 return e->mem_obj ? 1 : 0;
6684fec0 347}
090089c4 348
5e29a294 349static void
1da3b90b 350stat_vmobjects_get(StoreEntry * sentry)
6684fec0 351{
1da3b90b 352 statObjectsStart(sentry, statObjectsVmFilter);
090089c4 353}
354
ae94d28e 355#if DEBUG_OPENFD
1da3b90b 356static int
357statObjectsOpenfdFilter(const StoreEntry * e)
358{
359 if (e->mem_obj == NULL)
360 return 0;
361 if (e->mem_obj->swapout.fd < 0)
362 return 0;;
363 return 1;
364}
365
ae94d28e 366static void
367statOpenfdObj(StoreEntry * sentry)
368{
1da3b90b 369 statObjectsStart(sentry, statObjectsOpenfdFilter);
ae94d28e 370}
1da3b90b 371
ae94d28e 372#endif
373
0a0bf5db 374#ifdef XMALLOC_STATISTICS
b8d8561b 375static void
0a0bf5db 376info_get_mallstat(int size, int number, StoreEntry * sentry)
30a4f2a8 377{
30a4f2a8 378 if (number > 0)
15576b6a 379 storeAppendPrintf(sentry, "\t%d = %d\n", size, number);
30a4f2a8 380}
381#endif
090089c4 382
0ee4272b 383static const char *
f1dc9b30 384fdRemoteAddr(const fde * f)
d51e52f5 385{
95d659f0 386 LOCAL_ARRAY(char, buf, 32);
4f92c80c 387 if (f->type != FD_SOCKET)
388 return null_string;
042461c3 389 snprintf(buf, 32, "%s.%d", f->ipaddr, (int) f->remote_port);
d2af9477 390 return buf;
d51e52f5 391}
392
5e29a294 393static void
b8d8561b 394statFiledescriptors(StoreEntry * sentry)
d51e52f5 395{
396 int i;
f1dc9b30 397 fde *f;
15576b6a 398 storeAppendPrintf(sentry, "Active file descriptors:\n");
399 storeAppendPrintf(sentry, "%-4s %-6s %-4s %-7s %-7s %-21s %s\n",
d51e52f5 400 "File",
401 "Type",
d51e52f5 402 "Tout",
4f92c80c 403 "Nread",
404 "Nwrite",
d51e52f5 405 "Remote Address",
406 "Description");
15576b6a 407 storeAppendPrintf(sentry, "---- ------ ---- ------- ------- --------------------- ------------------------------\n");
e83892e9 408 for (i = 0; i < Squid_MaxFD; i++) {
429fdbec 409 f = &fd_table[i];
5c5783a2 410 if (!f->open)
d51e52f5 411 continue;
15576b6a 412 storeAppendPrintf(sentry, "%4d %-6.6s %4d %7d %7d %-21s %s\n",
d2af9477 413 i,
22f5d1ca 414 fdTypeStr[f->type],
5f6ac48b 415 f->timeout_handler ? (int) (f->timeout - squid_curtime) / 60 : 0,
4f92c80c 416 f->bytes_read,
417 f->bytes_written,
418 fdRemoteAddr(f),
419 f->desc);
d51e52f5 420 }
d51e52f5 421}
422
5e29a294 423static void
03eb2f01 424info_get(StoreEntry * sentry)
090089c4 425{
090089c4 426 struct rusage rusage;
f2908497 427 double cputime;
428 double runtime;
88738790 429#if HAVE_MSTATS && HAVE_GNUMALLOC_H
430 struct mstats ms;
431#elif HAVE_MALLINFO
090089c4 432 struct mallinfo mp;
88738790 433 int t;
090089c4 434#endif
435
f2908497 436 runtime = tvSubDsec(squid_start, current_time);
437 if (runtime == 0.0)
438 runtime = 1.0;
15576b6a 439 storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
d51e52f5 440 version_string);
15576b6a 441 storeAppendPrintf(sentry, "Start Time:\t%s\n",
f2908497 442 mkrfc1123(squid_start.tv_sec));
15576b6a 443 storeAppendPrintf(sentry, "Current Time:\t%s\n",
f2908497 444 mkrfc1123(current_time.tv_sec));
15576b6a 445 storeAppendPrintf(sentry, "Connection information for %s:\n",
d51e52f5 446 appname);
98829f69 447 storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%u\n",
448 Counter.client_http.clients);
15576b6a 449 storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%u\n",
f2908497 450 Counter.client_http.requests);
15576b6a 451 storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%u\n",
f2908497 452 Counter.icp.pkts_recv);
15576b6a 453 storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%u\n",
f2908497 454 Counter.icp.pkts_sent);
2e8e29b8 455 storeAppendPrintf(sentry, "\tNumber of queued ICP replies:\t%u\n",
456 Counter.icp.replies_queued);
15576b6a 457 storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f%%\n",
88aad2e5 458 request_failure_ratio);
f2908497 459
15576b6a 460 storeAppendPrintf(sentry, "\tHTTP requests per minute:\t%.1f\n",
f2908497 461 Counter.client_http.requests / (runtime / 60.0));
15576b6a 462 storeAppendPrintf(sentry, "\tICP messages per minute:\t%.1f\n",
f2908497 463 (Counter.icp.pkts_sent + Counter.icp.pkts_recv) / (runtime / 60.0));
15576b6a 464 storeAppendPrintf(sentry, "\tSelect loop called: %d times, %0.3f ms avg\n",
f2908497 465 Counter.select_loops, 1000.0 * runtime / Counter.select_loops);
090089c4 466
15576b6a 467 storeAppendPrintf(sentry, "Cache information for %s:\n",
30a4f2a8 468 appname);
491a980b 469 storeAppendPrintf(sentry, "\tRequest Hit Ratios:\t5min: %3.1f%%, 60min: %3.1f%%\n",
470 statRequestHitRatio(5),
471 statRequestHitRatio(60));
472 storeAppendPrintf(sentry, "\tByte Hit Ratios:\t5min: %3.1f%%, 60min: %3.1f%%\n",
473 statByteHitRatio(5),
474 statByteHitRatio(60));
15576b6a 475 storeAppendPrintf(sentry, "\tStorage Swap size:\t%d KB\n",
c932b107 476 store_swap_size);
15576b6a 477 storeAppendPrintf(sentry, "\tStorage Mem size:\t%d KB\n",
5f6ac48b 478 (int) (store_mem_size >> 10));
15576b6a 479 storeAppendPrintf(sentry, "\tStorage LRU Expiration Age:\t%6.2f days\n",
52cd89fd 480 (double) storeExpiredReferenceAge() / 86400.0);
0faf70d0 481 storeAppendPrintf(sentry, "\tMean Object Size:\t%0.2f KB\n",
482 n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0);
15576b6a 483 storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%d\n",
f2908497 484 Counter.unlink.requests);
090089c4 485
b87b92fb 486 storeAppendPrintf(sentry, "Median Service Times (seconds) 5 min 60 min:\n");
487 storeAppendPrintf(sentry, "\tHTTP Requests (All): %8.5f %8.5f\n",
488 statMedianSvc(5, MEDIAN_HTTP) / 1000.0,
489 statMedianSvc(60, MEDIAN_HTTP) / 1000.0);
490 storeAppendPrintf(sentry, "\tCache Misses: %8.5f %8.5f\n",
491 statMedianSvc(5, MEDIAN_MISS) / 1000.0,
492 statMedianSvc(60, MEDIAN_MISS) / 1000.0);
493 storeAppendPrintf(sentry, "\tCache Hits: %8.5f %8.5f\n",
494 statMedianSvc(5, MEDIAN_HIT) / 1000.0,
495 statMedianSvc(60, MEDIAN_HIT) / 1000.0);
7c9c84ad 496 storeAppendPrintf(sentry, "\tNear Hits: %8.5f %8.5f\n",
497 statMedianSvc(5, MEDIAN_NH) / 1000.0,
498 statMedianSvc(60, MEDIAN_NH) / 1000.0);
b87b92fb 499 storeAppendPrintf(sentry, "\tNot-Modified Replies: %8.5f %8.5f\n",
500 statMedianSvc(5, MEDIAN_NM) / 1000.0,
501 statMedianSvc(60, MEDIAN_NM) / 1000.0);
502 storeAppendPrintf(sentry, "\tDNS Lookups: %8.5f %8.5f\n",
503 statMedianSvc(5, MEDIAN_DNS) / 1000.0,
504 statMedianSvc(60, MEDIAN_DNS) / 1000.0);
505 storeAppendPrintf(sentry, "\tICP Queries: %8.5f %8.5f\n",
506 statMedianSvc(5, MEDIAN_ICP_QUERY) / 1000000.0,
507 statMedianSvc(60, MEDIAN_ICP_QUERY) / 1000000.0);
508
f2908497 509 squid_getrusage(&rusage);
510 cputime = rusage_cputime(&rusage);
15576b6a 511 storeAppendPrintf(sentry, "Resource usage for %s:\n", appname);
512 storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", runtime);
513 storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", cputime);
514 storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
f2908497 515 dpercent(cputime, runtime));
979533fa 516 storeAppendPrintf(sentry, "\tCPU Usage, 5 minute avg:\t%.2f%%\n",
49ad0a8c 517 statCPUUsage(5));
518 storeAppendPrintf(sentry, "\tCPU Usage, 60 minute avg:\t%.2f%%\n",
519 statCPUUsage(60));
5f6ac48b 520 storeAppendPrintf(sentry, "\tMaximum Resident Size: %d KB\n",
f2908497 521 rusage_maxrss(&rusage));
5f6ac48b 522 storeAppendPrintf(sentry, "\tPage faults with physical i/o: %d\n",
f2908497 523 rusage_pagefaults(&rusage));
090089c4 524
88738790 525#if HAVE_MSTATS && HAVE_GNUMALLOC_H
526 ms = mstats();
15576b6a 527 storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",
88738790 528 appname);
15576b6a 529 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
88738790 530 ms.bytes_total >> 10);
15576b6a 531 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
88738790 532 ms.bytes_free >> 10, percent(ms.bytes_free, ms.bytes_total));
533#elif HAVE_MALLINFO
090089c4 534 mp = mallinfo();
15576b6a 535 storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",
d51e52f5 536 appname);
15576b6a 537 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
b560dd20 538 mp.arena >> 10);
15576b6a 539 storeAppendPrintf(sentry, "\tOrdinary blocks: %6d KB %6d blks\n",
30a4f2a8 540 mp.uordblks >> 10, mp.ordblks);
15576b6a 541 storeAppendPrintf(sentry, "\tSmall blocks: %6d KB %6d blks\n",
30a4f2a8 542 mp.usmblks >> 10, mp.smblks);
15576b6a 543 storeAppendPrintf(sentry, "\tHolding blocks: %6d KB %6d blks\n",
30a4f2a8 544 mp.hblkhd >> 10, mp.hblks);
15576b6a 545 storeAppendPrintf(sentry, "\tFree Small blocks: %6d KB\n",
30a4f2a8 546 mp.fsmblks >> 10);
15576b6a 547 storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6d KB\n",
30a4f2a8 548 mp.fordblks >> 10);
549 t = mp.uordblks + mp.usmblks + mp.hblkhd;
15576b6a 550 storeAppendPrintf(sentry, "\tTotal in use: %6d KB %d%%\n",
30a4f2a8 551 t >> 10, percent(t, mp.arena));
552 t = mp.fsmblks + mp.fordblks;
15576b6a 553 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
30a4f2a8 554 t >> 10, percent(t, mp.arena));
46c883ed 555#if HAVE_EXT_MALLINFO
15576b6a 556 storeAppendPrintf(sentry, "\tmax size of small blocks:\t%d\n", mp.mxfast);
557 storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%d\n",
090089c4 558 mp.nlblks);
15576b6a 559 storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%d\n", mp.grain);
560 storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%d\n"
090089c4 561 ,mp.uordbytes);
15576b6a 562 storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%d\n",
090089c4 563 mp.allocated);
15576b6a 564 storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%d\n",
090089c4 565 mp.treeoverhead);
46c883ed 566#endif /* HAVE_EXT_MALLINFO */
50bc2565 567#endif /* HAVE_MALLINFO */
5d1f3c82 568 storeAppendPrintf(sentry, "Memory accounted for:\n");
979533fa 569 storeAppendPrintf(sentry, "\tTotal accounted: %6d KB\n",
48a0f016 570 memTotalAllocated() >> 10);
090089c4 571
15576b6a 572 storeAppendPrintf(sentry, "File descriptor usage for %s:\n", appname);
573 storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n",
e83892e9 574 Squid_MaxFD);
15576b6a 575 storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4d\n",
429fdbec 576 Biggest_FD);
15576b6a 577 storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4d\n",
88738790 578 Number_FD);
15576b6a 579 storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4d\n",
88738790 580 Squid_MaxFD - Number_FD);
15576b6a 581 storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4d\n",
090089c4 582 RESERVED_FD);
c5f627c2 583 storeAppendPrintf(sentry, "\tDisk files open: %4d\n",
584 open_disk_fd);
090089c4 585
15576b6a 586 storeAppendPrintf(sentry, "Internal Data Structures:\n");
587 storeAppendPrintf(sentry, "\t%6d StoreEntries\n",
3f6c0fb2 588 memInUse(MEM_STOREENTRY));
15576b6a 589 storeAppendPrintf(sentry, "\t%6d StoreEntries with MemObjects\n",
3f6c0fb2 590 memInUse(MEM_MEMOBJECT));
15576b6a 591 storeAppendPrintf(sentry, "\t%6d Hot Object Cache Items\n",
59c4d35b 592 hot_obj_count);
5d406e78 593 storeAppendPrintf(sentry, "\t%6d Filemap bits set\n",
594 storeDirMapBitsInUse());
0b2e785a 595 storeAppendPrintf(sentry, "\t%6d on-disk objects\n",
596 n_disk_objects);
30a4f2a8 597
598#if XMALLOC_STATISTICS
15576b6a 599 storeAppendPrintf(sentry, "Memory allocation statistics\n");
30a4f2a8 600 malloc_statistics(info_get_mallstat, sentry);
601#endif
090089c4 602}
603
a7c05555 604#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
b8d8561b 605static void
a0f32775 606statAvgDump(StoreEntry * sentry, int minutes, int hours)
090089c4 607{
a7c05555 608 StatCounters *f;
609 StatCounters *l;
610 double dt;
611 double ct;
7ae52c25 612 double x;
a7c05555 613 assert(N_COUNT_HIST > 1);
a0f32775 614 assert(minutes > 0 || hours > 0);
a7c05555 615 f = &CountHist[0];
a0f32775 616 l = f;
617 if (minutes > 0 && hours == 0) {
618 /* checking minute readings ... */
619 if (minutes > N_COUNT_HIST - 1)
620 minutes = N_COUNT_HIST - 1;
621 l = &CountHist[minutes];
622 } else if (minutes == 0 && hours > 0) {
623 /* checking hour readings ... */
624 if (hours > N_COUNT_HOUR_HIST - 1)
625 hours = N_COUNT_HOUR_HIST - 1;
626 l = &CountHourHist[hours];
627 } else {
399e85ea 628 debug(18, 1) ("statAvgDump: Invalid args, minutes=%d, hours=%d\n",
629 minutes, hours);
a0f32775 630 return;
631 }
a7c05555 632 dt = tvSubDsec(l->timestamp, f->timestamp);
633 ct = f->cputime - l->cputime;
ee1679df 634
399e85ea 635 storeAppendPrintf(sentry, "sample_start_time = %d.%d (%s)\n",
5f6ac48b 636 (int) l->timestamp.tv_sec,
637 (int) l->timestamp.tv_usec,
cc1ae888 638 mkrfc1123(l->timestamp.tv_sec));
5843f24a 639 storeAppendPrintf(sentry, "sample_end_time = %d.%d (%s)\n",
640 (int) f->timestamp.tv_sec,
641 (int) f->timestamp.tv_usec,
cc1ae888 642 mkrfc1123(f->timestamp.tv_sec));
a0f32775 643
a7c05555 644 storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
645 XAVG(client_http.requests));
646 storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
647 XAVG(client_http.hits));
648 storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
649 XAVG(client_http.errors));
650 storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
651 XAVG(client_http.kbytes_in.kb));
652 storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
653 XAVG(client_http.kbytes_out.kb));
ee1679df 654
12cf1be2 655 x = statHistDeltaMedian(&l->client_http.all_svc_time,
ee1679df 656 &f->client_http.all_svc_time);
657 storeAppendPrintf(sentry, "client_http.all_median_svc_time = %f seconds\n",
658 x / 1000.0);
12cf1be2 659 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
ee1679df 660 &f->client_http.miss_svc_time);
661 storeAppendPrintf(sentry, "client_http.miss_median_svc_time = %f seconds\n",
662 x / 1000.0);
12cf1be2 663 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
ee1679df 664 &f->client_http.nm_svc_time);
665 storeAppendPrintf(sentry, "client_http.nm_median_svc_time = %f seconds\n",
666 x / 1000.0);
7c9c84ad 667 x = statHistDeltaMedian(&l->client_http.nh_svc_time,
668 &f->client_http.nh_svc_time);
669 storeAppendPrintf(sentry, "client_http.nh_median_svc_time = %f seconds\n",
670 x / 1000.0);
12cf1be2 671 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
ee1679df 672 &f->client_http.hit_svc_time);
673 storeAppendPrintf(sentry, "client_http.hit_median_svc_time = %f seconds\n",
7ae52c25 674 x / 1000.0);
071a3ae7 675
a0f32775 676 storeAppendPrintf(sentry, "server.all.requests = %f/sec\n",
677 XAVG(server.all.requests));
678 storeAppendPrintf(sentry, "server.all.errors = %f/sec\n",
679 XAVG(server.all.errors));
680 storeAppendPrintf(sentry, "server.all.kbytes_in = %f/sec\n",
681 XAVG(server.all.kbytes_in.kb));
682 storeAppendPrintf(sentry, "server.all.kbytes_out = %f/sec\n",
683 XAVG(server.all.kbytes_out.kb));
684
685 storeAppendPrintf(sentry, "server.http.requests = %f/sec\n",
686 XAVG(server.http.requests));
687 storeAppendPrintf(sentry, "server.http.errors = %f/sec\n",
688 XAVG(server.http.errors));
689 storeAppendPrintf(sentry, "server.http.kbytes_in = %f/sec\n",
690 XAVG(server.http.kbytes_in.kb));
691 storeAppendPrintf(sentry, "server.http.kbytes_out = %f/sec\n",
692 XAVG(server.http.kbytes_out.kb));
693
694 storeAppendPrintf(sentry, "server.ftp.requests = %f/sec\n",
695 XAVG(server.ftp.requests));
696 storeAppendPrintf(sentry, "server.ftp.errors = %f/sec\n",
697 XAVG(server.ftp.errors));
698 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %f/sec\n",
699 XAVG(server.ftp.kbytes_in.kb));
700 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %f/sec\n",
701 XAVG(server.ftp.kbytes_out.kb));
702
703 storeAppendPrintf(sentry, "server.other.requests = %f/sec\n",
704 XAVG(server.other.requests));
705 storeAppendPrintf(sentry, "server.other.errors = %f/sec\n",
706 XAVG(server.other.errors));
707 storeAppendPrintf(sentry, "server.other.kbytes_in = %f/sec\n",
708 XAVG(server.other.kbytes_in.kb));
709 storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
710 XAVG(server.other.kbytes_out.kb));
ee1679df 711
a7c05555 712 storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
713 XAVG(icp.pkts_sent));
714 storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
715 XAVG(icp.pkts_recv));
071a3ae7 716 storeAppendPrintf(sentry, "icp.queries_sent = %f/sec\n",
717 XAVG(icp.queries_sent));
718 storeAppendPrintf(sentry, "icp.replies_sent = %f/sec\n",
719 XAVG(icp.replies_sent));
720 storeAppendPrintf(sentry, "icp.queries_recv = %f/sec\n",
721 XAVG(icp.queries_recv));
722 storeAppendPrintf(sentry, "icp.replies_recv = %f/sec\n",
723 XAVG(icp.replies_recv));
2e8e29b8 724 storeAppendPrintf(sentry, "icp.replies_queued = %f/sec\n",
725 XAVG(icp.replies_queued));
071a3ae7 726 storeAppendPrintf(sentry, "icp.query_timeouts = %f/sec\n",
727 XAVG(icp.query_timeouts));
a7c05555 728 storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
729 XAVG(icp.kbytes_sent.kb));
730 storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
731 XAVG(icp.kbytes_recv.kb));
071a3ae7 732 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %f/sec\n",
733 XAVG(icp.q_kbytes_sent.kb));
734 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %f/sec\n",
735 XAVG(icp.r_kbytes_sent.kb));
736 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %f/sec\n",
737 XAVG(icp.q_kbytes_recv.kb));
738 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %f/sec\n",
739 XAVG(icp.r_kbytes_recv.kb));
12cf1be2 740 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
ee1679df 741 storeAppendPrintf(sentry, "icp.query_median_svc_time = %f seconds\n",
742 x / 1000000.0);
12cf1be2 743 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
ee1679df 744 storeAppendPrintf(sentry, "icp.reply_median_svc_time = %f seconds\n",
7ae52c25 745 x / 1000000.0);
12cf1be2 746 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
9973e9fe 747 storeAppendPrintf(sentry, "dns.median_svc_time = %f seconds\n",
901d8c30 748 x / 1000.0);
a7c05555 749 storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
750 XAVG(unlink.requests));
751 storeAppendPrintf(sentry, "page_faults = %f/sec\n",
752 XAVG(page_faults));
753 storeAppendPrintf(sentry, "select_loops = %f/sec\n",
754 XAVG(select_loops));
d239c2f5 755 storeAppendPrintf(sentry, "select_fds = %f/sec\n",
756 XAVG(select_fds));
757 storeAppendPrintf(sentry, "average_select_fd_period = %f/fd\n",
5942e8d4 758 f->select_fds > l->select_fds ?
d239c2f5 759 (f->select_time - l->select_time) / (f->select_fds - l->select_fds)
760 : 0.0);
26d6ee93 761 x = statHistDeltaMedian(&l->select_fds_hist, &f->select_fds_hist);
762 storeAppendPrintf(sentry, "median_select_fds = %f\n", x);
2c4f7ab2 763 storeAppendPrintf(sentry, "swap_files_cleaned = %f/sec\n",
764 XAVG(swap_files_cleaned));
bfae3379 765 storeAppendPrintf(sentry, "aborted_requests = %f/sec\n",
766 XAVG(aborted_requests));
886f2785 767
768#if HAVE_POLL
769 storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", XAVG(syscalls.polls));
770#else
771 storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", XAVG(syscalls.selects));
772#endif
773 storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", XAVG(syscalls.disk.opens));
774 storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", XAVG(syscalls.disk.closes));
775 storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", XAVG(syscalls.disk.reads));
776 storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", XAVG(syscalls.disk.writes));
777 storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", XAVG(syscalls.disk.seeks));
bfae3379 778 storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", XAVG(syscalls.disk.unlinks));
886f2785 779 storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", XAVG(syscalls.sock.accepts));
780 storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", XAVG(syscalls.sock.sockets));
781 storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", XAVG(syscalls.sock.connects));
782 storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", XAVG(syscalls.sock.binds));
783 storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", XAVG(syscalls.sock.closes));
784 storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", XAVG(syscalls.sock.reads));
785 storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", XAVG(syscalls.sock.writes));
786 storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", XAVG(syscalls.sock.recvfroms));
787 storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", XAVG(syscalls.sock.sendtos));
788
a7c05555 789 storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct);
790 storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt);
0e473d70 791 storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt));
090089c4 792}
793
979533fa 794
b8d8561b 795void
a7c05555 796statInit(void)
090089c4 797{
090089c4 798 int i;
a7c05555 799 debug(18, 5) ("statInit: Initializing...\n");
0e473d70 800 for (i = 0; i < N_COUNT_HIST; i++)
12cf1be2 801 statCountersInit(&CountHist[i]);
a0f32775 802 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
803 statCountersInit(&CountHourHist[i]);
12cf1be2 804 statCountersInit(&Counter);
52040193 805 eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
22f3fd98 806 cachemgrRegister("info",
807 "General Runtime Information",
1da3b90b 808 info_get, 0, 1);
22f3fd98 809 cachemgrRegister("filedescriptors",
810 "Process Filedescriptor Allocation",
1da3b90b 811 statFiledescriptors, 0, 1);
22f3fd98 812 cachemgrRegister("objects",
813 "All Cache Objects",
1da3b90b 814 stat_objects_get, 0, 0);
22f3fd98 815 cachemgrRegister("vm_objects",
816 "In-Memory and In-Transit Objects",
1da3b90b 817 stat_vmobjects_get, 0, 0);
ae94d28e 818#if DEBUG_OPENFD
819 cachemgrRegister("openfd_objects",
820 "Objects with Swapout files open",
1da3b90b 821 statOpenfdObj, 0, 0);
ae94d28e 822#endif
22f3fd98 823 cachemgrRegister("io",
824 "Server-side network read() size histograms",
1da3b90b 825 stat_io_get, 0, 1);
22f3fd98 826 cachemgrRegister("counters",
827 "Traffic and Resource Counters",
1da3b90b 828 statCountersDump, 0, 1);
a1e927f6 829 cachemgrRegister("peer_select",
830 "Peer Selection Algorithms",
1da3b90b 831 statPeerSelect, 0, 1);
26b164ac 832 cachemgrRegister("digest_stats",
833 "Cache Digest and ICP blob",
1da3b90b 834 statDigestBlob, 0, 1);
22f3fd98 835 cachemgrRegister("5min",
836 "5 Minute Average of Counters",
1da3b90b 837 statAvg5min, 0, 1);
45eb7f49 838 cachemgrRegister("60min",
839 "60 Minute Average of Counters",
1da3b90b 840 statAvg60min, 0, 1);
e9b5ead4 841 cachemgrRegister("utilization",
842 "Cache Utilization",
1da3b90b 843 statUtilization, 0, 1);
01aebf31 844#if STAT_GRAPHS
845 cachemgrRegister("graph_variables",
846 "Display cache metrics graphically",
1da3b90b 847 statGraphDump, 0, 1);
01aebf31 848#endif
ba4f8e5a 849 cachemgrRegister("histograms",
850 "Full Histogram Counts",
1da3b90b 851 statCountersHistograms, 0, 1);
090089c4 852}
f2908497 853
f2908497 854static void
855statAvgTick(void *notused)
856{
d5649d9f 857 StatCounters *t = &CountHist[0];
858 StatCounters *p = &CountHist[1];
f2908497 859 StatCounters *c = &Counter;
860 struct rusage rusage;
f720985e 861 eventAdd("statAvgTick", statAvgTick, NULL, COUNT_INTERVAL, 1);
20903cac 862 squid_getrusage(&rusage);
863 c->page_faults = rusage_pagefaults(&rusage);
864 c->cputime = rusage_cputime(&rusage);
d5649d9f 865 c->timestamp = current_time;
12cf1be2 866 /* even if NCountHist is small, we already Init()ed the tail */
2ac76861 867 statCountersClean(CountHist + N_COUNT_HIST - 1);
dbfed404 868 xmemmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
12cf1be2 869 statCountersCopy(t, c);
d5649d9f 870 NCountHist++;
a0f32775 871
872 if ((NCountHist % COUNT_INTERVAL) == 0) {
873 /* we have an hours worth of readings. store previous hour */
ffb245b5 874 StatCounters *t = &CountHourHist[0];
875 StatCounters *p = &CountHourHist[1];
e82d6d21 876 StatCounters *c = &CountHist[N_COUNT_HIST - 1];
ffb245b5 877 statCountersClean(CountHourHist + N_COUNT_HOUR_HIST - 1);
a0f32775 878 xmemmove(p, t, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
a887b8fa 879 statCountersCopy(t, c);
a0f32775 880 NCountHourHist++;
881 }
20903cac 882}
883
12cf1be2 884static void
2ac76861 885statCountersInit(StatCounters * C)
20903cac 886{
12cf1be2 887 assert(C);
1d803566 888 memset(C, 0, sizeof(*C));
12cf1be2 889 C->timestamp = current_time;
1d803566 890 statCountersInitSpecial(C);
891}
892
893/* add special cases here as they arrive */
894static void
2ac76861 895statCountersInitSpecial(StatCounters * C)
1d803566 896{
12cf1be2 897 /*
898 * HTTP svc_time hist is kept in milli-seconds; max of 3 hours.
899 */
900 statHistLogInit(&C->client_http.all_svc_time, 300, 0.0, 3600000.0 * 3.0);
901 statHistLogInit(&C->client_http.miss_svc_time, 300, 0.0, 3600000.0 * 3.0);
902 statHistLogInit(&C->client_http.nm_svc_time, 300, 0.0, 3600000.0 * 3.0);
7c9c84ad 903 statHistLogInit(&C->client_http.nh_svc_time, 300, 0.0, 3600000.0 * 3.0);
12cf1be2 904 statHistLogInit(&C->client_http.hit_svc_time, 300, 0.0, 3600000.0 * 3.0);
905 /*
906 * ICP svc_time hist is kept in micro-seconds; max of 1 minute.
907 */
908 statHistLogInit(&C->icp.query_svc_time, 300, 0.0, 1000000.0 * 60.0);
909 statHistLogInit(&C->icp.reply_svc_time, 300, 0.0, 1000000.0 * 60.0);
910 /*
911 * DNS svc_time hist is kept in milli-seconds; max of 10 minutes.
912 */
913 statHistLogInit(&C->dns.svc_time, 300, 0.0, 60000.0 * 10.0);
a1e927f6 914 /*
69c95dd3 915 * Cache Digest Stuff
a1e927f6 916 */
0c511722 917 statHistEnumInit(&C->cd.on_xition_count, CacheDigestHashFuncCount);
c6ecdbc3 918 statHistEnumInit(&C->comm_icp_incoming, INCOMING_ICP_MAX);
919 statHistEnumInit(&C->comm_http_incoming, INCOMING_HTTP_MAX);
26d6ee93 920 statHistIntInit(&C->select_fds_hist, SQUID_MAXFD);
0f5607d9 921}
922
12cf1be2 923/* add special cases here as they arrive */
5e29a294 924static void
2ac76861 925statCountersClean(StatCounters * C)
0f5607d9 926{
12cf1be2 927 assert(C);
928 statHistClean(&C->client_http.all_svc_time);
929 statHistClean(&C->client_http.miss_svc_time);
930 statHistClean(&C->client_http.nm_svc_time);
7c9c84ad 931 statHistClean(&C->client_http.nh_svc_time);
12cf1be2 932 statHistClean(&C->client_http.hit_svc_time);
933 statHistClean(&C->icp.query_svc_time);
934 statHistClean(&C->icp.reply_svc_time);
935 statHistClean(&C->dns.svc_time);
c135694e 936 statHistClean(&C->cd.on_xition_count);
c6ecdbc3 937 statHistClean(&C->comm_icp_incoming);
938 statHistClean(&C->comm_http_incoming);
26d6ee93 939 statHistClean(&C->select_fds_hist);
a7c05555 940}
941
12cf1be2 942/* add special cases here as they arrive */
5e29a294 943static void
2ac76861 944statCountersCopy(StatCounters * dest, const StatCounters * orig)
45eb7f49 945{
12cf1be2 946 assert(dest && orig);
1d803566 947 /* this should take care of all the fields, but "special" ones */
12cf1be2 948 memcpy(dest, orig, sizeof(*dest));
1d803566 949 /* prepare space where to copy special entries */
950 statCountersInitSpecial(dest);
951 /* now handle special cases */
952 /* note: we assert that histogram capacities do not change */
12cf1be2 953 statHistCopy(&dest->client_http.all_svc_time, &orig->client_http.all_svc_time);
954 statHistCopy(&dest->client_http.miss_svc_time, &orig->client_http.miss_svc_time);
955 statHistCopy(&dest->client_http.nm_svc_time, &orig->client_http.nm_svc_time);
7c9c84ad 956 statHistCopy(&dest->client_http.nh_svc_time, &orig->client_http.nh_svc_time);
12cf1be2 957 statHistCopy(&dest->client_http.hit_svc_time, &orig->client_http.hit_svc_time);
958 statHistCopy(&dest->icp.query_svc_time, &orig->icp.query_svc_time);
959 statHistCopy(&dest->icp.reply_svc_time, &orig->icp.reply_svc_time);
960 statHistCopy(&dest->dns.svc_time, &orig->dns.svc_time);
c135694e 961 statHistCopy(&dest->cd.on_xition_count, &orig->cd.on_xition_count);
c6ecdbc3 962 statHistCopy(&dest->comm_icp_incoming, &orig->comm_icp_incoming);
963 statHistCopy(&dest->comm_http_incoming, &orig->comm_http_incoming);
26d6ee93 964 statHistCopy(&dest->select_fds_hist, &orig->select_fds_hist);
45eb7f49 965}
966
071a3ae7 967static void
5d406e78 968statCountersHistograms(StoreEntry * sentry)
071a3ae7 969{
ba4f8e5a 970 StatCounters *f = &Counter;
071a3ae7 971 storeAppendPrintf(sentry, "client_http.all_svc_time histogram:\n");
972 statHistDump(&f->client_http.all_svc_time, sentry, NULL);
973 storeAppendPrintf(sentry, "client_http.miss_svc_time histogram:\n");
974 statHistDump(&f->client_http.miss_svc_time, sentry, NULL);
975 storeAppendPrintf(sentry, "client_http.nm_svc_time histogram:\n");
976 statHistDump(&f->client_http.nm_svc_time, sentry, NULL);
7c9c84ad 977 storeAppendPrintf(sentry, "client_http.nh_svc_time histogram:\n");
978 statHistDump(&f->client_http.nh_svc_time, sentry, NULL);
071a3ae7 979 storeAppendPrintf(sentry, "client_http.hit_svc_time histogram:\n");
980 statHistDump(&f->client_http.hit_svc_time, sentry, NULL);
071a3ae7 981 storeAppendPrintf(sentry, "icp.query_svc_time histogram:\n");
982 statHistDump(&f->icp.query_svc_time, sentry, NULL);
983 storeAppendPrintf(sentry, "icp.reply_svc_time histogram:\n");
984 statHistDump(&f->icp.reply_svc_time, sentry, NULL);
985 storeAppendPrintf(sentry, "dns.svc_time histogram:\n");
986 statHistDump(&f->dns.svc_time, sentry, NULL);
071a3ae7 987}
988
12cf1be2 989static void
990statCountersDump(StoreEntry * sentry)
7ae52c25 991{
12cf1be2 992 StatCounters *f = &Counter;
993 struct rusage rusage;
994 squid_getrusage(&rusage);
995 f->page_faults = rusage_pagefaults(&rusage);
996 f->cputime = rusage_cputime(&rusage);
997
a0f32775 998 storeAppendPrintf(sentry, "sample_time = %d.%d (%s)\n",
5f6ac48b 999 (int) f->timestamp.tv_sec,
1000 (int) f->timestamp.tv_usec,
a0f32775 1001 mkrfc1123(f->timestamp.tv_sec));
12cf1be2 1002 storeAppendPrintf(sentry, "client_http.requests = %d\n",
1003 f->client_http.requests);
1004 storeAppendPrintf(sentry, "client_http.hits = %d\n",
1005 f->client_http.hits);
1006 storeAppendPrintf(sentry, "client_http.errors = %d\n",
1007 f->client_http.errors);
1008 storeAppendPrintf(sentry, "client_http.kbytes_in = %d\n",
1009 (int) f->client_http.kbytes_in.kb);
1010 storeAppendPrintf(sentry, "client_http.kbytes_out = %d\n",
1011 (int) f->client_http.kbytes_out.kb);
c68e9c6b 1012 storeAppendPrintf(sentry, "client_http.hit_kbytes_out = %d\n",
1013 (int) f->client_http.hit_kbytes_out.kb);
0567f2a6 1014
a0f32775 1015 storeAppendPrintf(sentry, "server.all.requests = %d\n",
1016 (int) f->server.all.requests);
1017 storeAppendPrintf(sentry, "server.all.errors = %d\n",
1018 (int) f->server.all.errors);
1019 storeAppendPrintf(sentry, "server.all.kbytes_in = %d\n",
1020 (int) f->server.all.kbytes_in.kb);
1021 storeAppendPrintf(sentry, "server.all.kbytes_out = %d\n",
1022 (int) f->server.all.kbytes_out.kb);
1023
1024 storeAppendPrintf(sentry, "server.http.requests = %d\n",
1025 (int) f->server.http.requests);
1026 storeAppendPrintf(sentry, "server.http.errors = %d\n",
1027 (int) f->server.http.errors);
1028 storeAppendPrintf(sentry, "server.http.kbytes_in = %d\n",
1029 (int) f->server.http.kbytes_in.kb);
1030 storeAppendPrintf(sentry, "server.http.kbytes_out = %d\n",
1031 (int) f->server.http.kbytes_out.kb);
1032
1033 storeAppendPrintf(sentry, "server.ftp.requests = %d\n",
1034 (int) f->server.ftp.requests);
1035 storeAppendPrintf(sentry, "server.ftp.errors = %d\n",
1036 (int) f->server.ftp.errors);
1037 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %d\n",
1038 (int) f->server.ftp.kbytes_in.kb);
1039 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %d\n",
1040 (int) f->server.ftp.kbytes_out.kb);
1041
1042 storeAppendPrintf(sentry, "server.other.requests = %d\n",
1043 (int) f->server.other.requests);
1044 storeAppendPrintf(sentry, "server.other.errors = %d\n",
1045 (int) f->server.other.errors);
1046 storeAppendPrintf(sentry, "server.other.kbytes_in = %d\n",
1047 (int) f->server.other.kbytes_in.kb);
1048 storeAppendPrintf(sentry, "server.other.kbytes_out = %d\n",
1049 (int) f->server.other.kbytes_out.kb);
12cf1be2 1050
1051 storeAppendPrintf(sentry, "icp.pkts_sent = %d\n",
1052 f->icp.pkts_sent);
1053 storeAppendPrintf(sentry, "icp.pkts_recv = %d\n",
1054 f->icp.pkts_recv);
071a3ae7 1055 storeAppendPrintf(sentry, "icp.queries_sent = %d\n",
1056 f->icp.queries_sent);
1057 storeAppendPrintf(sentry, "icp.replies_sent = %d\n",
1058 f->icp.replies_sent);
1059 storeAppendPrintf(sentry, "icp.queries_recv = %d\n",
1060 f->icp.queries_recv);
1061 storeAppendPrintf(sentry, "icp.replies_recv = %d\n",
1062 f->icp.replies_recv);
1063 storeAppendPrintf(sentry, "icp.query_timeouts = %d\n",
1064 f->icp.query_timeouts);
2e8e29b8 1065 storeAppendPrintf(sentry, "icp.replies_queued = %d\n",
1066 f->icp.replies_queued);
12cf1be2 1067 storeAppendPrintf(sentry, "icp.kbytes_sent = %d\n",
1068 (int) f->icp.kbytes_sent.kb);
1069 storeAppendPrintf(sentry, "icp.kbytes_recv = %d\n",
1070 (int) f->icp.kbytes_recv.kb);
071a3ae7 1071 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %d\n",
1072 (int) f->icp.q_kbytes_sent.kb);
1073 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %d\n",
1074 (int) f->icp.r_kbytes_sent.kb);
1075 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %d\n",
1076 (int) f->icp.q_kbytes_recv.kb);
1077 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %d\n",
1078 (int) f->icp.r_kbytes_recv.kb);
0567f2a6 1079
6cfa8966 1080#if USE_CACHE_DIGESTS
071a3ae7 1081 storeAppendPrintf(sentry, "icp.times_used = %d\n",
5d406e78 1082 f->icp.times_used);
071a3ae7 1083 storeAppendPrintf(sentry, "cd.times_used = %d\n",
5d406e78 1084 f->cd.times_used);
00485c29 1085 storeAppendPrintf(sentry, "cd.msgs_sent = %d\n",
1086 f->cd.msgs_sent);
1087 storeAppendPrintf(sentry, "cd.msgs_recv = %d\n",
1088 f->cd.msgs_recv);
071a3ae7 1089 storeAppendPrintf(sentry, "cd.memory = %d\n",
5d406e78 1090 (int) f->cd.memory.kb);
522b517b 1091 storeAppendPrintf(sentry, "cd.local_memory = %d\n",
5d406e78 1092 (int) (store_digest ? store_digest->mask_size / 1024 : 0));
00485c29 1093 storeAppendPrintf(sentry, "cd.kbytes_sent = %d\n",
1094 (int) f->cd.kbytes_sent.kb);
1095 storeAppendPrintf(sentry, "cd.kbytes_recv = %d\n",
1096 (int) f->cd.kbytes_recv.kb);
0567f2a6 1097#endif
1098
12cf1be2 1099 storeAppendPrintf(sentry, "unlink.requests = %d\n",
1100 f->unlink.requests);
1101 storeAppendPrintf(sentry, "page_faults = %d\n",
1102 f->page_faults);
1103 storeAppendPrintf(sentry, "select_loops = %d\n",
1104 f->select_loops);
1105 storeAppendPrintf(sentry, "cpu_time = %f\n",
1106 f->cputime);
1107 storeAppendPrintf(sentry, "wall_time = %f\n",
1108 tvSubDsec(f->timestamp, current_time));
2c4f7ab2 1109 storeAppendPrintf(sentry, "swap_files_cleaned = %d\n",
1110 f->swap_files_cleaned);
bfae3379 1111 storeAppendPrintf(sentry, "aborted_requests = %d\n",
1112 f->aborted_requests);
7ae52c25 1113}
1114
d2db411c 1115void
1116statFreeMemory(void)
1117{
1118 int i;
1119 for (i = 0; i < N_COUNT_HIST; i++)
1120 statCountersClean(&CountHist[i]);
1121 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
1122 statCountersClean(&CountHourHist[i]);
1123}
1124
5e29a294 1125static void
a1e927f6 1126statPeerSelect(StoreEntry * sentry)
1127{
6cfa8966 1128#if USE_CACHE_DIGESTS
a1e927f6 1129 StatCounters *f = &Counter;
1130 peer *peer;
1131 const int tot_used = f->cd.times_used + f->icp.times_used;
1132
1133 /* totals */
1134 cacheDigestGuessStatsReport(&f->cd.guess, sentry, "all peers");
1135 /* per-peer */
1136 storeAppendPrintf(sentry, "\nPer-peer statistics:\n");
1137 for (peer = getFirstPeer(); peer; peer = getNextPeer(peer)) {
e13ee7ad 1138 if (peer->digest)
1139 peerDigestStatsReport(peer->digest, sentry);
1543ab6c 1140 else
e13ee7ad 1141 storeAppendPrintf(sentry, "\nNo peer digest from %s\n", peer->host);
7ea5d333 1142 storeAppendPrintf(sentry, "\n");
a1e927f6 1143 }
1144
1145 storeAppendPrintf(sentry, "\nAlgorithm usage:\n");
1146 storeAppendPrintf(sentry, "Cache Digest: %7d (%3d%%)\n",
1147 f->cd.times_used, xpercentInt(f->cd.times_used, tot_used));
1148 storeAppendPrintf(sentry, "Icp: %7d (%3d%%)\n",
1149 f->icp.times_used, xpercentInt(f->icp.times_used, tot_used));
1150 storeAppendPrintf(sentry, "Total: %7d (%3d%%)\n",
1151 tot_used, xpercentInt(tot_used, tot_used));
1152#else
1153 storeAppendPrintf(sentry, "peer digests are disabled; no stats is available.\n");
1154#endif
1155}
1156
1157static void
26b164ac 1158statDigestBlob(StoreEntry * sentry)
1159{
071a3ae7 1160 storeAppendPrintf(sentry, "\nCounters:\n");
1161 statCountersDump(sentry);
86e2a291 1162 storeAppendPrintf(sentry, "\n5 Min Averages:\n");
1163 statAvgDump(sentry, 5, 0);
071a3ae7 1164 storeAppendPrintf(sentry, "\nHistograms:\n");
1165 statCountersHistograms(sentry);
1166 storeAppendPrintf(sentry, "\nPeer Digests:\n");
26b164ac 1167 statPeerSelect(sentry);
588d9545 1168 storeAppendPrintf(sentry, "\nLocal Digest:\n");
26b164ac 1169 storeDigestReport(sentry);
1170}
1171
5e29a294 1172static void
12cf1be2 1173statAvg5min(StoreEntry * e)
7ae52c25 1174{
a0f32775 1175 statAvgDump(e, 5, 0);
7ae52c25 1176}
1177
5e29a294 1178static void
12cf1be2 1179statAvg60min(StoreEntry * e)
7ae52c25 1180{
a0f32775 1181 statAvgDump(e, 60, 0);
7ae52c25 1182}
1183
7d94ae33 1184static double
b87b92fb 1185statMedianSvc(int interval, int which)
a9113eb0 1186{
1187 StatCounters *f;
1188 StatCounters *l;
1189 double x;
f8d264b8 1190 assert(interval > 0);
1191 if (interval > N_COUNT_HIST - 1)
1192 interval = N_COUNT_HIST - 1;
a9113eb0 1193 f = &CountHist[0];
1194 l = &CountHist[interval];
ee1679df 1195 assert(f);
1196 assert(l);
a9113eb0 1197 switch (which) {
b87b92fb 1198 case MEDIAN_HTTP:
12cf1be2 1199 x = statHistDeltaMedian(&l->client_http.all_svc_time, &f->client_http.all_svc_time);
ee1679df 1200 break;
b87b92fb 1201 case MEDIAN_HIT:
1202 x = statHistDeltaMedian(&l->client_http.hit_svc_time, &f->client_http.hit_svc_time);
1203 break;
1204 case MEDIAN_MISS:
1205 x = statHistDeltaMedian(&l->client_http.miss_svc_time, &f->client_http.miss_svc_time);
1206 break;
1207 case MEDIAN_NM:
1208 x = statHistDeltaMedian(&l->client_http.nm_svc_time, &f->client_http.nm_svc_time);
1209 break;
7c9c84ad 1210 case MEDIAN_NH:
1211 x = statHistDeltaMedian(&l->client_http.nh_svc_time, &f->client_http.nh_svc_time);
1212 break;
b87b92fb 1213 case MEDIAN_ICP_QUERY:
12cf1be2 1214 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
ee1679df 1215 break;
b87b92fb 1216 case MEDIAN_DNS:
12cf1be2 1217 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
ee1679df 1218 break;
a9113eb0 1219 default:
ee1679df 1220 debug(49, 5) ("get_median_val: unknown type.\n");
1221 x = 0;
a9113eb0 1222 }
b87b92fb 1223 return x;
1224}
1225
1226/*
1227 * SNMP wants ints, ick
1228 */
1229int
1230get_median_svc(int interval, int which)
1231{
b644367b 1232 return (int) statMedianSvc(interval, which);
a9113eb0 1233}
451b07c5 1234
1235StatCounters *
1236snmpStatGet(int minutes)
1237{
2ac76861 1238 return &CountHist[minutes];
451b07c5 1239}
01aebf31 1240
1f3c4622 1241int
1242stat5minClientRequests(void)
1243{
5999b776 1244 assert(N_COUNT_HIST > 5);
1245 return Counter.client_http.requests - CountHist[5].client_http.requests;
1f3c4622 1246}
1247
49ad0a8c 1248static double
1249statCPUUsage(int minutes)
979533fa 1250{
49ad0a8c 1251 assert(minutes < N_COUNT_HIST);
1252 return dpercent(CountHist[0].cputime - CountHist[minutes].cputime,
1253 tvSubDsec(CountHist[minutes].timestamp, CountHist[0].timestamp));
979533fa 1254}
01aebf31 1255
491a980b 1256static double
1257statRequestHitRatio(int minutes)
1258{
1259 assert(minutes < N_COUNT_HIST);
1260 return dpercent(CountHist[0].client_http.hits -
1261 CountHist[minutes].client_http.hits,
1262 CountHist[0].client_http.requests -
1263 CountHist[minutes].client_http.requests);
1264}
1265
1266static double
1267statByteHitRatio(int minutes)
1268{
1269 size_t s;
1270 size_t c;
1271 assert(minutes < N_COUNT_HIST);
1272 c = CountHist[0].client_http.kbytes_out.kb - CountHist[minutes].client_http.kbytes_out.kb;
1273 s = CountHist[0].server.all.kbytes_in.kb - CountHist[minutes].server.all.kbytes_in.kb;
94e56ef7 1274 /* size_t might be unsigned */
1275 if (c > s)
7d47d8e6 1276 return dpercent(c - s, c);
94e56ef7 1277 else
7d47d8e6 1278 return (-1.0 * dpercent(s - c, c));
491a980b 1279}
1280
01aebf31 1281#if STAT_GRAPHS
1282/*
1283 * urgh, i don't like these, but they do cut the amount of code down immensely
1284 */
1285
1286#define GRAPH_PER_MIN(Y) \
1287 for (i=0;i<(N_COUNT_HIST-2);i++) { \
1288 dt = tvSubDsec(CountHist[i].timestamp, CountHist[i+1].timestamp); \
1289 if (dt <= 0.0) \
1290 break; \
1291 storeAppendPrintf(e, "%lu,%0.2f:", \
1292 CountHist[i].timestamp.tv_sec, \
1293 ((CountHist[i].Y - CountHist[i+1].Y) / dt)); \
1294 }
1295
1296#define GRAPH_PER_HOUR(Y) \
1297 for (i=0;i<(N_COUNT_HOUR_HIST-2);i++) { \
1298 dt = tvSubDsec(CountHourHist[i].timestamp, CountHourHist[i+1].timestamp); \
1299 if (dt <= 0.0) \
1300 break; \
1301 storeAppendPrintf(e, "%lu,%0.2f:", \
1302 CountHourHist[i].timestamp.tv_sec, \
1303 ((CountHourHist[i].Y - CountHourHist[i+1].Y) / dt)); \
1304 }
1305
1306#define GRAPH_TITLE(X,Y) storeAppendPrintf(e,"%s\t%s\t",X,Y);
1307#define GRAPH_END storeAppendPrintf(e,"\n");
1308
1309#define GENGRAPH(X,Y,Z) \
1310 GRAPH_TITLE(Y,Z) \
1311 GRAPH_PER_MIN(X) \
1312 GRAPH_PER_HOUR(X) \
1313 GRAPH_END
1314
1315static void
1316statGraphDump(StoreEntry * e)
1317{
1318 int i;
1319 double dt;
1320
1321 GENGRAPH(client_http.requests, "client_http.requests", "Client HTTP requests/sec");
1322 GENGRAPH(client_http.hits, "client_http.hits", "Client HTTP hits/sec");
1323 GENGRAPH(client_http.errors, "client_http.errors", "Client HTTP errors/sec");
1324 GENGRAPH(client_http.kbytes_in.kb, "client_http.kbytes_in", "Client HTTP kbytes_in/sec");
1325 GENGRAPH(client_http.kbytes_out.kb, "client_http.kbytes_out", "Client HTTP kbytes_out/sec");
1326
1327 /* XXX todo: http median service times */
1328
1329 GENGRAPH(server.all.requests, "server.all.requests", "Server requests/sec");
1330 GENGRAPH(server.all.errors, "server.all.errors", "Server errors/sec");
1331 GENGRAPH(server.all.kbytes_in.kb, "server.all.kbytes_in", "Server total kbytes_in/sec");
1332 GENGRAPH(server.all.kbytes_out.kb, "server.all.kbytes_out", "Server total kbytes_out/sec");
1333
1334 GENGRAPH(server.http.requests, "server.http.requests", "Server HTTP requests/sec");
1335 GENGRAPH(server.http.errors, "server.http.errors", "Server HTTP errors/sec");
1336 GENGRAPH(server.http.kbytes_in.kb, "server.http.kbytes_in", "Server HTTP kbytes_in/sec");
1337 GENGRAPH(server.http.kbytes_out.kb, "server.http.kbytes_out", "Server HTTP kbytes_out/sec");
1338
1339 GENGRAPH(server.ftp.requests, "server.ftp.requests", "Server FTP requests/sec");
1340 GENGRAPH(server.ftp.errors, "server.ftp.errors", "Server FTP errors/sec");
1341 GENGRAPH(server.ftp.kbytes_in.kb, "server.ftp.kbytes_in", "Server FTP kbytes_in/sec");
1342 GENGRAPH(server.ftp.kbytes_out.kb, "server.ftp.kbytes_out", "Server FTP kbytes_out/sec");
1343
1344 GENGRAPH(server.other.requests, "server.other.requests", "Server other requests/sec");
1345 GENGRAPH(server.other.errors, "server.other.errors", "Server other errors/sec");
1346 GENGRAPH(server.other.kbytes_in.kb, "server.other.kbytes_in", "Server other kbytes_in/sec");
1347 GENGRAPH(server.other.kbytes_out.kb, "server.other.kbytes_out", "Server other kbytes_out/sec");
1348
1349 GENGRAPH(icp.pkts_sent, "icp.pkts_sent", "ICP packets sent/sec");
1350 GENGRAPH(icp.pkts_recv, "icp.pkts_recv", "ICP packets received/sec");
1351 GENGRAPH(icp.kbytes_sent.kb, "icp.kbytes_sent", "ICP kbytes_sent/sec");
1352 GENGRAPH(icp.kbytes_recv.kb, "icp.kbytes_recv", "ICP kbytes_received/sec");
1353
1354 /* XXX todo: icp median service times */
1355 /* XXX todo: dns median service times */
1356
1357 GENGRAPH(unlink.requests, "unlink.requests", "Cache File unlink requests/sec");
1358 GENGRAPH(page_faults, "page_faults", "System Page Faults/sec");
1359 GENGRAPH(select_loops, "select_loops", "System Select Loop calls/sec");
1360 GENGRAPH(cputime, "cputime", "CPU utilisation");
1361}
1afe05c5 1362
01aebf31 1363#endif /* STAT_GRAPHS */