]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stat.cc
rename mallocblksize to avoid conflicts
[thirdparty/squid.git] / src / stat.cc
CommitLineData
e5f6c5c2 1
30a4f2a8 2/*
0f5607d9 3 * $Id: stat.cc,v 1.196 1998/02/12 23:52:16 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);
a7c05555 115static void statAvgDump(StoreEntry *, int minutes);
116static void statCountersDump(StoreEntry * sentry);
20882fb1 117
20882fb1 118#ifdef XMALLOC_STATISTICS
f5b8bbc4 119static void info_get_mallstat(int, int, StoreEntry *);
20882fb1 120#endif
30a4f2a8 121
6605655c 122#define PCONN_HIST_SZ 256
123int client_pconn_hist[PCONN_HIST_SZ];
b716a8ad 124int server_pconn_hist[PCONN_HIST_SZ];
6605655c 125
a7c05555 126/*
127 * An hour's worth, plus the 'current' counter
128 */
129#define N_COUNT_HIST 61
d5649d9f 130static StatCounters CountHist[N_COUNT_HIST];
131static int NCountHist = 0;
f2908497 132
6684fec0 133void
603a02fd 134stat_utilization_get(StoreEntry * e)
6684fec0 135{
0e473d70 136 /* MAKE SOMETHING UP */
6684fec0 137}
138
139void
b8d8561b 140stat_io_get(StoreEntry * sentry)
30a4f2a8 141{
142 int i;
143
15576b6a 144 storeAppendPrintf(sentry, "HTTP I/O\n");
145 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Http.reads);
146 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
30a4f2a8 147 IOStats.Http.reads_deferred,
148 percent(IOStats.Http.reads_deferred, IOStats.Http.reads));
15576b6a 149 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 150 for (i = 0; i < 16; i++) {
15576b6a 151 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 152 i ? (1 << (i - 1)) + 1 : 1,
153 1 << i,
154 IOStats.Http.read_hist[i],
155 percent(IOStats.Http.read_hist[i], IOStats.Http.reads));
156 }
157
15576b6a 158 storeAppendPrintf(sentry, "\n");
159 storeAppendPrintf(sentry, "FTP I/O\n");
160 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Ftp.reads);
161 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
30a4f2a8 162 IOStats.Ftp.reads_deferred,
163 percent(IOStats.Ftp.reads_deferred, IOStats.Ftp.reads));
15576b6a 164 storeAppendPrintf(sentry, "Read Histogram:\n");
30a4f2a8 165 for (i = 0; i < 16; i++) {
15576b6a 166 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
30a4f2a8 167 i ? (1 << (i - 1)) + 1 : 1,
168 1 << i,
169 IOStats.Ftp.read_hist[i],
170 percent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads));
171 }
172
15576b6a 173 storeAppendPrintf(sentry, "\n");
174 storeAppendPrintf(sentry, "Gopher I/O\n");
175 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Gopher.reads);
176 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
56fa4cad 177 IOStats.Gopher.reads_deferred,
178 percent(IOStats.Gopher.reads_deferred, IOStats.Gopher.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.Gopher.read_hist[i],
185 percent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads));
186 }
187
15576b6a 188 storeAppendPrintf(sentry, "\n");
189 storeAppendPrintf(sentry, "WAIS I/O\n");
190 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Wais.reads);
191 storeAppendPrintf(sentry, "deferred reads: %d (%d%%)\n",
56fa4cad 192 IOStats.Wais.reads_deferred,
193 percent(IOStats.Wais.reads_deferred, IOStats.Wais.reads));
15576b6a 194 storeAppendPrintf(sentry, "Read Histogram:\n");
56fa4cad 195 for (i = 0; i < 16; i++) {
15576b6a 196 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
56fa4cad 197 i ? (1 << (i - 1)) + 1 : 1,
198 1 << i,
199 IOStats.Wais.read_hist[i],
200 percent(IOStats.Wais.read_hist[i], IOStats.Wais.reads));
201 }
090089c4 202}
203
0ee4272b 204static const char *
fe4e214f 205describeStatuses(const StoreEntry * entry)
d1a43e28 206{
207 LOCAL_ARRAY(char, buf, 256);
56878878 208 snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
d1a43e28 209 storeStatusStr[entry->store_status],
210 memStatusStr[entry->mem_status],
211 swapStatusStr[entry->swap_status],
212 pingStatusStr[entry->ping_status]);
213 return buf;
214}
215
0ee4272b 216static const char *
fe4e214f 217describeFlags(const StoreEntry * entry)
d1a43e28 218{
219 LOCAL_ARRAY(char, buf, 256);
220 int flags = (int) entry->flag;
221 char *t;
222 buf[0] = '\0';
79a15e0a 223 if (EBIT_TEST(flags, DELAY_SENDING))
d1a43e28 224 strcat(buf, "DS,");
79a15e0a 225 if (EBIT_TEST(flags, RELEASE_REQUEST))
d1a43e28 226 strcat(buf, "RL,");
79a15e0a 227 if (EBIT_TEST(flags, REFRESH_REQUEST))
d1a43e28 228 strcat(buf, "RF,");
79a15e0a 229 if (EBIT_TEST(flags, ENTRY_CACHABLE))
d1a43e28 230 strcat(buf, "EC,");
79a15e0a 231 if (EBIT_TEST(flags, ENTRY_DISPATCHED))
d1a43e28 232 strcat(buf, "ED,");
79a15e0a 233 if (EBIT_TEST(flags, KEY_PRIVATE))
d1a43e28 234 strcat(buf, "KP,");
79a15e0a 235 if (EBIT_TEST(flags, HIERARCHICAL))
d1a43e28 236 strcat(buf, "HI,");
79a15e0a 237 if (EBIT_TEST(flags, ENTRY_NEGCACHED))
d1a43e28 238 strcat(buf, "NG,");
d1a43e28 239 if ((t = strrchr(buf, ',')))
240 *t = '\0';
241 return buf;
242}
243
0ee4272b 244static const char *
fe4e214f 245describeTimestamps(const StoreEntry * entry)
d1a43e28 246{
247 LOCAL_ARRAY(char, buf, 256);
56878878 248 snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
d1a43e28 249 (int) entry->timestamp,
250 (int) entry->lastref,
251 (int) entry->lastmod,
252 (int) entry->expires);
253 return buf;
254}
255
090089c4 256/* process objects list */
b8d8561b 257static void
6684fec0 258statObjects(StoreEntry * sentry, int vm_or_not)
090089c4 259{
09610784 260 StoreEntry *entry = NULL;
f09f5b26 261 StoreEntry *next = NULL;
d1a43e28 262 MemObject *mem;
090089c4 263 int N = 0;
637ed800 264 int i;
265 struct _store_client *sc;
f09f5b26 266 next = (StoreEntry *) hash_first(store_table);
a200bbd2 267 while ((entry = next) != NULL) {
f09f5b26 268 next = (StoreEntry *) hash_next(store_table);
d1a43e28 269 mem = entry->mem_obj;
270 if (vm_or_not && mem == NULL)
090089c4 271 continue;
272 if ((++N & 0xFF) == 0) {
a3d5953d 273 debug(18, 3) ("stat_objects_get: Processed %d objects...\n", N);
090089c4 274 }
438fc1e3 275 storeBuffer(sentry);
24ffafb4 276 storeAppendPrintf(sentry, "KEY %s\n", storeKeyText(entry->key));
2ac237e2 277 if (mem)
278 storeAppendPrintf(sentry, "\t%s %s\n",
279 RequestMethodStr[mem->method], mem->url);
637ed800 280 storeAppendPrintf(sentry, "\t%s\n", describeStatuses(entry));
281 storeAppendPrintf(sentry, "\t%s\n", describeFlags(entry));
282 storeAppendPrintf(sentry, "\t%s\n", describeTimestamps(entry));
283 storeAppendPrintf(sentry, "\t%d locks, %d clients, %d refs\n",
284 (int) entry->lock_count,
285 storePendingNClients(entry),
286 (int) entry->refcount);
287 storeAppendPrintf(sentry, "\tSwap File %#08X\n",
288 entry->swap_file_number);
289 if (mem == NULL)
290 continue;
291 storeAppendPrintf(sentry, "\tinmem_lo: %d\n", (int) mem->inmem_lo);
292 storeAppendPrintf(sentry, "\tinmem_hi: %d\n", (int) mem->inmem_hi);
293 storeAppendPrintf(sentry, "\tswapout: %d bytes done, %d queued, FD %d\n",
294 mem->swapout.done_offset,
295 mem->swapout.queue_offset,
296 mem->swapout.fd);
297 for (i = 0; i < mem->nclients; i++) {
298 sc = &mem->clients[i];
299 if (sc->callback_data == NULL)
300 continue;
301 storeAppendPrintf(sentry, "\tClient #%d\n", i);
302 storeAppendPrintf(sentry, "\t\tcopy_offset: %d\n",
303 (int) sc->copy_offset);
304 storeAppendPrintf(sentry, "\t\tseen_offset: %d\n",
305 (int) sc->seen_offset);
306 storeAppendPrintf(sentry, "\t\tcopy_size: %d\n",
307 (int) sc->copy_size);
308 storeAppendPrintf(sentry, "\t\tswapin_fd: %d\n",
309 (int) sc->swapin_fd);
310 }
24ffafb4 311 storeAppendPrintf(sentry, "\n");
438fc1e3 312 storeBufferFlush(sentry);
090089c4 313 }
090089c4 314}
315
03eb2f01 316void
603a02fd 317stat_objects_get(StoreEntry * e)
090089c4 318{
603a02fd 319 statObjects(e, 0);
6684fec0 320}
090089c4 321
6684fec0 322void
603a02fd 323stat_vmobjects_get(StoreEntry * e)
6684fec0 324{
603a02fd 325 statObjects(e, 1);
090089c4 326}
327
03eb2f01 328void
329server_list(StoreEntry * sentry)
e102ebda 330{
331 dump_peers(sentry, Config.peers);
332}
333
334void
335dump_peers(StoreEntry * sentry, peer * peers)
090089c4 336{
deb79f06 337 peer *e = NULL;
b012353a 338 struct _domain_ping *d = NULL;
30a4f2a8 339 icp_opcode op;
e102ebda 340 if (peers == NULL)
15576b6a 341 storeAppendPrintf(sentry, "There are no neighbors installed.\n");
e102ebda 342 for (e = peers; e; e = e->next) {
343 assert(e->host != NULL);
15576b6a 344 storeAppendPrintf(sentry, "\n%-11.11s: %s/%d/%d\n",
0c77d853 345 neighborTypeStr(e),
30a4f2a8 346 e->host,
347 e->http_port,
348 e->icp_port);
15576b6a 349 storeAppendPrintf(sentry, "Status : %s\n",
5269d0bd 350 neighborUp(e) ? "Up" : "Down");
15576b6a 351 storeAppendPrintf(sentry, "AVG RTT : %d msec\n", e->stats.rtt);
352 storeAppendPrintf(sentry, "LAST QUERY : %8d seconds ago\n",
dc835977 353 (int) (squid_curtime - e->stats.last_query));
15576b6a 354 storeAppendPrintf(sentry, "LAST REPLY : %8d seconds ago\n",
dc835977 355 (int) (squid_curtime - e->stats.last_reply));
15576b6a 356 storeAppendPrintf(sentry, "PINGS SENT : %8d\n", e->stats.pings_sent);
357 storeAppendPrintf(sentry, "PINGS ACKED: %8d %3d%%\n",
30a4f2a8 358 e->stats.pings_acked,
359 percent(e->stats.pings_acked, e->stats.pings_sent));
15576b6a 360 storeAppendPrintf(sentry, "FETCHES : %8d %3d%%\n",
0c77d853 361 e->stats.fetches,
362 percent(e->stats.fetches, e->stats.pings_acked));
15576b6a 363 storeAppendPrintf(sentry, "IGNORED : %8d %3d%%\n",
a7e59001 364 e->stats.ignored_replies,
365 percent(e->stats.ignored_replies, e->stats.pings_acked));
15576b6a 366 storeAppendPrintf(sentry, "Histogram of PINGS ACKED:\n");
27cd7235 367 for (op = ICP_INVALID; op < ICP_END; op++) {
30a4f2a8 368 if (e->stats.counts[op] == 0)
369 continue;
15576b6a 370 storeAppendPrintf(sentry, " %12.12s : %8d %3d%%\n",
27cd7235 371 icp_opcode_str[op],
30a4f2a8 372 e->stats.counts[op],
373 percent(e->stats.counts[op], e->stats.pings_acked));
374 }
090089c4 375 if (e->last_fail_time) {
15576b6a 376 storeAppendPrintf(sentry, "Last failed connect() at: %s\n",
090089c4 377 mkhttpdlogtime(&(e->last_fail_time)));
090089c4 378 }
15576b6a 379 if (e->pinglist != NULL)
380 storeAppendPrintf(sentry, "DOMAIN LIST: ");
b012353a 381 for (d = e->pinglist; d; d = d->next) {
090089c4 382 if (d->do_ping)
c30c5a73 383 storeAppendPrintf(sentry, "%s ", d->domain);
090089c4 384 else
c30c5a73 385 storeAppendPrintf(sentry, "!%s ", d->domain);
090089c4 386 }
15576b6a 387 storeAppendPrintf(sentry, "Keep-Alive Ratio: %d%%\n",
79d39a72 388 percent(e->stats.n_keepalives_recv, e->stats.n_keepalives_sent));
090089c4 389 }
090089c4 390}
391
0a0bf5db 392#ifdef XMALLOC_STATISTICS
b8d8561b 393static void
0a0bf5db 394info_get_mallstat(int size, int number, StoreEntry * sentry)
30a4f2a8 395{
30a4f2a8 396 if (number > 0)
15576b6a 397 storeAppendPrintf(sentry, "\t%d = %d\n", size, number);
30a4f2a8 398}
399#endif
090089c4 400
0ee4272b 401static const char *
f1dc9b30 402fdRemoteAddr(const fde * f)
d51e52f5 403{
95d659f0 404 LOCAL_ARRAY(char, buf, 32);
4f92c80c 405 if (f->type != FD_SOCKET)
406 return null_string;
042461c3 407 snprintf(buf, 32, "%s.%d", f->ipaddr, (int) f->remote_port);
d2af9477 408 return buf;
d51e52f5 409}
410
6684fec0 411void
b8d8561b 412statFiledescriptors(StoreEntry * sentry)
d51e52f5 413{
414 int i;
f1dc9b30 415 fde *f;
15576b6a 416 storeAppendPrintf(sentry, "Active file descriptors:\n");
417 storeAppendPrintf(sentry, "%-4s %-6s %-4s %-7s %-7s %-21s %s\n",
d51e52f5 418 "File",
419 "Type",
d51e52f5 420 "Tout",
4f92c80c 421 "Nread",
422 "Nwrite",
d51e52f5 423 "Remote Address",
424 "Description");
15576b6a 425 storeAppendPrintf(sentry, "---- ------ ---- ------- ------- --------------------- ------------------------------\n");
e83892e9 426 for (i = 0; i < Squid_MaxFD; i++) {
429fdbec 427 f = &fd_table[i];
5c5783a2 428 if (!f->open)
d51e52f5 429 continue;
15576b6a 430 storeAppendPrintf(sentry, "%4d %-6.6s %4d %7d %7d %-21s %s\n",
d2af9477 431 i,
22f5d1ca 432 fdTypeStr[f->type],
4f92c80c 433 f->timeout_handler ? (f->timeout - squid_curtime) / 60 : 0,
434 f->bytes_read,
435 f->bytes_written,
436 fdRemoteAddr(f),
437 f->desc);
d51e52f5 438 }
d51e52f5 439}
440
be335c22 441int
663eaa63 442statMemoryAccounted(void)
1a082686 443{
92a8c005 444 return (int)
9fb13bb6 445 meta_data.store_keys +
92a8c005 446 meta_data.ipcache_count * sizeof(ipcache_entry) +
f88bb09c 447 meta_data.fqdncache_count * sizeof(fqdncache_entry) +
b15fe823 448 hash_links_allocated * sizeof(hash_link) +
16300b58 449 meta_data.netdb_peers * sizeof(struct _net_db_peer) +
f6c78bd2 450 meta_data.client_info * client_info_sz +
f6610c4e 451 meta_data.misc;
1a082686 452}
453
03eb2f01 454void
455info_get(StoreEntry * sentry)
090089c4 456{
090089c4 457 struct rusage rusage;
f2908497 458 double cputime;
459 double runtime;
88738790 460#if HAVE_MSTATS && HAVE_GNUMALLOC_H
461 struct mstats ms;
462#elif HAVE_MALLINFO
090089c4 463 struct mallinfo mp;
88738790 464 int t;
090089c4 465#endif
466
f2908497 467 runtime = tvSubDsec(squid_start, current_time);
468 if (runtime == 0.0)
469 runtime = 1.0;
15576b6a 470 storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
d51e52f5 471 version_string);
15576b6a 472 storeAppendPrintf(sentry, "Start Time:\t%s\n",
f2908497 473 mkrfc1123(squid_start.tv_sec));
15576b6a 474 storeAppendPrintf(sentry, "Current Time:\t%s\n",
f2908497 475 mkrfc1123(current_time.tv_sec));
15576b6a 476 storeAppendPrintf(sentry, "Connection information for %s:\n",
d51e52f5 477 appname);
15576b6a 478 storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%u\n",
f2908497 479 Counter.client_http.requests);
15576b6a 480 storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%u\n",
f2908497 481 Counter.icp.pkts_recv);
15576b6a 482 storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%u\n",
f2908497 483 Counter.icp.pkts_sent);
15576b6a 484 storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f%%\n",
88aad2e5 485 request_failure_ratio);
f2908497 486
15576b6a 487 storeAppendPrintf(sentry, "\tHTTP requests per minute:\t%.1f\n",
f2908497 488 Counter.client_http.requests / (runtime / 60.0));
15576b6a 489 storeAppendPrintf(sentry, "\tICP messages per minute:\t%.1f\n",
f2908497 490 (Counter.icp.pkts_sent + Counter.icp.pkts_recv) / (runtime / 60.0));
15576b6a 491 storeAppendPrintf(sentry, "\tSelect loop called: %d times, %0.3f ms avg\n",
f2908497 492 Counter.select_loops, 1000.0 * runtime / Counter.select_loops);
090089c4 493
15576b6a 494 storeAppendPrintf(sentry, "Cache information for %s:\n",
30a4f2a8 495 appname);
15576b6a 496 storeAppendPrintf(sentry, "\tStorage Swap size:\t%d KB\n",
c932b107 497 store_swap_size);
15576b6a 498 storeAppendPrintf(sentry, "\tStorage Mem size:\t%d KB\n",
e954773d 499 store_mem_size >> 10);
15576b6a 500 storeAppendPrintf(sentry, "\tStorage LRU Expiration Age:\t%6.2f days\n",
52cd89fd 501 (double) storeExpiredReferenceAge() / 86400.0);
15576b6a 502 storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%d\n",
f2908497 503 Counter.unlink.requests);
090089c4 504
f2908497 505 squid_getrusage(&rusage);
506 cputime = rusage_cputime(&rusage);
15576b6a 507 storeAppendPrintf(sentry, "Resource usage for %s:\n", appname);
508 storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", runtime);
509 storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", cputime);
510 storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
f2908497 511 dpercent(cputime, runtime));
15576b6a 512 storeAppendPrintf(sentry, "\tMaximum Resident Size: %ld KB\n",
f2908497 513 rusage_maxrss(&rusage));
15576b6a 514 storeAppendPrintf(sentry, "\tPage faults with physical i/o: %ld\n",
f2908497 515 rusage_pagefaults(&rusage));
090089c4 516
88738790 517#if HAVE_MSTATS && HAVE_GNUMALLOC_H
518 ms = mstats();
15576b6a 519 storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",
88738790 520 appname);
15576b6a 521 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
88738790 522 ms.bytes_total >> 10);
15576b6a 523 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
88738790 524 ms.bytes_free >> 10, percent(ms.bytes_free, ms.bytes_total));
525#elif HAVE_MALLINFO
090089c4 526 mp = mallinfo();
15576b6a 527 storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",
d51e52f5 528 appname);
15576b6a 529 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
b560dd20 530 mp.arena >> 10);
15576b6a 531 storeAppendPrintf(sentry, "\tOrdinary blocks: %6d KB %6d blks\n",
30a4f2a8 532 mp.uordblks >> 10, mp.ordblks);
15576b6a 533 storeAppendPrintf(sentry, "\tSmall blocks: %6d KB %6d blks\n",
30a4f2a8 534 mp.usmblks >> 10, mp.smblks);
15576b6a 535 storeAppendPrintf(sentry, "\tHolding blocks: %6d KB %6d blks\n",
30a4f2a8 536 mp.hblkhd >> 10, mp.hblks);
15576b6a 537 storeAppendPrintf(sentry, "\tFree Small blocks: %6d KB\n",
30a4f2a8 538 mp.fsmblks >> 10);
15576b6a 539 storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6d KB\n",
30a4f2a8 540 mp.fordblks >> 10);
541 t = mp.uordblks + mp.usmblks + mp.hblkhd;
15576b6a 542 storeAppendPrintf(sentry, "\tTotal in use: %6d KB %d%%\n",
30a4f2a8 543 t >> 10, percent(t, mp.arena));
544 t = mp.fsmblks + mp.fordblks;
15576b6a 545 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
30a4f2a8 546 t >> 10, percent(t, mp.arena));
46c883ed 547#if HAVE_EXT_MALLINFO
15576b6a 548 storeAppendPrintf(sentry, "\tmax size of small blocks:\t%d\n", mp.mxfast);
549 storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%d\n",
090089c4 550 mp.nlblks);
15576b6a 551 storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%d\n", mp.grain);
552 storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%d\n"
090089c4 553 ,mp.uordbytes);
15576b6a 554 storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%d\n",
090089c4 555 mp.allocated);
15576b6a 556 storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%d\n",
090089c4 557 mp.treeoverhead);
46c883ed 558#endif /* HAVE_EXT_MALLINFO */
50bc2565 559#endif /* HAVE_MALLINFO */
090089c4 560
15576b6a 561 storeAppendPrintf(sentry, "File descriptor usage for %s:\n", appname);
562 storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n",
e83892e9 563 Squid_MaxFD);
15576b6a 564 storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4d\n",
429fdbec 565 Biggest_FD);
15576b6a 566 storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4d\n",
88738790 567 Number_FD);
15576b6a 568 storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4d\n",
88738790 569 Squid_MaxFD - Number_FD);
15576b6a 570 storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4d\n",
090089c4 571 RESERVED_FD);
090089c4 572
15576b6a 573 storeAppendPrintf(sentry, "Internal Data Structures:\n");
574 storeAppendPrintf(sentry, "\t%6d StoreEntries\n",
3f6c0fb2 575 memInUse(MEM_STOREENTRY));
15576b6a 576 storeAppendPrintf(sentry, "\t%6d StoreEntries with MemObjects\n",
3f6c0fb2 577 memInUse(MEM_MEMOBJECT));
15576b6a 578 storeAppendPrintf(sentry, "\t%6d StoreEntries with MemObject Data\n",
3f6c0fb2 579 memInUse(MEM_MEM_HDR));
15576b6a 580 storeAppendPrintf(sentry, "\t%6d Hot Object Cache Items\n",
30a4f2a8 581 meta_data.hot_vm);
30a4f2a8 582
15576b6a 583 storeAppendPrintf(sentry, "\t%-25.25s = %6d KB\n",
9fb13bb6 584 "StoreEntry Keys",
585 meta_data.store_keys >> 10);
a6f3a003 586
15576b6a 587 storeAppendPrintf(sentry, "\t%-25.25s %7d x %4d bytes = %6d KB\n",
30a4f2a8 588 "IPCacheEntry",
cff333e8 589 meta_data.ipcache_count,
590 (int) sizeof(ipcache_entry),
0d5fc38a 591 (int) (meta_data.ipcache_count * sizeof(ipcache_entry) >> 10));
cff333e8 592
15576b6a 593 storeAppendPrintf(sentry, "\t%-25.25s %7d x %4d bytes = %6d KB\n",
f88bb09c 594 "FQDNCacheEntry",
595 meta_data.fqdncache_count,
596 (int) sizeof(fqdncache_entry),
597 (int) (meta_data.fqdncache_count * sizeof(fqdncache_entry) >> 10));
598
15576b6a 599 storeAppendPrintf(sentry, "\t%-25.25s %7d x %4d bytes = %6d KB\n",
30a4f2a8 600 "Hash link",
b15fe823 601 hash_links_allocated,
cff333e8 602 (int) sizeof(hash_link),
b15fe823 603 (int) (hash_links_allocated * sizeof(hash_link) >> 10));
cff333e8 604
15576b6a 605 storeAppendPrintf(sentry, "\t%-25.25s %7d x %4d bytes = %6d KB\n",
429fdbec 606 "NetDB Peer Entries",
607 meta_data.netdb_peers,
608 (int) sizeof(struct _net_db_peer),
609 (int) (meta_data.netdb_peers * sizeof(struct _net_db_peer) >> 10));
610
15576b6a 611 storeAppendPrintf(sentry, "\t%-25.25s %7d x %4d bytes = %6d KB\n",
5ecceaa4 612 "ClientDB Entries",
613 meta_data.client_info,
614 client_info_sz,
615 (int) (meta_data.client_info * client_info_sz >> 10));
82696127 616
15576b6a 617 storeAppendPrintf(sentry, "\t%-25.25s = %6d KB\n",
30a4f2a8 618 "Miscellaneous",
619 meta_data.misc >> 10);
cff333e8 620
15576b6a 621 storeAppendPrintf(sentry, "\t%-25.25s = %6d KB\n",
30a4f2a8 622 "Total Accounted",
663eaa63 623 statMemoryAccounted() >> 10);
30a4f2a8 624
625#if XMALLOC_STATISTICS
15576b6a 626 storeAppendPrintf(sentry, "Memory allocation statistics\n");
30a4f2a8 627 malloc_statistics(info_get_mallstat, sentry);
628#endif
090089c4 629}
630
b8d8561b 631static void
a7c05555 632statCountersDump(StoreEntry * sentry)
090089c4 633{
a7c05555 634 StatCounters *f = &Counter;
635 struct rusage rusage;
636 squid_getrusage(&rusage);
637 f->page_faults = rusage_pagefaults(&rusage);
638 f->cputime = rusage_cputime(&rusage);
639 storeAppendPrintf(sentry, "client_http.requests = %d\n",
640 f->client_http.requests);
641 storeAppendPrintf(sentry, "client_http.hits = %d\n",
642 f->client_http.hits);
643 storeAppendPrintf(sentry, "client_http.errors = %d\n",
644 f->client_http.errors);
645 storeAppendPrintf(sentry, "client_http.kbytes_in = %d\n",
646 (int) f->client_http.kbytes_in.kb);
647 storeAppendPrintf(sentry, "client_http.kbytes_out = %d\n",
648 (int) f->client_http.kbytes_out.kb);
649 storeAppendPrintf(sentry, "icp.pkts_sent = %d\n",
650 f->icp.pkts_sent);
651 storeAppendPrintf(sentry, "icp.pkts_recv = %d\n",
652 f->icp.pkts_recv);
653 storeAppendPrintf(sentry, "icp.kbytes_sent = %d\n",
654 (int) f->icp.kbytes_sent.kb);
655 storeAppendPrintf(sentry, "icp.kbytes_recv = %d\n",
656 (int) f->icp.kbytes_recv.kb);
657 storeAppendPrintf(sentry, "unlink.requests = %d\n",
658 f->unlink.requests);
659 storeAppendPrintf(sentry, "page_faults = %d\n",
660 f->page_faults);
661 storeAppendPrintf(sentry, "select_loops = %d\n",
662 f->select_loops);
663 storeAppendPrintf(sentry, "cpu_time = %f\n",
664 f->cputime);
665 storeAppendPrintf(sentry, "wall_time = %f\n",
0e473d70 666 tvSubDsec(f->timestamp, current_time));
090089c4 667}
668
a7c05555 669#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
b8d8561b 670static void
a7c05555 671statAvgDump(StoreEntry * sentry, int minutes)
090089c4 672{
a7c05555 673 StatCounters *f;
674 StatCounters *l;
675 double dt;
676 double ct;
677 assert(N_COUNT_HIST > 1);
678 assert(minutes > 0);
679 f = &CountHist[0];
0e473d70 680 if (minutes > N_COUNT_HIST - 1)
681 minutes = N_COUNT_HIST - 1;
a7c05555 682 l = &CountHist[minutes];
683 dt = tvSubDsec(l->timestamp, f->timestamp);
684 ct = f->cputime - l->cputime;
685 storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
686 XAVG(client_http.requests));
687 storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
688 XAVG(client_http.hits));
689 storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
690 XAVG(client_http.errors));
691 storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
692 XAVG(client_http.kbytes_in.kb));
693 storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
694 XAVG(client_http.kbytes_out.kb));
695 storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
696 XAVG(icp.pkts_sent));
697 storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
698 XAVG(icp.pkts_recv));
699 storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
700 XAVG(icp.kbytes_sent.kb));
701 storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
702 XAVG(icp.kbytes_recv.kb));
703 storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
704 XAVG(unlink.requests));
705 storeAppendPrintf(sentry, "page_faults = %f/sec\n",
706 XAVG(page_faults));
707 storeAppendPrintf(sentry, "select_loops = %f/sec\n",
708 XAVG(select_loops));
709 storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct);
710 storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt);
0e473d70 711 storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt));
090089c4 712}
713
b8d8561b 714void
a7c05555 715statInit(void)
090089c4 716{
090089c4 717 int i;
a7c05555 718 debug(18, 5) ("statInit: Initializing...\n");
b716a8ad 719 for (i = 0; i < PCONN_HIST_SZ; i++) {
603a02fd 720 client_pconn_hist[i] = 0;
b716a8ad 721 server_pconn_hist[i] = 0;
722 }
a7c05555 723 memset(CountHist, '\0', N_COUNT_HIST * sizeof(StatCounters));
0e473d70 724 for (i = 0; i < N_COUNT_HIST; i++)
a7c05555 725 CountHist[i].timestamp = current_time;
726 Counter.timestamp = current_time;
727 eventAdd("statAvgTick", statAvgTick, NULL, 60);
6605655c 728}
729
730void
731pconnHistCount(int what, int i)
732{
733 if (i >= PCONN_HIST_SZ)
734 i = PCONN_HIST_SZ - 1;
735 /* what == 0 for client, 1 for server */
736 if (what == 0)
737 client_pconn_hist[i]++;
b716a8ad 738 else if (what == 1)
739 server_pconn_hist[i]++;
740 else
ce66013b 741 assert(0);
6605655c 742}
743
744void
745pconnHistDump(StoreEntry * e)
746{
747 int i;
748 storeAppendPrintf(e,
749 "Client-side persistent connection counts:\n"
750 "\n"
b716a8ad 751 "\treq/\n"
752 "\tconn count\n"
753 "\t---- ---------\n");
6605655c 754 for (i = 0; i < PCONN_HIST_SZ; i++) {
755 if (client_pconn_hist[i] == 0)
756 continue;
b716a8ad 757 storeAppendPrintf(e, "\t%4d %9d\n", i, client_pconn_hist[i]);
758 }
759 storeAppendPrintf(e,
760 "\n"
761 "Server-side persistent connection counts:\n"
762 "\n"
763 "\treq/\n"
764 "\tconn count\n"
765 "\t---- ---------\n");
766 for (i = 0; i < PCONN_HIST_SZ; i++) {
767 if (server_pconn_hist[i] == 0)
768 continue;
769 storeAppendPrintf(e, "\t%4d %9d\n", i, server_pconn_hist[i]);
6605655c 770 }
090089c4 771}
f2908497 772
f2908497 773static void
774statAvgTick(void *notused)
775{
d5649d9f 776 StatCounters *t = &CountHist[0];
777 StatCounters *p = &CountHist[1];
f2908497 778 StatCounters *c = &Counter;
779 struct rusage rusage;
780 eventAdd("statAvgTick", statAvgTick, NULL, 60);
20903cac 781 squid_getrusage(&rusage);
782 c->page_faults = rusage_pagefaults(&rusage);
783 c->cputime = rusage_cputime(&rusage);
d5649d9f 784 c->timestamp = current_time;
dbfed404 785 xmemmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
d5649d9f 786 memcpy(t, c, sizeof(StatCounters));
787 NCountHist++;
20903cac 788}
789
790void
0f5607d9 791statCounters(StoreEntry * e)
20903cac 792{
0e473d70 793 statCountersDump(e);
0f5607d9 794}
795
796void
797statAvg5min(StoreEntry * e)
798{
0e473d70 799 statAvgDump(e, 5);
a7c05555 800}
801
802void
0e473d70 803statAvg60min(StoreEntry * e)
a7c05555 804{
0e473d70 805 statAvgDump(e, 60);
f2908497 806}