]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stat.cc
ftp size bug again
[thirdparty/squid.git] / src / stat.cc
CommitLineData
e5f6c5c2 1
30a4f2a8 2/*
785c2dc3 3 * $Id: stat.cc,v 1.216 1998/03/12 17:51:21 wessels 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/
30a4f2a8 9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
019dd986 31
32/*
30a4f2a8 33 * Copyright (c) 1994, 1995. All rights reserved.
34 *
35 * The Harvest software was developed by the Internet Research Task
36 * Force Research Group on Resource Discovery (IRTF-RD):
37 *
38 * Mic Bowman of Transarc Corporation.
39 * Peter Danzig of the University of Southern California.
40 * Darren R. Hardy of the University of Colorado at Boulder.
41 * Udi Manber of the University of Arizona.
42 * Michael F. Schwartz of the University of Colorado at Boulder.
43 * Duane Wessels of the University of Colorado at Boulder.
44 *
45 * This copyright notice applies to software in the Harvest
46 * ``src/'' directory only. Users should consult the individual
47 * copyright notices in the ``components/'' subdirectories for
48 * copyright information about other software bundled with the
49 * Harvest source code distribution.
50 *
51 * TERMS OF USE
52 *
53 * The Harvest software may be used and re-distributed without
54 * charge, provided that the software origin and research team are
55 * cited in any use of the system. Most commonly this is
56 * accomplished by including a link to the Harvest Home Page
57 * (http://harvest.cs.colorado.edu/) from the query page of any
58 * Broker you deploy, as well as in the query result pages. These
59 * links are generated automatically by the standard Broker
60 * software distribution.
61 *
62 * The Harvest software is provided ``as is'', without express or
63 * implied warranty, and with no support nor obligation to assist
64 * in its use, correction, modification or enhancement. We assume
65 * no liability with respect to the infringement of copyrights,
66 * trade secrets, or any patents, and are not responsible for
67 * consequential damages. Proper use of the Harvest software is
68 * entirely the responsibility of the user.
69 *
70 * DERIVATIVE WORKS
71 *
72 * Users may make derivative works from the Harvest software, subject
73 * to the following constraints:
74 *
75 * - You must include the above copyright notice and these
76 * accompanying paragraphs in all forms of derivative works,
77 * and any documentation and other materials related to such
78 * distribution and use acknowledge that the software was
79 * developed at the above institutions.
80 *
81 * - You must notify IRTF-RD regarding your distribution of
82 * the derivative work.
83 *
84 * - You must clearly notify users that your are distributing
85 * a modified version and not the original Harvest software.
86 *
87 * - Any derivative product is also subject to these copyright
88 * and use restrictions.
89 *
90 * Note that the Harvest software is NOT in the public domain. We
91 * retain copyright, as specified above.
92 *
93 * HISTORY OF FREE SOFTWARE STATUS
94 *
95 * Originally we required sites to license the software in cases
96 * where they were going to build commercial products/services
97 * around Harvest. In June 1995 we changed this policy. We now
98 * allow people to use the core Harvest software (the code found in
99 * the Harvest ``src/'' directory) for free. We made this change
100 * in the interest of encouraging the widest possible deployment of
101 * the technology. The Harvest software is really a reference
102 * implementation of a set of protocols and formats, some of which
103 * we intend to standardize. We encourage commercial
104 * re-implementations of code complying to this set of standards.
019dd986 105 */
ed43818f 106
234967c9 107
44a47c6e 108#include "squid.h"
090089c4 109
67508012 110/* LOCALS */
f5b8bbc4 111static const char *describeStatuses(const StoreEntry *);
112static const char *describeFlags(const StoreEntry *);
113static const char *describeTimestamps(const StoreEntry *);
f2908497 114static void statAvgTick(void *notused);
a0f32775 115static void statAvgDump(StoreEntry *, int minutes, int hours);
12cf1be2 116static void statCountersInit(StatCounters *);
1d803566 117static void statCountersInitSpecial(StatCounters *);
12cf1be2 118static void statCountersClean(StatCounters *);
2ac76861 119static void statCountersCopy(StatCounters * dest, const StatCounters * orig);
a7c05555 120static void statCountersDump(StoreEntry * sentry);
ed7f5615 121static OBJH stat_io_get;
122static OBJH stat_objects_get;
123static OBJH stat_vmobjects_get;
124static OBJH info_get;
125static OBJH statFiledescriptors;
126static OBJH statCounters;
127static OBJH statAvg5min;
45eb7f49 128static OBJH statAvg60min;
e9b5ead4 129static OBJH statUtilization;
20882fb1 130
20882fb1 131#ifdef XMALLOC_STATISTICS
f5b8bbc4 132static void info_get_mallstat(int, int, StoreEntry *);
20882fb1 133#endif
30a4f2a8 134
a9113eb0 135StatCounters CountHist[N_COUNT_HIST];
d5649d9f 136static int NCountHist = 0;
a0f32775 137static StatCounters CountHourHist[N_COUNT_HOUR_HIST];
138static int NCountHourHist = 0;
139
140void
e9b5ead4 141statUtilization(StoreEntry * e)
a0f32775 142{
143 storeAppendPrintf(e, "Cache Utilisation:\n");
144 storeAppendPrintf(e, "\n");
145 storeAppendPrintf(e, "Last 5 minutes:\n");
146 if (NCountHist >= 5)
147 statAvgDump(e, 5, 0);
148 else
149 storeAppendPrintf(e, "(no values recorded yet)\n");
150 storeAppendPrintf(e, "\n");
151 storeAppendPrintf(e, "Last 15 minutes:\n");
152 if (NCountHist >= 15)
153 statAvgDump(e, 15, 0);
154 else
155 storeAppendPrintf(e, "(no values recorded yet)\n");
156 storeAppendPrintf(e, "\n");
157 storeAppendPrintf(e, "Last hour:\n");
158 if (NCountHist >= 60)
159 statAvgDump(e, 60, 0);
160 else
161 storeAppendPrintf(e, "(no values recorded yet)\n");
162 storeAppendPrintf(e, "\n");
163 storeAppendPrintf(e, "Last 8 hours:\n");
164 if (NCountHourHist >= 8)
165 statAvgDump(e, 0, 8);
166 else
167 storeAppendPrintf(e, "(no values recorded yet)\n");
168 storeAppendPrintf(e, "\n");
169 storeAppendPrintf(e, "Last day:\n");
170 if (NCountHourHist >= 24)
171 statAvgDump(e, 0, 24);
172 else
173 storeAppendPrintf(e, "(no values recorded yet)\n");
174 storeAppendPrintf(e, "\n");
175 storeAppendPrintf(e, "Last 3 days:\n");
176 if (NCountHourHist >= 72)
177 statAvgDump(e, 0, 72);
178 else
179 storeAppendPrintf(e, "(no values recorded yet)\n");
180 storeAppendPrintf(e, "\n");
181 storeAppendPrintf(e, "Totals since cache startup:\n");
182 statCountersDump(e);
183}
f2908497 184
6684fec0 185void
b8d8561b 186stat_io_get(StoreEntry * sentry)
30a4f2a8 187{
188 int i;
189
15576b6a 190 storeAppendPrintf(sentry, "HTTP I/O\n");
191 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Http.reads);
192 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
30a4f2a8 193 IOStats.Http.reads_deferred,
194 percent(IOStats.Http.reads_deferred, IOStats.Http.reads));
15576b6a 195 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 196 for (i = 0; i < 16; i++) {
15576b6a 197 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 198 i ? (1 << (i - 1)) + 1 : 1,
199 1 << i,
200 IOStats.Http.read_hist[i],
201 percent(IOStats.Http.read_hist[i], IOStats.Http.reads));
202 }
203
15576b6a 204 storeAppendPrintf(sentry, "\n");
205 storeAppendPrintf(sentry, "FTP I/O\n");
206 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Ftp.reads);
207 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
30a4f2a8 208 IOStats.Ftp.reads_deferred,
209 percent(IOStats.Ftp.reads_deferred, IOStats.Ftp.reads));
15576b6a 210 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 211 for (i = 0; i < 16; i++) {
15576b6a 212 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 213 i ? (1 << (i - 1)) + 1 : 1,
214 1 << i,
215 IOStats.Ftp.read_hist[i],
216 percent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads));
217 }
218
15576b6a 219 storeAppendPrintf(sentry, "\n");
220 storeAppendPrintf(sentry, "Gopher I/O\n");
221 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Gopher.reads);
222 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
56fa4cad 223 IOStats.Gopher.reads_deferred,
224 percent(IOStats.Gopher.reads_deferred, IOStats.Gopher.reads));
15576b6a 225 storeAppendPrintf(sentry, "Read Histogram:\n");
56fa4cad 226 for (i = 0; i < 16; i++) {
15576b6a 227 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
56fa4cad 228 i ? (1 << (i - 1)) + 1 : 1,
229 1 << i,
230 IOStats.Gopher.read_hist[i],
231 percent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads));
232 }
233
15576b6a 234 storeAppendPrintf(sentry, "\n");
235 storeAppendPrintf(sentry, "WAIS I/O\n");
236 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Wais.reads);
237 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
56fa4cad 238 IOStats.Wais.reads_deferred,
239 percent(IOStats.Wais.reads_deferred, IOStats.Wais.reads));
15576b6a 240 storeAppendPrintf(sentry, "Read Histogram:\n");
56fa4cad 241 for (i = 0; i < 16; i++) {
15576b6a 242 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
56fa4cad 243 i ? (1 << (i - 1)) + 1 : 1,
244 1 << i,
245 IOStats.Wais.read_hist[i],
246 percent(IOStats.Wais.read_hist[i], IOStats.Wais.reads));
247 }
090089c4 248}
249
0ee4272b 250static const char *
fe4e214f 251describeStatuses(const StoreEntry * entry)
d1a43e28 252{
253 LOCAL_ARRAY(char, buf, 256);
56878878 254 snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
d1a43e28 255 storeStatusStr[entry->store_status],
256 memStatusStr[entry->mem_status],
257 swapStatusStr[entry->swap_status],
258 pingStatusStr[entry->ping_status]);
259 return buf;
260}
261
0ee4272b 262static const char *
fe4e214f 263describeFlags(const StoreEntry * entry)
d1a43e28 264{
265 LOCAL_ARRAY(char, buf, 256);
266 int flags = (int) entry->flag;
267 char *t;
268 buf[0] = '\0';
79a15e0a 269 if (EBIT_TEST(flags, DELAY_SENDING))
d1a43e28 270 strcat(buf, "DS,");
79a15e0a 271 if (EBIT_TEST(flags, RELEASE_REQUEST))
d1a43e28 272 strcat(buf, "RL,");
79a15e0a 273 if (EBIT_TEST(flags, REFRESH_REQUEST))
d1a43e28 274 strcat(buf, "RF,");
79a15e0a 275 if (EBIT_TEST(flags, ENTRY_CACHABLE))
d1a43e28 276 strcat(buf, "EC,");
79a15e0a 277 if (EBIT_TEST(flags, ENTRY_DISPATCHED))
d1a43e28 278 strcat(buf, "ED,");
79a15e0a 279 if (EBIT_TEST(flags, KEY_PRIVATE))
d1a43e28 280 strcat(buf, "KP,");
79a15e0a 281 if (EBIT_TEST(flags, HIERARCHICAL))
d1a43e28 282 strcat(buf, "HI,");
79a15e0a 283 if (EBIT_TEST(flags, ENTRY_NEGCACHED))
d1a43e28 284 strcat(buf, "NG,");
d1a43e28 285 if ((t = strrchr(buf, ',')))
286 *t = '\0';
287 return buf;
288}
289
0ee4272b 290static const char *
fe4e214f 291describeTimestamps(const StoreEntry * entry)
d1a43e28 292{
293 LOCAL_ARRAY(char, buf, 256);
56878878 294 snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
d1a43e28 295 (int) entry->timestamp,
296 (int) entry->lastref,
297 (int) entry->lastmod,
298 (int) entry->expires);
299 return buf;
300}
301
090089c4 302/* process objects list */
b8d8561b 303static void
6684fec0 304statObjects(StoreEntry * sentry, int vm_or_not)
090089c4 305{
09610784 306 StoreEntry *entry = NULL;
f09f5b26 307 StoreEntry *next = NULL;
d1a43e28 308 MemObject *mem;
090089c4 309 int N = 0;
637ed800 310 int i;
311 struct _store_client *sc;
f09f5b26 312 next = (StoreEntry *) hash_first(store_table);
a200bbd2 313 while ((entry = next) != NULL) {
f09f5b26 314 next = (StoreEntry *) hash_next(store_table);
d1a43e28 315 mem = entry->mem_obj;
316 if (vm_or_not && mem == NULL)
090089c4 317 continue;
318 if ((++N & 0xFF) == 0) {
22f3fd98 319 debug(18, 3) ("statObjects: Processed %d objects...\n", N);
090089c4 320 }
438fc1e3 321 storeBuffer(sentry);
24ffafb4 322 storeAppendPrintf(sentry, "KEY %s\n", storeKeyText(entry->key));
2ac237e2 323 if (mem)
324 storeAppendPrintf(sentry, "\t%s %s\n",
785c2dc3 325 RequestMethodStr[mem->method], mem->log_url);
637ed800 326 storeAppendPrintf(sentry, "\t%s\n", describeStatuses(entry));
327 storeAppendPrintf(sentry, "\t%s\n", describeFlags(entry));
328 storeAppendPrintf(sentry, "\t%s\n", describeTimestamps(entry));
329 storeAppendPrintf(sentry, "\t%d locks, %d clients, %d refs\n",
330 (int) entry->lock_count,
331 storePendingNClients(entry),
332 (int) entry->refcount);
333 storeAppendPrintf(sentry, "\tSwap File %#08X\n",
334 entry->swap_file_number);
335 if (mem == NULL)
336 continue;
337 storeAppendPrintf(sentry, "\tinmem_lo: %d\n", (int) mem->inmem_lo);
338 storeAppendPrintf(sentry, "\tinmem_hi: %d\n", (int) mem->inmem_hi);
339 storeAppendPrintf(sentry, "\tswapout: %d bytes done, %d queued, FD %d\n",
340 mem->swapout.done_offset,
341 mem->swapout.queue_offset,
342 mem->swapout.fd);
343 for (i = 0; i < mem->nclients; i++) {
344 sc = &mem->clients[i];
345 if (sc->callback_data == NULL)
346 continue;
347 storeAppendPrintf(sentry, "\tClient #%d\n", i);
348 storeAppendPrintf(sentry, "\t\tcopy_offset: %d\n",
349 (int) sc->copy_offset);
350 storeAppendPrintf(sentry, "\t\tseen_offset: %d\n",
351 (int) sc->seen_offset);
352 storeAppendPrintf(sentry, "\t\tcopy_size: %d\n",
353 (int) sc->copy_size);
354 storeAppendPrintf(sentry, "\t\tswapin_fd: %d\n",
355 (int) sc->swapin_fd);
356 }
24ffafb4 357 storeAppendPrintf(sentry, "\n");
438fc1e3 358 storeBufferFlush(sentry);
090089c4 359 }
090089c4 360}
361
03eb2f01 362void
603a02fd 363stat_objects_get(StoreEntry * e)
090089c4 364{
603a02fd 365 statObjects(e, 0);
6684fec0 366}
090089c4 367
6684fec0 368void
603a02fd 369stat_vmobjects_get(StoreEntry * e)
6684fec0 370{
603a02fd 371 statObjects(e, 1);
090089c4 372}
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
6684fec0 393void
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],
4f92c80c 415 f->timeout_handler ? (f->timeout - squid_curtime) / 60 : 0,
416 f->bytes_read,
417 f->bytes_written,
418 fdRemoteAddr(f),
419 f->desc);
d51e52f5 420 }
d51e52f5 421}
422
03eb2f01 423void
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);
15576b6a 447 storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%u\n",
f2908497 448 Counter.client_http.requests);
15576b6a 449 storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%u\n",
f2908497 450 Counter.icp.pkts_recv);
15576b6a 451 storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%u\n",
f2908497 452 Counter.icp.pkts_sent);
15576b6a 453 storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f%%\n",
88aad2e5 454 request_failure_ratio);
f2908497 455
15576b6a 456 storeAppendPrintf(sentry, "\tHTTP requests per minute:\t%.1f\n",
f2908497 457 Counter.client_http.requests / (runtime / 60.0));
15576b6a 458 storeAppendPrintf(sentry, "\tICP messages per minute:\t%.1f\n",
f2908497 459 (Counter.icp.pkts_sent + Counter.icp.pkts_recv) / (runtime / 60.0));
15576b6a 460 storeAppendPrintf(sentry, "\tSelect loop called: %d times, %0.3f ms avg\n",
f2908497 461 Counter.select_loops, 1000.0 * runtime / Counter.select_loops);
090089c4 462
15576b6a 463 storeAppendPrintf(sentry, "Cache information for %s:\n",
30a4f2a8 464 appname);
15576b6a 465 storeAppendPrintf(sentry, "\tStorage Swap size:\t%d KB\n",
c932b107 466 store_swap_size);
15576b6a 467 storeAppendPrintf(sentry, "\tStorage Mem size:\t%d KB\n",
e954773d 468 store_mem_size >> 10);
15576b6a 469 storeAppendPrintf(sentry, "\tStorage LRU Expiration Age:\t%6.2f days\n",
52cd89fd 470 (double) storeExpiredReferenceAge() / 86400.0);
15576b6a 471 storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%d\n",
f2908497 472 Counter.unlink.requests);
090089c4 473
f2908497 474 squid_getrusage(&rusage);
475 cputime = rusage_cputime(&rusage);
15576b6a 476 storeAppendPrintf(sentry, "Resource usage for %s:\n", appname);
477 storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", runtime);
478 storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", cputime);
479 storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
f2908497 480 dpercent(cputime, runtime));
15576b6a 481 storeAppendPrintf(sentry, "\tMaximum Resident Size: %ld KB\n",
f2908497 482 rusage_maxrss(&rusage));
15576b6a 483 storeAppendPrintf(sentry, "\tPage faults with physical i/o: %ld\n",
f2908497 484 rusage_pagefaults(&rusage));
090089c4 485
88738790 486#if HAVE_MSTATS && HAVE_GNUMALLOC_H
487 ms = mstats();
15576b6a 488 storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",
88738790 489 appname);
15576b6a 490 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
88738790 491 ms.bytes_total >> 10);
15576b6a 492 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
88738790 493 ms.bytes_free >> 10, percent(ms.bytes_free, ms.bytes_total));
494#elif HAVE_MALLINFO
090089c4 495 mp = mallinfo();
15576b6a 496 storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",
d51e52f5 497 appname);
15576b6a 498 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
b560dd20 499 mp.arena >> 10);
15576b6a 500 storeAppendPrintf(sentry, "\tOrdinary blocks: %6d KB %6d blks\n",
30a4f2a8 501 mp.uordblks >> 10, mp.ordblks);
15576b6a 502 storeAppendPrintf(sentry, "\tSmall blocks: %6d KB %6d blks\n",
30a4f2a8 503 mp.usmblks >> 10, mp.smblks);
15576b6a 504 storeAppendPrintf(sentry, "\tHolding blocks: %6d KB %6d blks\n",
30a4f2a8 505 mp.hblkhd >> 10, mp.hblks);
15576b6a 506 storeAppendPrintf(sentry, "\tFree Small blocks: %6d KB\n",
30a4f2a8 507 mp.fsmblks >> 10);
15576b6a 508 storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6d KB\n",
30a4f2a8 509 mp.fordblks >> 10);
510 t = mp.uordblks + mp.usmblks + mp.hblkhd;
15576b6a 511 storeAppendPrintf(sentry, "\tTotal in use: %6d KB %d%%\n",
30a4f2a8 512 t >> 10, percent(t, mp.arena));
513 t = mp.fsmblks + mp.fordblks;
15576b6a 514 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
30a4f2a8 515 t >> 10, percent(t, mp.arena));
46c883ed 516#if HAVE_EXT_MALLINFO
15576b6a 517 storeAppendPrintf(sentry, "\tmax size of small blocks:\t%d\n", mp.mxfast);
518 storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%d\n",
090089c4 519 mp.nlblks);
15576b6a 520 storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%d\n", mp.grain);
521 storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%d\n"
090089c4 522 ,mp.uordbytes);
15576b6a 523 storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%d\n",
090089c4 524 mp.allocated);
15576b6a 525 storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%d\n",
090089c4 526 mp.treeoverhead);
46c883ed 527#endif /* HAVE_EXT_MALLINFO */
50bc2565 528#endif /* HAVE_MALLINFO */
090089c4 529
15576b6a 530 storeAppendPrintf(sentry, "File descriptor usage for %s:\n", appname);
531 storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n",
e83892e9 532 Squid_MaxFD);
15576b6a 533 storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4d\n",
429fdbec 534 Biggest_FD);
15576b6a 535 storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4d\n",
88738790 536 Number_FD);
15576b6a 537 storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4d\n",
88738790 538 Squid_MaxFD - Number_FD);
15576b6a 539 storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4d\n",
090089c4 540 RESERVED_FD);
090089c4 541
15576b6a 542 storeAppendPrintf(sentry, "Internal Data Structures:\n");
543 storeAppendPrintf(sentry, "\t%6d StoreEntries\n",
3f6c0fb2 544 memInUse(MEM_STOREENTRY));
15576b6a 545 storeAppendPrintf(sentry, "\t%6d StoreEntries with MemObjects\n",
3f6c0fb2 546 memInUse(MEM_MEMOBJECT));
15576b6a 547 storeAppendPrintf(sentry, "\t%6d StoreEntries with MemObject Data\n",
3f6c0fb2 548 memInUse(MEM_MEM_HDR));
15576b6a 549 storeAppendPrintf(sentry, "\t%6d Hot Object Cache Items\n",
59c4d35b 550 hot_obj_count);
30a4f2a8 551
552#if XMALLOC_STATISTICS
15576b6a 553 storeAppendPrintf(sentry, "Memory allocation statistics\n");
30a4f2a8 554 malloc_statistics(info_get_mallstat, sentry);
555#endif
090089c4 556}
557
a7c05555 558#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
b8d8561b 559static void
a0f32775 560statAvgDump(StoreEntry * sentry, int minutes, int hours)
090089c4 561{
a7c05555 562 StatCounters *f;
563 StatCounters *l;
564 double dt;
565 double ct;
7ae52c25 566 double x;
a7c05555 567 assert(N_COUNT_HIST > 1);
a0f32775 568 assert(minutes > 0 || hours > 0);
a7c05555 569 f = &CountHist[0];
a0f32775 570 l = f;
571 if (minutes > 0 && hours == 0) {
572 /* checking minute readings ... */
573 if (minutes > N_COUNT_HIST - 1)
574 minutes = N_COUNT_HIST - 1;
575 l = &CountHist[minutes];
576 } else if (minutes == 0 && hours > 0) {
577 /* checking hour readings ... */
578 if (hours > N_COUNT_HOUR_HIST - 1)
579 hours = N_COUNT_HOUR_HIST - 1;
580 l = &CountHourHist[hours];
581 } else {
399e85ea 582 debug(18, 1) ("statAvgDump: Invalid args, minutes=%d, hours=%d\n",
583 minutes, hours);
a0f32775 584 return;
585 }
a7c05555 586 dt = tvSubDsec(l->timestamp, f->timestamp);
587 ct = f->cputime - l->cputime;
ee1679df 588
399e85ea 589 storeAppendPrintf(sentry, "sample_start_time = %d.%d (%s)\n",
590 f->timestamp.tv_sec,
a0f32775 591 f->timestamp.tv_usec,
592 mkrfc1123(f->timestamp.tv_sec));
399e85ea 593 storeAppendPrintf(sentry, "sample_end_time = %d.%d (%s)\n",
594 l->timestamp.tv_sec,
a0f32775 595 l->timestamp.tv_usec,
596 mkrfc1123(l->timestamp.tv_sec));
597
a7c05555 598 storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
599 XAVG(client_http.requests));
600 storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
601 XAVG(client_http.hits));
602 storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
603 XAVG(client_http.errors));
604 storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
605 XAVG(client_http.kbytes_in.kb));
606 storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
607 XAVG(client_http.kbytes_out.kb));
ee1679df 608
12cf1be2 609 x = statHistDeltaMedian(&l->client_http.all_svc_time,
ee1679df 610 &f->client_http.all_svc_time);
611 storeAppendPrintf(sentry, "client_http.all_median_svc_time = %f seconds\n",
612 x / 1000.0);
12cf1be2 613 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
ee1679df 614 &f->client_http.miss_svc_time);
615 storeAppendPrintf(sentry, "client_http.miss_median_svc_time = %f seconds\n",
616 x / 1000.0);
12cf1be2 617 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
ee1679df 618 &f->client_http.nm_svc_time);
619 storeAppendPrintf(sentry, "client_http.nm_median_svc_time = %f seconds\n",
620 x / 1000.0);
12cf1be2 621 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
ee1679df 622 &f->client_http.hit_svc_time);
623 storeAppendPrintf(sentry, "client_http.hit_median_svc_time = %f seconds\n",
7ae52c25 624 x / 1000.0);
ee1679df 625
a0f32775 626 storeAppendPrintf(sentry, "server.all.requests = %f/sec\n",
627 XAVG(server.all.requests));
628 storeAppendPrintf(sentry, "server.all.errors = %f/sec\n",
629 XAVG(server.all.errors));
630 storeAppendPrintf(sentry, "server.all.kbytes_in = %f/sec\n",
631 XAVG(server.all.kbytes_in.kb));
632 storeAppendPrintf(sentry, "server.all.kbytes_out = %f/sec\n",
633 XAVG(server.all.kbytes_out.kb));
634
635 storeAppendPrintf(sentry, "server.http.requests = %f/sec\n",
636 XAVG(server.http.requests));
637 storeAppendPrintf(sentry, "server.http.errors = %f/sec\n",
638 XAVG(server.http.errors));
639 storeAppendPrintf(sentry, "server.http.kbytes_in = %f/sec\n",
640 XAVG(server.http.kbytes_in.kb));
641 storeAppendPrintf(sentry, "server.http.kbytes_out = %f/sec\n",
642 XAVG(server.http.kbytes_out.kb));
643
644 storeAppendPrintf(sentry, "server.ftp.requests = %f/sec\n",
645 XAVG(server.ftp.requests));
646 storeAppendPrintf(sentry, "server.ftp.errors = %f/sec\n",
647 XAVG(server.ftp.errors));
648 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %f/sec\n",
649 XAVG(server.ftp.kbytes_in.kb));
650 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %f/sec\n",
651 XAVG(server.ftp.kbytes_out.kb));
652
653 storeAppendPrintf(sentry, "server.other.requests = %f/sec\n",
654 XAVG(server.other.requests));
655 storeAppendPrintf(sentry, "server.other.errors = %f/sec\n",
656 XAVG(server.other.errors));
657 storeAppendPrintf(sentry, "server.other.kbytes_in = %f/sec\n",
658 XAVG(server.other.kbytes_in.kb));
659 storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
660 XAVG(server.other.kbytes_out.kb));
ee1679df 661
a7c05555 662 storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
663 XAVG(icp.pkts_sent));
664 storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
665 XAVG(icp.pkts_recv));
666 storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
667 XAVG(icp.kbytes_sent.kb));
668 storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
669 XAVG(icp.kbytes_recv.kb));
12cf1be2 670 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
ee1679df 671 storeAppendPrintf(sentry, "icp.query_median_svc_time = %f seconds\n",
672 x / 1000000.0);
12cf1be2 673 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
ee1679df 674 storeAppendPrintf(sentry, "icp.reply_median_svc_time = %f seconds\n",
7ae52c25 675 x / 1000000.0);
12cf1be2 676 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
9973e9fe 677 storeAppendPrintf(sentry, "dns.median_svc_time = %f seconds\n",
901d8c30 678 x / 1000.0);
a7c05555 679 storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
680 XAVG(unlink.requests));
681 storeAppendPrintf(sentry, "page_faults = %f/sec\n",
682 XAVG(page_faults));
683 storeAppendPrintf(sentry, "select_loops = %f/sec\n",
684 XAVG(select_loops));
685 storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct);
686 storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt);
0e473d70 687 storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt));
090089c4 688}
689
b8d8561b 690void
a7c05555 691statInit(void)
090089c4 692{
090089c4 693 int i;
a7c05555 694 debug(18, 5) ("statInit: Initializing...\n");
0e473d70 695 for (i = 0; i < N_COUNT_HIST; i++)
12cf1be2 696 statCountersInit(&CountHist[i]);
a0f32775 697 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
698 statCountersInit(&CountHourHist[i]);
12cf1be2 699 statCountersInit(&Counter);
a0f32775 700 eventAdd("statAvgTick", statAvgTick, NULL, COUNT_INTERVAL);
22f3fd98 701 cachemgrRegister("info",
702 "General Runtime Information",
703 info_get, 0);
704 cachemgrRegister("filedescriptors",
705 "Process Filedescriptor Allocation",
706 statFiledescriptors, 0);
707 cachemgrRegister("objects",
708 "All Cache Objects",
709 stat_objects_get, 0);
710 cachemgrRegister("vm_objects",
711 "In-Memory and In-Transit Objects",
712 stat_vmobjects_get, 0);
713 cachemgrRegister("io",
714 "Server-side network read() size histograms",
715 stat_io_get, 0);
716 cachemgrRegister("counters",
717 "Traffic and Resource Counters",
718 statCounters, 0);
719 cachemgrRegister("5min",
720 "5 Minute Average of Counters",
721 statAvg5min, 0);
45eb7f49 722 cachemgrRegister("60min",
723 "60 Minute Average of Counters",
724 statAvg60min, 0);
e9b5ead4 725 cachemgrRegister("utilization",
726 "Cache Utilization",
727 statUtilization, 0);
090089c4 728}
f2908497 729
f2908497 730static void
731statAvgTick(void *notused)
732{
d5649d9f 733 StatCounters *t = &CountHist[0];
734 StatCounters *p = &CountHist[1];
f2908497 735 StatCounters *c = &Counter;
736 struct rusage rusage;
a0f32775 737 eventAdd("statAvgTick", statAvgTick, NULL, COUNT_INTERVAL);
20903cac 738 squid_getrusage(&rusage);
739 c->page_faults = rusage_pagefaults(&rusage);
740 c->cputime = rusage_cputime(&rusage);
d5649d9f 741 c->timestamp = current_time;
12cf1be2 742 /* even if NCountHist is small, we already Init()ed the tail */
2ac76861 743 statCountersClean(CountHist + N_COUNT_HIST - 1);
dbfed404 744 xmemmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
12cf1be2 745 statCountersCopy(t, c);
d5649d9f 746 NCountHist++;
a0f32775 747
748 if ((NCountHist % COUNT_INTERVAL) == 0) {
749 /* we have an hours worth of readings. store previous hour */
750 StatCounters *p = &CountHourHist[0];
751 StatCounters *t = &CountHourHist[1];
752 StatCounters *c = &CountHist[N_COUNT_HIST];
753 xmemmove(p, t, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
754 memcpy(t, c, sizeof(StatCounters));
755 NCountHourHist++;
756 }
20903cac 757}
758
12cf1be2 759static void
2ac76861 760statCountersInit(StatCounters * C)
20903cac 761{
12cf1be2 762 assert(C);
1d803566 763 memset(C, 0, sizeof(*C));
12cf1be2 764 C->timestamp = current_time;
1d803566 765 statCountersInitSpecial(C);
766}
767
768/* add special cases here as they arrive */
769static void
2ac76861 770statCountersInitSpecial(StatCounters * C)
1d803566 771{
12cf1be2 772 /*
773 * HTTP svc_time hist is kept in milli-seconds; max of 3 hours.
774 */
775 statHistLogInit(&C->client_http.all_svc_time, 300, 0.0, 3600000.0 * 3.0);
776 statHistLogInit(&C->client_http.miss_svc_time, 300, 0.0, 3600000.0 * 3.0);
777 statHistLogInit(&C->client_http.nm_svc_time, 300, 0.0, 3600000.0 * 3.0);
778 statHistLogInit(&C->client_http.hit_svc_time, 300, 0.0, 3600000.0 * 3.0);
779 /*
780 * ICP svc_time hist is kept in micro-seconds; max of 1 minute.
781 */
782 statHistLogInit(&C->icp.query_svc_time, 300, 0.0, 1000000.0 * 60.0);
783 statHistLogInit(&C->icp.reply_svc_time, 300, 0.0, 1000000.0 * 60.0);
784 /*
785 * DNS svc_time hist is kept in milli-seconds; max of 10 minutes.
786 */
787 statHistLogInit(&C->dns.svc_time, 300, 0.0, 60000.0 * 10.0);
0f5607d9 788}
789
12cf1be2 790/* add special cases here as they arrive */
0f5607d9 791void
2ac76861 792statCountersClean(StatCounters * C)
0f5607d9 793{
12cf1be2 794 assert(C);
795 statHistClean(&C->client_http.all_svc_time);
796 statHistClean(&C->client_http.miss_svc_time);
797 statHistClean(&C->client_http.nm_svc_time);
798 statHistClean(&C->client_http.hit_svc_time);
799 statHistClean(&C->icp.query_svc_time);
800 statHistClean(&C->icp.reply_svc_time);
801 statHistClean(&C->dns.svc_time);
a7c05555 802}
803
12cf1be2 804/* add special cases here as they arrive */
45eb7f49 805void
2ac76861 806statCountersCopy(StatCounters * dest, const StatCounters * orig)
45eb7f49 807{
12cf1be2 808 assert(dest && orig);
1d803566 809 /* this should take care of all the fields, but "special" ones */
12cf1be2 810 memcpy(dest, orig, sizeof(*dest));
1d803566 811 /* prepare space where to copy special entries */
812 statCountersInitSpecial(dest);
813 /* now handle special cases */
814 /* note: we assert that histogram capacities do not change */
12cf1be2 815 statHistCopy(&dest->client_http.all_svc_time, &orig->client_http.all_svc_time);
816 statHistCopy(&dest->client_http.miss_svc_time, &orig->client_http.miss_svc_time);
817 statHistCopy(&dest->client_http.nm_svc_time, &orig->client_http.nm_svc_time);
818 statHistCopy(&dest->client_http.hit_svc_time, &orig->client_http.hit_svc_time);
819 statHistCopy(&dest->icp.query_svc_time, &orig->icp.query_svc_time);
820 statHistCopy(&dest->icp.reply_svc_time, &orig->icp.reply_svc_time);
821 statHistCopy(&dest->dns.svc_time, &orig->dns.svc_time);
45eb7f49 822}
823
12cf1be2 824static void
825statCountersDump(StoreEntry * sentry)
7ae52c25 826{
12cf1be2 827 StatCounters *f = &Counter;
828 struct rusage rusage;
829 squid_getrusage(&rusage);
830 f->page_faults = rusage_pagefaults(&rusage);
831 f->cputime = rusage_cputime(&rusage);
832
a0f32775 833 storeAppendPrintf(sentry, "sample_time = %d.%d (%s)\n",
399e85ea 834 f->timestamp.tv_sec,
a0f32775 835 f->timestamp.tv_usec,
836 mkrfc1123(f->timestamp.tv_sec));
12cf1be2 837 storeAppendPrintf(sentry, "client_http.requests = %d\n",
838 f->client_http.requests);
839 storeAppendPrintf(sentry, "client_http.hits = %d\n",
840 f->client_http.hits);
841 storeAppendPrintf(sentry, "client_http.errors = %d\n",
842 f->client_http.errors);
843 storeAppendPrintf(sentry, "client_http.kbytes_in = %d\n",
844 (int) f->client_http.kbytes_in.kb);
845 storeAppendPrintf(sentry, "client_http.kbytes_out = %d\n",
846 (int) f->client_http.kbytes_out.kb);
0567f2a6 847
848#if TOO_MUCH_OUTPUT
12cf1be2 849 storeAppendPrintf(sentry, "client_http.all_svc_time histogram:\n");
850 statHistDump(&f->client_http.all_svc_time, sentry, NULL);
851 storeAppendPrintf(sentry, "client_http.miss_svc_time histogram:\n");
852 statHistDump(&f->client_http.miss_svc_time, sentry, NULL);
853 storeAppendPrintf(sentry, "client_http.nm_svc_time histogram:\n");
854 statHistDump(&f->client_http.nm_svc_time, sentry, NULL);
855 storeAppendPrintf(sentry, "client_http.hit_svc_time histogram:\n");
856 statHistDump(&f->client_http.hit_svc_time, sentry, NULL);
0567f2a6 857#endif
12cf1be2 858
a0f32775 859 storeAppendPrintf(sentry, "server.all.requests = %d\n",
860 (int) f->server.all.requests);
861 storeAppendPrintf(sentry, "server.all.errors = %d\n",
862 (int) f->server.all.errors);
863 storeAppendPrintf(sentry, "server.all.kbytes_in = %d\n",
864 (int) f->server.all.kbytes_in.kb);
865 storeAppendPrintf(sentry, "server.all.kbytes_out = %d\n",
866 (int) f->server.all.kbytes_out.kb);
867
868 storeAppendPrintf(sentry, "server.http.requests = %d\n",
869 (int) f->server.http.requests);
870 storeAppendPrintf(sentry, "server.http.errors = %d\n",
871 (int) f->server.http.errors);
872 storeAppendPrintf(sentry, "server.http.kbytes_in = %d\n",
873 (int) f->server.http.kbytes_in.kb);
874 storeAppendPrintf(sentry, "server.http.kbytes_out = %d\n",
875 (int) f->server.http.kbytes_out.kb);
876
877 storeAppendPrintf(sentry, "server.ftp.requests = %d\n",
878 (int) f->server.ftp.requests);
879 storeAppendPrintf(sentry, "server.ftp.errors = %d\n",
880 (int) f->server.ftp.errors);
881 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %d\n",
882 (int) f->server.ftp.kbytes_in.kb);
883 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %d\n",
884 (int) f->server.ftp.kbytes_out.kb);
885
886 storeAppendPrintf(sentry, "server.other.requests = %d\n",
887 (int) f->server.other.requests);
888 storeAppendPrintf(sentry, "server.other.errors = %d\n",
889 (int) f->server.other.errors);
890 storeAppendPrintf(sentry, "server.other.kbytes_in = %d\n",
891 (int) f->server.other.kbytes_in.kb);
892 storeAppendPrintf(sentry, "server.other.kbytes_out = %d\n",
893 (int) f->server.other.kbytes_out.kb);
12cf1be2 894
895 storeAppendPrintf(sentry, "icp.pkts_sent = %d\n",
896 f->icp.pkts_sent);
897 storeAppendPrintf(sentry, "icp.pkts_recv = %d\n",
898 f->icp.pkts_recv);
899 storeAppendPrintf(sentry, "icp.kbytes_sent = %d\n",
900 (int) f->icp.kbytes_sent.kb);
901 storeAppendPrintf(sentry, "icp.kbytes_recv = %d\n",
902 (int) f->icp.kbytes_recv.kb);
0567f2a6 903
904#if TOO_MUCH_OUTPUT
12cf1be2 905 storeAppendPrintf(sentry, "icp.query_svc_time histogram:\n");
906 statHistDump(&f->icp.query_svc_time, sentry, NULL);
907 storeAppendPrintf(sentry, "icp.reply_svc_time histogram:\n");
908 statHistDump(&f->icp.reply_svc_time, sentry, NULL);
12cf1be2 909 storeAppendPrintf(sentry, "dns.svc_time histogram:\n");
910 statHistDump(&f->dns.svc_time, sentry, NULL);
0567f2a6 911#endif
912
12cf1be2 913 storeAppendPrintf(sentry, "unlink.requests = %d\n",
914 f->unlink.requests);
915 storeAppendPrintf(sentry, "page_faults = %d\n",
916 f->page_faults);
917 storeAppendPrintf(sentry, "select_loops = %d\n",
918 f->select_loops);
919 storeAppendPrintf(sentry, "cpu_time = %f\n",
920 f->cputime);
921 storeAppendPrintf(sentry, "wall_time = %f\n",
922 tvSubDsec(f->timestamp, current_time));
7ae52c25 923}
924
925void
12cf1be2 926statCounters(StoreEntry * e)
7ae52c25 927{
12cf1be2 928 statCountersDump(e);
7ae52c25 929}
930
12cf1be2 931void
932statAvg5min(StoreEntry * e)
7ae52c25 933{
a0f32775 934 statAvgDump(e, 5, 0);
7ae52c25 935}
936
12cf1be2 937void
938statAvg60min(StoreEntry * e)
7ae52c25 939{
a0f32775 940 statAvgDump(e, 60, 0);
7ae52c25 941}
942
9973e9fe 943
ee1679df 944enum {
945 HTTP_SVC, ICP_SVC, DNS_SVC
946};
a9113eb0 947
ee1679df 948int
a9113eb0 949get_median_svc(int interval, int which)
950{
951 StatCounters *f;
952 StatCounters *l;
953 double x;
f8d264b8 954 assert(interval > 0);
955 if (interval > N_COUNT_HIST - 1)
956 interval = N_COUNT_HIST - 1;
a9113eb0 957 f = &CountHist[0];
958 l = &CountHist[interval];
ee1679df 959 assert(f);
960 assert(l);
a9113eb0 961 switch (which) {
962 case HTTP_SVC:
12cf1be2 963 x = statHistDeltaMedian(&l->client_http.all_svc_time, &f->client_http.all_svc_time);
ee1679df 964 break;
a9113eb0 965 case ICP_SVC:
12cf1be2 966 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
ee1679df 967 break;
a9113eb0 968 case DNS_SVC:
12cf1be2 969 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
ee1679df 970 break;
a9113eb0 971 default:
ee1679df 972 debug(49, 5) ("get_median_val: unknown type.\n");
973 x = 0;
a9113eb0 974 }
ee1679df 975 return (int) x;
a9113eb0 976}
451b07c5 977
978StatCounters *
979snmpStatGet(int minutes)
980{
2ac76861 981 return &CountHist[minutes];
451b07c5 982}