]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stat.cc
cf_gen should use xcalloc() instead of calloc(), if for no other reason
[thirdparty/squid.git] / src / stat.cc
CommitLineData
30a4f2a8 1/*
59a1efb2 2 * $Id: stat.cc,v 1.390 2005/09/09 17:31:33 wessels Exp $
30a4f2a8 3 *
4 * DEBUG: section 18 Cache Manager Statistics
5 * AUTHOR: Harvest Derived
6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 8 * ----------------------------------------------------------
30a4f2a8 9 *
2b6662ba 10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
30a4f2a8 18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
cbdec147 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 32 *
019dd986 33 */
ed43818f 34
44a47c6e 35#include "squid.h"
c8be6d7b 36#include "StoreClient.h"
d3f603c8 37#include "AuthUserRequest.h"
e6ccf245 38#include "Store.h"
d3f603c8 39#include "HttpRequest.h"
528b2c61 40#include "MemObject.h"
41#include "fde.h"
42#include "mem_node.h"
8faa78e6 43#if DELAY_POOLS
44#include "DelayId.h"
45#endif
528b2c61 46#include "client_side_request.h"
a46d2c0e 47#include "client_side.h"
528b2c61 48
49/* these are included because they expose stats calls */
50/* TODO: provide a self registration mechanism for those classes
51 * to use during static construction
52 */
53#include "comm.h"
c8f4eac4 54#include "StoreSearch.h"
090089c4 55
ae94d28e 56#define DEBUG_OPENFD 1
57
1da3b90b 58typedef int STOBJFLT(const StoreEntry *);
62e76326 59
c8f4eac4 60class StatObjectsState
62e76326 61{
c8f4eac4 62
63public:
1da3b90b 64 StoreEntry *sentry;
1da3b90b 65 STOBJFLT *filter;
c8f4eac4 66 StoreSearchPointer theSearch;
67
68private:
69 CBDATA_CLASS2(StatObjectsState);
70};
62e76326 71
1da3b90b 72
67508012 73/* LOCALS */
f5b8bbc4 74static const char *describeStatuses(const StoreEntry *);
f5b8bbc4 75static const char *describeTimestamps(const StoreEntry *);
f2908497 76static void statAvgTick(void *notused);
a0f32775 77static void statAvgDump(StoreEntry *, int minutes, int hours);
01aebf31 78#if STAT_GRAPHS
79static void statGraphDump(StoreEntry *);
80#endif
12cf1be2 81static void statCountersInit(StatCounters *);
1d803566 82static void statCountersInitSpecial(StatCounters *);
12cf1be2 83static void statCountersClean(StatCounters *);
2ac76861 84static void statCountersCopy(StatCounters * dest, const StatCounters * orig);
7d94ae33 85static double statMedianSvc(int, int);
fcc35180 86static void statStoreEntry(MemBuf * mb, StoreEntry * e);
49ad0a8c 87static double statCPUUsage(int minutes);
ed7f5615 88static OBJH stat_io_get;
89static OBJH stat_objects_get;
90static OBJH stat_vmobjects_get;
ae94d28e 91#if DEBUG_OPENFD
92static OBJH statOpenfdObj;
93#endif
1da3b90b 94static EVH statObjects;
ed7f5615 95static OBJH info_get;
071a3ae7 96static OBJH statCountersDump;
a1e927f6 97static OBJH statPeerSelect;
26b164ac 98static OBJH statDigestBlob;
ed7f5615 99static OBJH statAvg5min;
45eb7f49 100static OBJH statAvg60min;
e9b5ead4 101static OBJH statUtilization;
ba4f8e5a 102static OBJH statCountersHistograms;
0f1bc304 103static OBJH statClientRequests;
20882fb1 104
20882fb1 105#ifdef XMALLOC_STATISTICS
58cd5bbd 106static void info_get_mallstat(int, int, int, void *);
107static double xm_time;
108static double xm_deltat;
20882fb1 109#endif
30a4f2a8 110
a9113eb0 111StatCounters CountHist[N_COUNT_HIST];
d5649d9f 112static int NCountHist = 0;
a0f32775 113static StatCounters CountHourHist[N_COUNT_HOUR_HIST];
114static int NCountHourHist = 0;
c8f4eac4 115CBDATA_CLASS_INIT(StatObjectsState);
a0f32775 116
d480bbc0 117extern unsigned int mem_pool_alloc_calls;
118extern unsigned int mem_pool_free_calls;
119
5e29a294 120static void
e9b5ead4 121statUtilization(StoreEntry * e)
a0f32775 122{
123 storeAppendPrintf(e, "Cache Utilisation:\n");
124 storeAppendPrintf(e, "\n");
125 storeAppendPrintf(e, "Last 5 minutes:\n");
62e76326 126
a0f32775 127 if (NCountHist >= 5)
62e76326 128 statAvgDump(e, 5, 0);
a0f32775 129 else
62e76326 130 storeAppendPrintf(e, "(no values recorded yet)\n");
131
a0f32775 132 storeAppendPrintf(e, "\n");
62e76326 133
a0f32775 134 storeAppendPrintf(e, "Last 15 minutes:\n");
62e76326 135
a0f32775 136 if (NCountHist >= 15)
62e76326 137 statAvgDump(e, 15, 0);
a0f32775 138 else
62e76326 139 storeAppendPrintf(e, "(no values recorded yet)\n");
140
a0f32775 141 storeAppendPrintf(e, "\n");
62e76326 142
a0f32775 143 storeAppendPrintf(e, "Last hour:\n");
62e76326 144
a0f32775 145 if (NCountHist >= 60)
62e76326 146 statAvgDump(e, 60, 0);
a0f32775 147 else
62e76326 148 storeAppendPrintf(e, "(no values recorded yet)\n");
149
a0f32775 150 storeAppendPrintf(e, "\n");
62e76326 151
a0f32775 152 storeAppendPrintf(e, "Last 8 hours:\n");
62e76326 153
a0f32775 154 if (NCountHourHist >= 8)
62e76326 155 statAvgDump(e, 0, 8);
a0f32775 156 else
62e76326 157 storeAppendPrintf(e, "(no values recorded yet)\n");
158
a0f32775 159 storeAppendPrintf(e, "\n");
62e76326 160
a0f32775 161 storeAppendPrintf(e, "Last day:\n");
62e76326 162
a0f32775 163 if (NCountHourHist >= 24)
62e76326 164 statAvgDump(e, 0, 24);
a0f32775 165 else
62e76326 166 storeAppendPrintf(e, "(no values recorded yet)\n");
167
a0f32775 168 storeAppendPrintf(e, "\n");
62e76326 169
a0f32775 170 storeAppendPrintf(e, "Last 3 days:\n");
62e76326 171
a0f32775 172 if (NCountHourHist >= 72)
62e76326 173 statAvgDump(e, 0, 72);
a0f32775 174 else
62e76326 175 storeAppendPrintf(e, "(no values recorded yet)\n");
176
a0f32775 177 storeAppendPrintf(e, "\n");
62e76326 178
a0f32775 179 storeAppendPrintf(e, "Totals since cache startup:\n");
62e76326 180
a0f32775 181 statCountersDump(e);
182}
f2908497 183
5e29a294 184static void
b8d8561b 185stat_io_get(StoreEntry * sentry)
30a4f2a8 186{
187 int i;
188
15576b6a 189 storeAppendPrintf(sentry, "HTTP I/O\n");
190 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Http.reads);
15576b6a 191 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 192
30a4f2a8 193 for (i = 0; i < 16; i++) {
62e76326 194 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
195 i ? (1 << (i - 1)) + 1 : 1,
196 1 << i,
197 IOStats.Http.read_hist[i],
198 percent(IOStats.Http.read_hist[i], IOStats.Http.reads));
30a4f2a8 199 }
200
15576b6a 201 storeAppendPrintf(sentry, "\n");
202 storeAppendPrintf(sentry, "FTP I/O\n");
203 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Ftp.reads);
15576b6a 204 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 205
30a4f2a8 206 for (i = 0; i < 16; i++) {
62e76326 207 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
208 i ? (1 << (i - 1)) + 1 : 1,
209 1 << i,
210 IOStats.Ftp.read_hist[i],
211 percent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads));
30a4f2a8 212 }
213
15576b6a 214 storeAppendPrintf(sentry, "\n");
215 storeAppendPrintf(sentry, "Gopher I/O\n");
216 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Gopher.reads);
15576b6a 217 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 218
56fa4cad 219 for (i = 0; i < 16; i++) {
62e76326 220 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
221 i ? (1 << (i - 1)) + 1 : 1,
222 1 << i,
223 IOStats.Gopher.read_hist[i],
224 percent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads));
56fa4cad 225 }
226
15576b6a 227 storeAppendPrintf(sentry, "\n");
228 storeAppendPrintf(sentry, "WAIS I/O\n");
229 storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Wais.reads);
15576b6a 230 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 231
56fa4cad 232 for (i = 0; i < 16; i++) {
62e76326 233 storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
234 i ? (1 << (i - 1)) + 1 : 1,
235 1 << i,
236 IOStats.Wais.read_hist[i],
237 percent(IOStats.Wais.read_hist[i], IOStats.Wais.reads));
56fa4cad 238 }
090089c4 239}
240
0ee4272b 241static const char *
fe4e214f 242describeStatuses(const StoreEntry * entry)
d1a43e28 243{
244 LOCAL_ARRAY(char, buf, 256);
56878878 245 snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
62e76326 246 storeStatusStr[entry->store_status],
247 memStatusStr[entry->mem_status],
248 swapStatusStr[entry->swap_status],
249 pingStatusStr[entry->ping_status]);
d1a43e28 250 return buf;
251}
252
415e0dd2 253const char *
254storeEntryFlags(const StoreEntry * entry)
d1a43e28 255{
256 LOCAL_ARRAY(char, buf, 256);
315005bd 257 int flags = (int) entry->flags;
d1a43e28 258 char *t;
259 buf[0] = '\0';
62e76326 260
7d94ae33 261 if (EBIT_TEST(flags, ENTRY_SPECIAL))
62e76326 262 strcat(buf, "SPECIAL,");
263
7d94ae33 264 if (EBIT_TEST(flags, ENTRY_REVALIDATE))
62e76326 265 strcat(buf, "REVALIDATE,");
266
7d94ae33 267 if (EBIT_TEST(flags, DELAY_SENDING))
62e76326 268 strcat(buf, "DELAY_SENDING,");
269
7d94ae33 270 if (EBIT_TEST(flags, RELEASE_REQUEST))
62e76326 271 strcat(buf, "RELEASE_REQUEST,");
272
7d94ae33 273 if (EBIT_TEST(flags, REFRESH_REQUEST))
62e76326 274 strcat(buf, "REFRESH_REQUEST,");
275
7d94ae33 276 if (EBIT_TEST(flags, ENTRY_CACHABLE))
62e76326 277 strcat(buf, "CACHABLE,");
278
7d94ae33 279 if (EBIT_TEST(flags, ENTRY_DISPATCHED))
62e76326 280 strcat(buf, "DISPATCHED,");
281
7d94ae33 282 if (EBIT_TEST(flags, KEY_PRIVATE))
62e76326 283 strcat(buf, "PRIVATE,");
284
05b0ef8a 285 if (EBIT_TEST(flags, ENTRY_FWD_HDR_WAIT))
62e76326 286 strcat(buf, "FWD_HDR_WAIT,");
287
7d94ae33 288 if (EBIT_TEST(flags, ENTRY_NEGCACHED))
62e76326 289 strcat(buf, "NEGCACHED,");
290
7d94ae33 291 if (EBIT_TEST(flags, ENTRY_VALIDATED))
62e76326 292 strcat(buf, "VALIDATED,");
293
7d94ae33 294 if (EBIT_TEST(flags, ENTRY_BAD_LENGTH))
62e76326 295 strcat(buf, "BAD_LENGTH,");
296
d2e002d1 297 if (EBIT_TEST(flags, ENTRY_ABORTED))
62e76326 298 strcat(buf, "ABORTED,");
299
d1a43e28 300 if ((t = strrchr(buf, ',')))
62e76326 301 *t = '\0';
302
d1a43e28 303 return buf;
304}
305
0ee4272b 306static const char *
fe4e214f 307describeTimestamps(const StoreEntry * entry)
d1a43e28 308{
309 LOCAL_ARRAY(char, buf, 256);
56878878 310 snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
62e76326 311 (int) entry->timestamp,
312 (int) entry->lastref,
313 (int) entry->lastmod,
314 (int) entry->expires);
d1a43e28 315 return buf;
316}
317
b8d8561b 318static void
fcc35180 319statStoreEntry(MemBuf * mb, StoreEntry * e)
090089c4 320{
a5a5de87 321 MemObject *mem = e->mem_obj;
fcc35180 322 memBufPrintf(mb, "KEY %s\n", e->getMD5Text());
323 memBufPrintf(mb, "\t%s\n", describeStatuses(e));
324 memBufPrintf(mb, "\t%s\n", storeEntryFlags(e));
325 memBufPrintf(mb, "\t%s\n", describeTimestamps(e));
326 memBufPrintf(mb, "\t%d locks, %d clients, %d refs\n",
327 (int) e->lock_count,
328 storePendingNClients(e),
329 (int) e->refcount);
330 memBufPrintf(mb, "\tSwap Dir %d, File %#08X\n",
331 e->swap_dirn, e->swap_filen);
62e76326 332
528b2c61 333 if (mem != NULL)
fcc35180 334 mem->stat (mb);
62e76326 335
fcc35180 336 memBufPrintf(mb, "\n");
a5a5de87 337}
338
339/* process objects list */
340static void
1da3b90b 341statObjects(void *data)
a5a5de87 342{
e6ccf245 343 StatObjectsState *state = static_cast<StatObjectsState *>(data);
1da3b90b 344 StoreEntry *e;
62e76326 345
c8f4eac4 346 if (state->theSearch->isDone()) {
62e76326 347 state->sentry->complete();
348 storeUnlockObject(state->sentry);
349 cbdataFree(state);
350 return;
b7fe0ab0 351 } else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) {
62e76326 352 storeUnlockObject(state->sentry);
353 cbdataFree(state);
354 return;
a46d2c0e 355 } else if (state->sentry->checkDeferRead(-1)) {
62e76326 356 eventAdd("statObjects", statObjects, state, 0.1, 1);
357 return;
1da3b90b 358 }
62e76326 359
c8f4eac4 360 storeBuffer(state->sentry);
361 size_t statCount = 0;
362 MemBuf mb;
363 memBufDefInit(&mb);
62e76326 364
c8f4eac4 365 while (statCount++ < static_cast<size_t>(Config.Store.objectsPerBucket) && state->
366 theSearch->next()) {
367 e = state->theSearch->currentItem();
62e76326 368
c8f4eac4 369 if (state->filter && 0 == state->filter(e))
370 continue;
62e76326 371
c8f4eac4 372 statStoreEntry(&mb, e);
373 }
fcc35180 374
c8f4eac4 375 if (mb.size)
fcc35180 376 storeAppend(state->sentry, mb.buf, mb.size);
c8f4eac4 377 memBufClean(&mb);
62e76326 378
1da3b90b 379 eventAdd("statObjects", statObjects, state, 0.0, 1);
a5a5de87 380}
381
5e29a294 382static void
1da3b90b 383statObjectsStart(StoreEntry * sentry, STOBJFLT * filter)
384{
c8f4eac4 385 StatObjectsState *state = new StatObjectsState;
1da3b90b 386 state->sentry = sentry;
387 state->filter = filter;
388 storeLockObject(sentry);
c8f4eac4 389 state->theSearch = Store::Root().search(NULL, NULL);
1da3b90b 390 eventAdd("statObjects", statObjects, state, 0.0, 1);
391}
392
393static void
394stat_objects_get(StoreEntry * sentry)
395{
396 statObjectsStart(sentry, NULL);
397}
398
399static int
400statObjectsVmFilter(const StoreEntry * e)
090089c4 401{
1da3b90b 402 return e->mem_obj ? 1 : 0;
6684fec0 403}
090089c4 404
5e29a294 405static void
1da3b90b 406stat_vmobjects_get(StoreEntry * sentry)
6684fec0 407{
1da3b90b 408 statObjectsStart(sentry, statObjectsVmFilter);
090089c4 409}
410
ae94d28e 411#if DEBUG_OPENFD
1da3b90b 412static int
413statObjectsOpenfdFilter(const StoreEntry * e)
414{
415 if (e->mem_obj == NULL)
62e76326 416 return 0;
417
2391a162 418 if (e->mem_obj->swapout.sio == NULL)
62e76326 419 return 0;
420
1da3b90b 421 return 1;
422}
423
ae94d28e 424static void
425statOpenfdObj(StoreEntry * sentry)
426{
1da3b90b 427 statObjectsStart(sentry, statObjectsOpenfdFilter);
ae94d28e 428}
1da3b90b 429
ae94d28e 430#endif
431
0a0bf5db 432#ifdef XMALLOC_STATISTICS
b8d8561b 433static void
58cd5bbd 434info_get_mallstat(int size, int number, int oldnum, void *data)
30a4f2a8 435{
18f2f920 436 StoreEntry *sentry = (StoreEntry *)data;
62e76326 437
30a4f2a8 438 if (number > 0)
62e76326 439 storeAppendPrintf(sentry, "%d\t %d\t %d\t %.1f\n", size, number, number - oldnum, xdiv((number - oldnum), xm_deltat));
30a4f2a8 440}
62e76326 441
30a4f2a8 442#endif
090089c4 443
5e29a294 444static void
03eb2f01 445info_get(StoreEntry * sentry)
090089c4 446{
62e76326 447
090089c4 448 struct rusage rusage;
f2908497 449 double cputime;
450 double runtime;
88738790 451#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 452
88738790 453 struct mstats ms;
eb824054 454#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 455
090089c4 456 struct mallinfo mp;
88738790 457 int t;
090089c4 458#endif
459
f2908497 460 runtime = tvSubDsec(squid_start, current_time);
62e76326 461
f2908497 462 if (runtime == 0.0)
62e76326 463 runtime = 1.0;
464
15576b6a 465 storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
62e76326 466 version_string);
467
ec4daaa5 468#ifdef _SQUID_WIN32_
1a774556 469
470 if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
471 storeAppendPrintf(sentry,"\nRunning as %s Windows System Service on %s\n",
472 WIN32_Service_name, WIN32_OS_string);
473 storeAppendPrintf(sentry,"Service command line is: %s\n", WIN32_Service_Command_Line);
474 } else
475 storeAppendPrintf(sentry,"Running on %s\n",WIN32_OS_string);
476
477#endif
478
15576b6a 479 storeAppendPrintf(sentry, "Start Time:\t%s\n",
62e76326 480 mkrfc1123(squid_start.tv_sec));
481
15576b6a 482 storeAppendPrintf(sentry, "Current Time:\t%s\n",
62e76326 483 mkrfc1123(current_time.tv_sec));
484
15576b6a 485 storeAppendPrintf(sentry, "Connection information for %s:\n",
62e76326 486 appname);
487
98829f69 488 storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%u\n",
62e76326 489 statCounter.client_http.clients);
490
15576b6a 491 storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%u\n",
62e76326 492 statCounter.client_http.requests);
493
15576b6a 494 storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%u\n",
62e76326 495 statCounter.icp.pkts_recv);
496
15576b6a 497 storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%u\n",
62e76326 498 statCounter.icp.pkts_sent);
499
2e8e29b8 500 storeAppendPrintf(sentry, "\tNumber of queued ICP replies:\t%u\n",
62e76326 501 statCounter.icp.replies_queued);
502
c4ebc830 503#if USE_HTCP
504
505 storeAppendPrintf(sentry, "\tNumber of HTCP messages received:\t%u\n",
506 statCounter.htcp.pkts_recv);
507
508 storeAppendPrintf(sentry, "\tNumber of HTCP messages sent:\t%u\n",
509 statCounter.htcp.pkts_sent);
510
511#endif
512
a4ba1105 513 storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f\n",
62e76326 514 request_failure_ratio);
f2908497 515
b51b0e13 516 storeAppendPrintf(sentry, "\tAverage HTTP requests per minute since start:\t%.1f\n",
62e76326 517 statCounter.client_http.requests / (runtime / 60.0));
518
b51b0e13 519 storeAppendPrintf(sentry, "\tAverage ICP messages per minute since start:\t%.1f\n",
62e76326 520 (statCounter.icp.pkts_sent + statCounter.icp.pkts_recv) / (runtime / 60.0));
521
15576b6a 522 storeAppendPrintf(sentry, "\tSelect loop called: %d times, %0.3f ms avg\n",
62e76326 523 statCounter.select_loops, 1000.0 * runtime / statCounter.select_loops);
090089c4 524
15576b6a 525 storeAppendPrintf(sentry, "Cache information for %s:\n",
62e76326 526 appname);
527
5bf79e53 528 storeAppendPrintf(sentry, "\tHits as %% of all requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
62e76326 529 statRequestHitRatio(5),
530 statRequestHitRatio(60));
531
5bf79e53 532 storeAppendPrintf(sentry, "\tHits as %% of bytes sent:\t5min: %3.1f%%, 60min: %3.1f%%\n",
62e76326 533 statByteHitRatio(5),
534 statByteHitRatio(60));
535
5bf79e53 536 storeAppendPrintf(sentry, "\tMemory hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
62e76326 537 statRequestHitMemoryRatio(5),
538 statRequestHitMemoryRatio(60));
539
5bf79e53 540 storeAppendPrintf(sentry, "\tDisk hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
62e76326 541 statRequestHitDiskRatio(5),
542 statRequestHitDiskRatio(60));
543
e6ccf245 544 storeAppendPrintf(sentry, "\tStorage Swap size:\t%lu KB\n",
62e76326 545 store_swap_size);
546
15576b6a 547 storeAppendPrintf(sentry, "\tStorage Mem size:\t%d KB\n",
62e76326 548 (int) (mem_node::store_mem_size >> 10));
549
0faf70d0 550 storeAppendPrintf(sentry, "\tMean Object Size:\t%0.2f KB\n",
62e76326 551 n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0);
552
15576b6a 553 storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%d\n",
62e76326 554 statCounter.unlink.requests);
090089c4 555
b87b92fb 556 storeAppendPrintf(sentry, "Median Service Times (seconds) 5 min 60 min:\n");
62e76326 557
b87b92fb 558 storeAppendPrintf(sentry, "\tHTTP Requests (All): %8.5f %8.5f\n",
62e76326 559 statMedianSvc(5, MEDIAN_HTTP) / 1000.0,
560 statMedianSvc(60, MEDIAN_HTTP) / 1000.0);
561
b87b92fb 562 storeAppendPrintf(sentry, "\tCache Misses: %8.5f %8.5f\n",
62e76326 563 statMedianSvc(5, MEDIAN_MISS) / 1000.0,
564 statMedianSvc(60, MEDIAN_MISS) / 1000.0);
565
b87b92fb 566 storeAppendPrintf(sentry, "\tCache Hits: %8.5f %8.5f\n",
62e76326 567 statMedianSvc(5, MEDIAN_HIT) / 1000.0,
568 statMedianSvc(60, MEDIAN_HIT) / 1000.0);
569
7c9c84ad 570 storeAppendPrintf(sentry, "\tNear Hits: %8.5f %8.5f\n",
62e76326 571 statMedianSvc(5, MEDIAN_NH) / 1000.0,
572 statMedianSvc(60, MEDIAN_NH) / 1000.0);
573
b87b92fb 574 storeAppendPrintf(sentry, "\tNot-Modified Replies: %8.5f %8.5f\n",
62e76326 575 statMedianSvc(5, MEDIAN_NM) / 1000.0,
576 statMedianSvc(60, MEDIAN_NM) / 1000.0);
577
b87b92fb 578 storeAppendPrintf(sentry, "\tDNS Lookups: %8.5f %8.5f\n",
62e76326 579 statMedianSvc(5, MEDIAN_DNS) / 1000.0,
580 statMedianSvc(60, MEDIAN_DNS) / 1000.0);
581
b87b92fb 582 storeAppendPrintf(sentry, "\tICP Queries: %8.5f %8.5f\n",
62e76326 583 statMedianSvc(5, MEDIAN_ICP_QUERY) / 1000000.0,
584 statMedianSvc(60, MEDIAN_ICP_QUERY) / 1000000.0);
b87b92fb 585
f2908497 586 squid_getrusage(&rusage);
62e76326 587
f2908497 588 cputime = rusage_cputime(&rusage);
62e76326 589
15576b6a 590 storeAppendPrintf(sentry, "Resource usage for %s:\n", appname);
62e76326 591
15576b6a 592 storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", runtime);
62e76326 593
15576b6a 594 storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", cputime);
62e76326 595
15576b6a 596 storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
62e76326 597 dpercent(cputime, runtime));
598
979533fa 599 storeAppendPrintf(sentry, "\tCPU Usage, 5 minute avg:\t%.2f%%\n",
62e76326 600 statCPUUsage(5));
601
49ad0a8c 602 storeAppendPrintf(sentry, "\tCPU Usage, 60 minute avg:\t%.2f%%\n",
62e76326 603 statCPUUsage(60));
604
a4ba1105 605#if HAVE_SBRK
62e76326 606
a4ba1105 607 storeAppendPrintf(sentry, "\tProcess Data Segment Size via sbrk(): %d KB\n",
62e76326 608 (int) (((char *) sbrk(0) - (char *) sbrk_start) >> 10));
609
a4ba1105 610#endif
62e76326 611
5f6ac48b 612 storeAppendPrintf(sentry, "\tMaximum Resident Size: %d KB\n",
62e76326 613 rusage_maxrss(&rusage));
614
5f6ac48b 615 storeAppendPrintf(sentry, "\tPage faults with physical i/o: %d\n",
62e76326 616 rusage_pagefaults(&rusage));
090089c4 617
88738790 618#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 619
88738790 620 ms = mstats();
62e76326 621
15576b6a 622 storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",
62e76326 623 appname);
624
15576b6a 625 storeAppendPrintf(sentry, "\tTotal space in arena: %6d KB\n",
62e76326 626 ms.bytes_total >> 10);
627
15576b6a 628 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
62e76326 629 ms.bytes_free >> 10, percent(ms.bytes_free, ms.bytes_total));
630
eb824054 631#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 632
090089c4 633 mp = mallinfo();
62e76326 634
15576b6a 635 storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",
62e76326 636 appname);
637
e4049756 638 storeAppendPrintf(sentry, "\tTotal space in arena: %6ld KB\n",
639 (long)mp.arena >> 10);
62e76326 640
e4049756 641 storeAppendPrintf(sentry, "\tOrdinary blocks: %6ld KB %6ld blks\n",
642 (long)mp.uordblks >> 10, (long)mp.ordblks);
62e76326 643
e4049756 644 storeAppendPrintf(sentry, "\tSmall blocks: %6ld KB %6ld blks\n",
645 (long)mp.usmblks >> 10, (long)mp.smblks);
62e76326 646
e4049756 647 storeAppendPrintf(sentry, "\tHolding blocks: %6ld KB %6ld blks\n",
648 (long)mp.hblkhd >> 10, (long)mp.hblks);
62e76326 649
e4049756 650 storeAppendPrintf(sentry, "\tFree Small blocks: %6ld KB\n",
651 (long)mp.fsmblks >> 10);
62e76326 652
e4049756 653 storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6ld KB\n",
654 (long)mp.fordblks >> 10);
62e76326 655
30a4f2a8 656 t = mp.uordblks + mp.usmblks + mp.hblkhd;
62e76326 657
15576b6a 658 storeAppendPrintf(sentry, "\tTotal in use: %6d KB %d%%\n",
62e76326 659 t >> 10, percent(t, mp.arena + mp.hblkhd));
660
30a4f2a8 661 t = mp.fsmblks + mp.fordblks;
62e76326 662
15576b6a 663 storeAppendPrintf(sentry, "\tTotal free: %6d KB %d%%\n",
62e76326 664 t >> 10, percent(t, mp.arena + mp.hblkhd));
665
d96ceb8e 666 t = mp.arena + mp.hblkhd;
62e76326 667
d96ceb8e 668 storeAppendPrintf(sentry, "\tTotal size: %6d KB\n",
62e76326 669 t >> 10);
670
6a9f6389 671#if HAVE_STRUCT_MALLINFO_MXFAST
62e76326 672
15576b6a 673 storeAppendPrintf(sentry, "\tmax size of small blocks:\t%d\n", mp.mxfast);
62e76326 674
15576b6a 675 storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%d\n",
62e76326 676 mp.nlblks);
677
15576b6a 678 storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%d\n", mp.grain);
62e76326 679
15576b6a 680 storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%d\n"
62e76326 681 ,mp.uordbytes);
682
15576b6a 683 storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%d\n",
62e76326 684 mp.allocated);
685
15576b6a 686 storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%d\n",
62e76326 687 mp.treeoverhead);
688
6a9f6389 689#endif /* HAVE_STRUCT_MALLINFO_MXFAST */
50bc2565 690#endif /* HAVE_MALLINFO */
62e76326 691
5d1f3c82 692 storeAppendPrintf(sentry, "Memory accounted for:\n");
62e76326 693
d96ceb8e 694#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 695
d96ceb8e 696 storeAppendPrintf(sentry, "\tTotal accounted: %6d KB %3d%%\n",
62e76326 697 statMemoryAccounted() >> 10, percent(statMemoryAccounted(), t));
698
d96ceb8e 699#else
62e76326 700
979533fa 701 storeAppendPrintf(sentry, "\tTotal accounted: %6d KB\n",
62e76326 702 statMemoryAccounted() >> 10);
703
d96ceb8e 704#endif
705 {
62e76326 706 MemPoolGlobalStats mp_stats;
707 memPoolGetGlobalStats(&mp_stats);
1ce8e204 708#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 709
710 storeAppendPrintf(sentry, "\tmemPool accounted: %6d KB %3d%%\n",
e4049756 711 (int) mp_stats.TheMeter->alloc.level >> 10,
712 percent(mp_stats.TheMeter->alloc.level, t));
62e76326 713 storeAppendPrintf(sentry, "\tmemPool unaccounted: %6d KB %3d%%\n",
e4049756 714 (t - (int) mp_stats.TheMeter->alloc.level) >> 10,
715 percent((t - mp_stats.TheMeter->alloc.level), t));
1ce8e204 716#endif
62e76326 717
718 storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9.0f\n",
719 mp_stats.TheMeter->gb_saved.count);
720 storeAppendPrintf(sentry, "\tmemPoolFree calls: %9.0f\n",
721 mp_stats.TheMeter->gb_freed.count);
d96ceb8e 722 }
62e76326 723
15576b6a 724 storeAppendPrintf(sentry, "File descriptor usage for %s:\n", appname);
725 storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n",
62e76326 726 Squid_MaxFD);
15576b6a 727 storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4d\n",
62e76326 728 Biggest_FD);
15576b6a 729 storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4d\n",
62e76326 730 Number_FD);
b6a2f15e 731 storeAppendPrintf(sentry, "\tFiles queued for open: %4d\n",
62e76326 732 Opening_FD);
15576b6a 733 storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4d\n",
62e76326 734 fdNFree());
15576b6a 735 storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4d\n",
62e76326 736 RESERVED_FD);
83a29c95 737 storeAppendPrintf(sentry, "\tStore Disk files open: %4d\n",
62e76326 738 store_open_disk_fd);
090089c4 739
15576b6a 740 storeAppendPrintf(sentry, "Internal Data Structures:\n");
08433d3c 741 storeAppendPrintf(sentry, "\t%6lu StoreEntries\n",
62e76326 742 (unsigned long)StoreEntry::inUseCount());
528b2c61 743 storeAppendPrintf(sentry, "\t%6lu StoreEntries with MemObjects\n",
62e76326 744 (unsigned long)MemObject::inUseCount());
15576b6a 745 storeAppendPrintf(sentry, "\t%6d Hot Object Cache Items\n",
62e76326 746 hot_obj_count);
0b2e785a 747 storeAppendPrintf(sentry, "\t%6d on-disk objects\n",
62e76326 748 n_disk_objects);
30a4f2a8 749
750#if XMALLOC_STATISTICS
62e76326 751
58cd5bbd 752 xm_deltat = current_dtime - xm_time;
753 xm_time = current_dtime;
754 storeAppendPrintf(sentry, "\nMemory allocation statistics\n");
755 storeAppendPrintf(sentry, "Allocation Size\t Alloc Count\t Alloc Delta\t Allocs/sec \n");
30a4f2a8 756 malloc_statistics(info_get_mallstat, sentry);
757#endif
090089c4 758}
759
a7c05555 760#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
b8d8561b 761static void
a0f32775 762statAvgDump(StoreEntry * sentry, int minutes, int hours)
090089c4 763{
a7c05555 764 StatCounters *f;
765 StatCounters *l;
766 double dt;
767 double ct;
7ae52c25 768 double x;
a7c05555 769 assert(N_COUNT_HIST > 1);
a0f32775 770 assert(minutes > 0 || hours > 0);
a7c05555 771 f = &CountHist[0];
a0f32775 772 l = f;
62e76326 773
a0f32775 774 if (minutes > 0 && hours == 0) {
62e76326 775 /* checking minute readings ... */
776
777 if (minutes > N_COUNT_HIST - 1)
778 minutes = N_COUNT_HIST - 1;
779
780 l = &CountHist[minutes];
a0f32775 781 } else if (minutes == 0 && hours > 0) {
62e76326 782 /* checking hour readings ... */
783
784 if (hours > N_COUNT_HOUR_HIST - 1)
785 hours = N_COUNT_HOUR_HIST - 1;
786
787 l = &CountHourHist[hours];
a0f32775 788 } else {
62e76326 789 debug(18, 1) ("statAvgDump: Invalid args, minutes=%d, hours=%d\n",
790 minutes, hours);
791 return;
a0f32775 792 }
62e76326 793
a7c05555 794 dt = tvSubDsec(l->timestamp, f->timestamp);
795 ct = f->cputime - l->cputime;
ee1679df 796
399e85ea 797 storeAppendPrintf(sentry, "sample_start_time = %d.%d (%s)\n",
62e76326 798 (int) l->timestamp.tv_sec,
799 (int) l->timestamp.tv_usec,
800 mkrfc1123(l->timestamp.tv_sec));
5843f24a 801 storeAppendPrintf(sentry, "sample_end_time = %d.%d (%s)\n",
62e76326 802 (int) f->timestamp.tv_sec,
803 (int) f->timestamp.tv_usec,
804 mkrfc1123(f->timestamp.tv_sec));
a0f32775 805
a7c05555 806 storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
62e76326 807 XAVG(client_http.requests));
a7c05555 808 storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
62e76326 809 XAVG(client_http.hits));
a7c05555 810 storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
62e76326 811 XAVG(client_http.errors));
a7c05555 812 storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
62e76326 813 XAVG(client_http.kbytes_in.kb));
a7c05555 814 storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
62e76326 815 XAVG(client_http.kbytes_out.kb));
ee1679df 816
12cf1be2 817 x = statHistDeltaMedian(&l->client_http.all_svc_time,
62e76326 818 &f->client_http.all_svc_time);
ee1679df 819 storeAppendPrintf(sentry, "client_http.all_median_svc_time = %f seconds\n",
62e76326 820 x / 1000.0);
12cf1be2 821 x = statHistDeltaMedian(&l->client_http.miss_svc_time,
62e76326 822 &f->client_http.miss_svc_time);
ee1679df 823 storeAppendPrintf(sentry, "client_http.miss_median_svc_time = %f seconds\n",
62e76326 824 x / 1000.0);
12cf1be2 825 x = statHistDeltaMedian(&l->client_http.nm_svc_time,
62e76326 826 &f->client_http.nm_svc_time);
ee1679df 827 storeAppendPrintf(sentry, "client_http.nm_median_svc_time = %f seconds\n",
62e76326 828 x / 1000.0);
7c9c84ad 829 x = statHistDeltaMedian(&l->client_http.nh_svc_time,
62e76326 830 &f->client_http.nh_svc_time);
7c9c84ad 831 storeAppendPrintf(sentry, "client_http.nh_median_svc_time = %f seconds\n",
62e76326 832 x / 1000.0);
12cf1be2 833 x = statHistDeltaMedian(&l->client_http.hit_svc_time,
62e76326 834 &f->client_http.hit_svc_time);
ee1679df 835 storeAppendPrintf(sentry, "client_http.hit_median_svc_time = %f seconds\n",
62e76326 836 x / 1000.0);
071a3ae7 837
a0f32775 838 storeAppendPrintf(sentry, "server.all.requests = %f/sec\n",
62e76326 839 XAVG(server.all.requests));
a0f32775 840 storeAppendPrintf(sentry, "server.all.errors = %f/sec\n",
62e76326 841 XAVG(server.all.errors));
a0f32775 842 storeAppendPrintf(sentry, "server.all.kbytes_in = %f/sec\n",
62e76326 843 XAVG(server.all.kbytes_in.kb));
a0f32775 844 storeAppendPrintf(sentry, "server.all.kbytes_out = %f/sec\n",
62e76326 845 XAVG(server.all.kbytes_out.kb));
a0f32775 846
847 storeAppendPrintf(sentry, "server.http.requests = %f/sec\n",
62e76326 848 XAVG(server.http.requests));
a0f32775 849 storeAppendPrintf(sentry, "server.http.errors = %f/sec\n",
62e76326 850 XAVG(server.http.errors));
a0f32775 851 storeAppendPrintf(sentry, "server.http.kbytes_in = %f/sec\n",
62e76326 852 XAVG(server.http.kbytes_in.kb));
a0f32775 853 storeAppendPrintf(sentry, "server.http.kbytes_out = %f/sec\n",
62e76326 854 XAVG(server.http.kbytes_out.kb));
a0f32775 855
856 storeAppendPrintf(sentry, "server.ftp.requests = %f/sec\n",
62e76326 857 XAVG(server.ftp.requests));
a0f32775 858 storeAppendPrintf(sentry, "server.ftp.errors = %f/sec\n",
62e76326 859 XAVG(server.ftp.errors));
a0f32775 860 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %f/sec\n",
62e76326 861 XAVG(server.ftp.kbytes_in.kb));
a0f32775 862 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %f/sec\n",
62e76326 863 XAVG(server.ftp.kbytes_out.kb));
a0f32775 864
865 storeAppendPrintf(sentry, "server.other.requests = %f/sec\n",
62e76326 866 XAVG(server.other.requests));
a0f32775 867 storeAppendPrintf(sentry, "server.other.errors = %f/sec\n",
62e76326 868 XAVG(server.other.errors));
a0f32775 869 storeAppendPrintf(sentry, "server.other.kbytes_in = %f/sec\n",
62e76326 870 XAVG(server.other.kbytes_in.kb));
a0f32775 871 storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
62e76326 872 XAVG(server.other.kbytes_out.kb));
ee1679df 873
a7c05555 874 storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
62e76326 875 XAVG(icp.pkts_sent));
a7c05555 876 storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
62e76326 877 XAVG(icp.pkts_recv));
071a3ae7 878 storeAppendPrintf(sentry, "icp.queries_sent = %f/sec\n",
62e76326 879 XAVG(icp.queries_sent));
071a3ae7 880 storeAppendPrintf(sentry, "icp.replies_sent = %f/sec\n",
62e76326 881 XAVG(icp.replies_sent));
071a3ae7 882 storeAppendPrintf(sentry, "icp.queries_recv = %f/sec\n",
62e76326 883 XAVG(icp.queries_recv));
071a3ae7 884 storeAppendPrintf(sentry, "icp.replies_recv = %f/sec\n",
62e76326 885 XAVG(icp.replies_recv));
2e8e29b8 886 storeAppendPrintf(sentry, "icp.replies_queued = %f/sec\n",
62e76326 887 XAVG(icp.replies_queued));
071a3ae7 888 storeAppendPrintf(sentry, "icp.query_timeouts = %f/sec\n",
62e76326 889 XAVG(icp.query_timeouts));
a7c05555 890 storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
62e76326 891 XAVG(icp.kbytes_sent.kb));
a7c05555 892 storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
62e76326 893 XAVG(icp.kbytes_recv.kb));
071a3ae7 894 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %f/sec\n",
62e76326 895 XAVG(icp.q_kbytes_sent.kb));
071a3ae7 896 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %f/sec\n",
62e76326 897 XAVG(icp.r_kbytes_sent.kb));
071a3ae7 898 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %f/sec\n",
62e76326 899 XAVG(icp.q_kbytes_recv.kb));
071a3ae7 900 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %f/sec\n",
62e76326 901 XAVG(icp.r_kbytes_recv.kb));
12cf1be2 902 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
ee1679df 903 storeAppendPrintf(sentry, "icp.query_median_svc_time = %f seconds\n",
62e76326 904 x / 1000000.0);
12cf1be2 905 x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
ee1679df 906 storeAppendPrintf(sentry, "icp.reply_median_svc_time = %f seconds\n",
62e76326 907 x / 1000000.0);
12cf1be2 908 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
9973e9fe 909 storeAppendPrintf(sentry, "dns.median_svc_time = %f seconds\n",
62e76326 910 x / 1000.0);
a7c05555 911 storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
62e76326 912 XAVG(unlink.requests));
a7c05555 913 storeAppendPrintf(sentry, "page_faults = %f/sec\n",
62e76326 914 XAVG(page_faults));
a7c05555 915 storeAppendPrintf(sentry, "select_loops = %f/sec\n",
62e76326 916 XAVG(select_loops));
d239c2f5 917 storeAppendPrintf(sentry, "select_fds = %f/sec\n",
62e76326 918 XAVG(select_fds));
d239c2f5 919 storeAppendPrintf(sentry, "average_select_fd_period = %f/fd\n",
62e76326 920 f->select_fds > l->select_fds ?
921 (f->select_time - l->select_time) / (f->select_fds - l->select_fds)
922 : 0.0);
26d6ee93 923 x = statHistDeltaMedian(&l->select_fds_hist, &f->select_fds_hist);
924 storeAppendPrintf(sentry, "median_select_fds = %f\n", x);
23dc8aca 925 storeAppendPrintf(sentry, "swap.outs = %f/sec\n",
62e76326 926 XAVG(swap.outs));
23dc8aca 927 storeAppendPrintf(sentry, "swap.ins = %f/sec\n",
62e76326 928 XAVG(swap.ins));
23dc8aca 929 storeAppendPrintf(sentry, "swap.files_cleaned = %f/sec\n",
62e76326 930 XAVG(swap.files_cleaned));
bfae3379 931 storeAppendPrintf(sentry, "aborted_requests = %f/sec\n",
62e76326 932 XAVG(aborted_requests));
886f2785 933
1b3db6d9 934#if USE_POLL
62e76326 935
886f2785 936 storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", XAVG(syscalls.polls));
1b3db6d9 937#endif
938#if USE_SELECT
62e76326 939
886f2785 940 storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", XAVG(syscalls.selects));
941#endif
62e76326 942
886f2785 943 storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", XAVG(syscalls.disk.opens));
944 storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", XAVG(syscalls.disk.closes));
945 storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", XAVG(syscalls.disk.reads));
946 storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", XAVG(syscalls.disk.writes));
947 storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", XAVG(syscalls.disk.seeks));
bfae3379 948 storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", XAVG(syscalls.disk.unlinks));
886f2785 949 storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", XAVG(syscalls.sock.accepts));
950 storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", XAVG(syscalls.sock.sockets));
951 storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", XAVG(syscalls.sock.connects));
952 storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", XAVG(syscalls.sock.binds));
953 storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", XAVG(syscalls.sock.closes));
954 storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", XAVG(syscalls.sock.reads));
955 storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", XAVG(syscalls.sock.writes));
956 storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", XAVG(syscalls.sock.recvfroms));
957 storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", XAVG(syscalls.sock.sendtos));
958
a7c05555 959 storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct);
960 storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt);
0e473d70 961 storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt));
090089c4 962}
963
979533fa 964
b8d8561b 965void
a7c05555 966statInit(void)
090089c4 967{
090089c4 968 int i;
a7c05555 969 debug(18, 5) ("statInit: Initializing...\n");
62e76326 970
0e473d70 971 for (i = 0; i < N_COUNT_HIST; i++)
62e76326 972 statCountersInit(&CountHist[i]);
973
a0f32775 974 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
62e76326 975 statCountersInit(&CountHourHist[i]);
976
83704487 977 statCountersInit(&statCounter);
62e76326 978
52040193 979 eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
62e76326 980
22f3fd98 981 cachemgrRegister("info",
62e76326 982 "General Runtime Information",
983 info_get, 0, 1);
984
22f3fd98 985 cachemgrRegister("filedescriptors",
62e76326 986 "Process Filedescriptor Allocation",
987 fde::DumpStats, 0, 1);
988
22f3fd98 989 cachemgrRegister("objects",
62e76326 990 "All Cache Objects",
991 stat_objects_get, 0, 0);
992
22f3fd98 993 cachemgrRegister("vm_objects",
62e76326 994 "In-Memory and In-Transit Objects",
995 stat_vmobjects_get, 0, 0);
996
ae94d28e 997#if DEBUG_OPENFD
62e76326 998
ae94d28e 999 cachemgrRegister("openfd_objects",
62e76326 1000 "Objects with Swapout files open",
1001 statOpenfdObj, 0, 0);
1002
ae94d28e 1003#endif
62e76326 1004
22f3fd98 1005 cachemgrRegister("io",
62e76326 1006 "Server-side network read() size histograms",
1007 stat_io_get, 0, 1);
1008
22f3fd98 1009 cachemgrRegister("counters",
62e76326 1010 "Traffic and Resource Counters",
1011 statCountersDump, 0, 1);
1012
a1e927f6 1013 cachemgrRegister("peer_select",
62e76326 1014 "Peer Selection Algorithms",
1015 statPeerSelect, 0, 1);
1016
26b164ac 1017 cachemgrRegister("digest_stats",
62e76326 1018 "Cache Digest and ICP blob",
1019 statDigestBlob, 0, 1);
1020
22f3fd98 1021 cachemgrRegister("5min",
62e76326 1022 "5 Minute Average of Counters",
1023 statAvg5min, 0, 1);
1024
45eb7f49 1025 cachemgrRegister("60min",
62e76326 1026 "60 Minute Average of Counters",
1027 statAvg60min, 0, 1);
1028
e9b5ead4 1029 cachemgrRegister("utilization",
62e76326 1030 "Cache Utilization",
1031 statUtilization, 0, 1);
1032
01aebf31 1033#if STAT_GRAPHS
62e76326 1034
01aebf31 1035 cachemgrRegister("graph_variables",
62e76326 1036 "Display cache metrics graphically",
1037 statGraphDump, 0, 1);
1038
01aebf31 1039#endif
62e76326 1040
ba4f8e5a 1041 cachemgrRegister("histograms",
62e76326 1042 "Full Histogram Counts",
1043 statCountersHistograms, 0, 1);
1044
0f1bc304 1045 ClientActiveRequests.head = NULL;
62e76326 1046
0f1bc304 1047 ClientActiveRequests.tail = NULL;
62e76326 1048
0f1bc304 1049 cachemgrRegister("active_requests",
62e76326 1050 "Client-side Active Requests",
1051 statClientRequests, 0, 1);
090089c4 1052}
f2908497 1053
f2908497 1054static void
1055statAvgTick(void *notused)
1056{
d5649d9f 1057 StatCounters *t = &CountHist[0];
1058 StatCounters *p = &CountHist[1];
83704487 1059 StatCounters *c = &statCounter;
62e76326 1060
f2908497 1061 struct rusage rusage;
b6a2f15e 1062 eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
20903cac 1063 squid_getrusage(&rusage);
1064 c->page_faults = rusage_pagefaults(&rusage);
1065 c->cputime = rusage_cputime(&rusage);
d5649d9f 1066 c->timestamp = current_time;
12cf1be2 1067 /* even if NCountHist is small, we already Init()ed the tail */
2ac76861 1068 statCountersClean(CountHist + N_COUNT_HIST - 1);
dbfed404 1069 xmemmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
12cf1be2 1070 statCountersCopy(t, c);
d5649d9f 1071 NCountHist++;
a0f32775 1072
1073 if ((NCountHist % COUNT_INTERVAL) == 0) {
62e76326 1074 /* we have an hours worth of readings. store previous hour */
1075 StatCounters *t = &CountHourHist[0];
1076 StatCounters *p = &CountHourHist[1];
1077 StatCounters *c = &CountHist[N_COUNT_HIST - 1];
1078 statCountersClean(CountHourHist + N_COUNT_HOUR_HIST - 1);
1079 xmemmove(p, t, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
1080 statCountersCopy(t, c);
1081 NCountHourHist++;
a0f32775 1082 }
62e76326 1083
b8a46de0 1084 if (Config.warnings.high_rptm > 0) {
62e76326 1085 int i = (int) statMedianSvc(20, MEDIAN_HTTP);
1086
1087 if (Config.warnings.high_rptm < i)
1088 debug(18, 0) ("WARNING: Median response time is %d milliseconds\n", i);
b8a46de0 1089 }
62e76326 1090
b8a46de0 1091 if (Config.warnings.high_pf) {
62e76326 1092 int i = (CountHist[0].page_faults - CountHist[1].page_faults);
1093 double dt = tvSubDsec(CountHist[0].timestamp, CountHist[1].timestamp);
1094
1095 if (i > 0 && dt > 0.0) {
1096 i /= (int) dt;
1097
1098 if (Config.warnings.high_pf < i)
1099 debug(18, 0) ("WARNING: Page faults occuring at %d/sec\n", i);
1100 }
b8a46de0 1101 }
62e76326 1102
b8a46de0 1103 if (Config.warnings.high_memory) {
62e76326 1104 size_t i = 0;
b8a46de0 1105#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 1106
1107 struct mstats ms = mstats();
1108 i = ms.bytes_total;
b8a46de0 1109#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 1110
1111 struct mallinfo mp = mallinfo();
1112 i = mp.arena;
703cc8e8 1113#elif HAVE_SBRK
1114
1115 i = (size_t) ((char *) sbrk(0) - (char *) sbrk_start);
b8a46de0 1116#endif
62e76326 1117
1118 if (Config.warnings.high_memory < i)
1119 debug(18, 0) ("WARNING: Memory usage at %lu MB\n", (unsigned long int)(i >> 20));
b8a46de0 1120 }
20903cac 1121}
1122
12cf1be2 1123static void
2ac76861 1124statCountersInit(StatCounters * C)
20903cac 1125{
12cf1be2 1126 assert(C);
1d803566 1127 memset(C, 0, sizeof(*C));
12cf1be2 1128 C->timestamp = current_time;
1d803566 1129 statCountersInitSpecial(C);
1130}
1131
1132/* add special cases here as they arrive */
1133static void
2ac76861 1134statCountersInitSpecial(StatCounters * C)
1d803566 1135{
12cf1be2 1136 /*
1137 * HTTP svc_time hist is kept in milli-seconds; max of 3 hours.
1138 */
1139 statHistLogInit(&C->client_http.all_svc_time, 300, 0.0, 3600000.0 * 3.0);
1140 statHistLogInit(&C->client_http.miss_svc_time, 300, 0.0, 3600000.0 * 3.0);
1141 statHistLogInit(&C->client_http.nm_svc_time, 300, 0.0, 3600000.0 * 3.0);
7c9c84ad 1142 statHistLogInit(&C->client_http.nh_svc_time, 300, 0.0, 3600000.0 * 3.0);
12cf1be2 1143 statHistLogInit(&C->client_http.hit_svc_time, 300, 0.0, 3600000.0 * 3.0);
1144 /*
1145 * ICP svc_time hist is kept in micro-seconds; max of 1 minute.
1146 */
1147 statHistLogInit(&C->icp.query_svc_time, 300, 0.0, 1000000.0 * 60.0);
1148 statHistLogInit(&C->icp.reply_svc_time, 300, 0.0, 1000000.0 * 60.0);
1149 /*
1150 * DNS svc_time hist is kept in milli-seconds; max of 10 minutes.
1151 */
1152 statHistLogInit(&C->dns.svc_time, 300, 0.0, 60000.0 * 10.0);
a1e927f6 1153 /*
69c95dd3 1154 * Cache Digest Stuff
a1e927f6 1155 */
0c511722 1156 statHistEnumInit(&C->cd.on_xition_count, CacheDigestHashFuncCount);
c6ecdbc3 1157 statHistEnumInit(&C->comm_icp_incoming, INCOMING_ICP_MAX);
ef523f99 1158 statHistEnumInit(&C->comm_dns_incoming, INCOMING_DNS_MAX);
c6ecdbc3 1159 statHistEnumInit(&C->comm_http_incoming, INCOMING_HTTP_MAX);
b671cc68 1160 statHistIntInit(&C->select_fds_hist, 256); /* was SQUID_MAXFD, but it is way too much. It is OK to crop this statistics */
0f5607d9 1161}
1162
12cf1be2 1163/* add special cases here as they arrive */
5e29a294 1164static void
2ac76861 1165statCountersClean(StatCounters * C)
0f5607d9 1166{
12cf1be2 1167 assert(C);
1168 statHistClean(&C->client_http.all_svc_time);
1169 statHistClean(&C->client_http.miss_svc_time);
1170 statHistClean(&C->client_http.nm_svc_time);
7c9c84ad 1171 statHistClean(&C->client_http.nh_svc_time);
12cf1be2 1172 statHistClean(&C->client_http.hit_svc_time);
1173 statHistClean(&C->icp.query_svc_time);
1174 statHistClean(&C->icp.reply_svc_time);
1175 statHistClean(&C->dns.svc_time);
c135694e 1176 statHistClean(&C->cd.on_xition_count);
c6ecdbc3 1177 statHistClean(&C->comm_icp_incoming);
a56906d4 1178 statHistClean(&C->comm_dns_incoming);
c6ecdbc3 1179 statHistClean(&C->comm_http_incoming);
26d6ee93 1180 statHistClean(&C->select_fds_hist);
a7c05555 1181}
1182
12cf1be2 1183/* add special cases here as they arrive */
5e29a294 1184static void
2ac76861 1185statCountersCopy(StatCounters * dest, const StatCounters * orig)
45eb7f49 1186{
12cf1be2 1187 assert(dest && orig);
1d803566 1188 /* this should take care of all the fields, but "special" ones */
cac03dd2 1189 xmemcpy(dest, orig, sizeof(*dest));
1d803566 1190 /* prepare space where to copy special entries */
1191 statCountersInitSpecial(dest);
1192 /* now handle special cases */
1193 /* note: we assert that histogram capacities do not change */
12cf1be2 1194 statHistCopy(&dest->client_http.all_svc_time, &orig->client_http.all_svc_time);
1195 statHistCopy(&dest->client_http.miss_svc_time, &orig->client_http.miss_svc_time);
1196 statHistCopy(&dest->client_http.nm_svc_time, &orig->client_http.nm_svc_time);
7c9c84ad 1197 statHistCopy(&dest->client_http.nh_svc_time, &orig->client_http.nh_svc_time);
12cf1be2 1198 statHistCopy(&dest->client_http.hit_svc_time, &orig->client_http.hit_svc_time);
1199 statHistCopy(&dest->icp.query_svc_time, &orig->icp.query_svc_time);
1200 statHistCopy(&dest->icp.reply_svc_time, &orig->icp.reply_svc_time);
1201 statHistCopy(&dest->dns.svc_time, &orig->dns.svc_time);
c135694e 1202 statHistCopy(&dest->cd.on_xition_count, &orig->cd.on_xition_count);
c6ecdbc3 1203 statHistCopy(&dest->comm_icp_incoming, &orig->comm_icp_incoming);
1204 statHistCopy(&dest->comm_http_incoming, &orig->comm_http_incoming);
26d6ee93 1205 statHistCopy(&dest->select_fds_hist, &orig->select_fds_hist);
45eb7f49 1206}
1207
071a3ae7 1208static void
5d406e78 1209statCountersHistograms(StoreEntry * sentry)
071a3ae7 1210{
83704487 1211 StatCounters *f = &statCounter;
071a3ae7 1212 storeAppendPrintf(sentry, "client_http.all_svc_time histogram:\n");
1213 statHistDump(&f->client_http.all_svc_time, sentry, NULL);
1214 storeAppendPrintf(sentry, "client_http.miss_svc_time histogram:\n");
1215 statHistDump(&f->client_http.miss_svc_time, sentry, NULL);
1216 storeAppendPrintf(sentry, "client_http.nm_svc_time histogram:\n");
1217 statHistDump(&f->client_http.nm_svc_time, sentry, NULL);
7c9c84ad 1218 storeAppendPrintf(sentry, "client_http.nh_svc_time histogram:\n");
1219 statHistDump(&f->client_http.nh_svc_time, sentry, NULL);
071a3ae7 1220 storeAppendPrintf(sentry, "client_http.hit_svc_time histogram:\n");
1221 statHistDump(&f->client_http.hit_svc_time, sentry, NULL);
071a3ae7 1222 storeAppendPrintf(sentry, "icp.query_svc_time histogram:\n");
1223 statHistDump(&f->icp.query_svc_time, sentry, NULL);
1224 storeAppendPrintf(sentry, "icp.reply_svc_time histogram:\n");
1225 statHistDump(&f->icp.reply_svc_time, sentry, NULL);
1226 storeAppendPrintf(sentry, "dns.svc_time histogram:\n");
1227 statHistDump(&f->dns.svc_time, sentry, NULL);
2a73b7cb 1228 storeAppendPrintf(sentry, "select_fds_hist histogram:\n");
1229 statHistDump(&f->select_fds_hist, sentry, NULL);
071a3ae7 1230}
1231
12cf1be2 1232static void
1233statCountersDump(StoreEntry * sentry)
7ae52c25 1234{
83704487 1235 StatCounters *f = &statCounter;
62e76326 1236
12cf1be2 1237 struct rusage rusage;
1238 squid_getrusage(&rusage);
1239 f->page_faults = rusage_pagefaults(&rusage);
1240 f->cputime = rusage_cputime(&rusage);
1241
a0f32775 1242 storeAppendPrintf(sentry, "sample_time = %d.%d (%s)\n",
62e76326 1243 (int) f->timestamp.tv_sec,
1244 (int) f->timestamp.tv_usec,
1245 mkrfc1123(f->timestamp.tv_sec));
12cf1be2 1246 storeAppendPrintf(sentry, "client_http.requests = %d\n",
62e76326 1247 f->client_http.requests);
12cf1be2 1248 storeAppendPrintf(sentry, "client_http.hits = %d\n",
62e76326 1249 f->client_http.hits);
12cf1be2 1250 storeAppendPrintf(sentry, "client_http.errors = %d\n",
62e76326 1251 f->client_http.errors);
12cf1be2 1252 storeAppendPrintf(sentry, "client_http.kbytes_in = %d\n",
62e76326 1253 (int) f->client_http.kbytes_in.kb);
12cf1be2 1254 storeAppendPrintf(sentry, "client_http.kbytes_out = %d\n",
62e76326 1255 (int) f->client_http.kbytes_out.kb);
c68e9c6b 1256 storeAppendPrintf(sentry, "client_http.hit_kbytes_out = %d\n",
62e76326 1257 (int) f->client_http.hit_kbytes_out.kb);
0567f2a6 1258
a0f32775 1259 storeAppendPrintf(sentry, "server.all.requests = %d\n",
62e76326 1260 (int) f->server.all.requests);
a0f32775 1261 storeAppendPrintf(sentry, "server.all.errors = %d\n",
62e76326 1262 (int) f->server.all.errors);
a0f32775 1263 storeAppendPrintf(sentry, "server.all.kbytes_in = %d\n",
62e76326 1264 (int) f->server.all.kbytes_in.kb);
a0f32775 1265 storeAppendPrintf(sentry, "server.all.kbytes_out = %d\n",
62e76326 1266 (int) f->server.all.kbytes_out.kb);
a0f32775 1267
1268 storeAppendPrintf(sentry, "server.http.requests = %d\n",
62e76326 1269 (int) f->server.http.requests);
a0f32775 1270 storeAppendPrintf(sentry, "server.http.errors = %d\n",
62e76326 1271 (int) f->server.http.errors);
a0f32775 1272 storeAppendPrintf(sentry, "server.http.kbytes_in = %d\n",
62e76326 1273 (int) f->server.http.kbytes_in.kb);
a0f32775 1274 storeAppendPrintf(sentry, "server.http.kbytes_out = %d\n",
62e76326 1275 (int) f->server.http.kbytes_out.kb);
a0f32775 1276
1277 storeAppendPrintf(sentry, "server.ftp.requests = %d\n",
62e76326 1278 (int) f->server.ftp.requests);
a0f32775 1279 storeAppendPrintf(sentry, "server.ftp.errors = %d\n",
62e76326 1280 (int) f->server.ftp.errors);
a0f32775 1281 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %d\n",
62e76326 1282 (int) f->server.ftp.kbytes_in.kb);
a0f32775 1283 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %d\n",
62e76326 1284 (int) f->server.ftp.kbytes_out.kb);
a0f32775 1285
1286 storeAppendPrintf(sentry, "server.other.requests = %d\n",
62e76326 1287 (int) f->server.other.requests);
a0f32775 1288 storeAppendPrintf(sentry, "server.other.errors = %d\n",
62e76326 1289 (int) f->server.other.errors);
a0f32775 1290 storeAppendPrintf(sentry, "server.other.kbytes_in = %d\n",
62e76326 1291 (int) f->server.other.kbytes_in.kb);
a0f32775 1292 storeAppendPrintf(sentry, "server.other.kbytes_out = %d\n",
62e76326 1293 (int) f->server.other.kbytes_out.kb);
12cf1be2 1294
1295 storeAppendPrintf(sentry, "icp.pkts_sent = %d\n",
62e76326 1296 f->icp.pkts_sent);
12cf1be2 1297 storeAppendPrintf(sentry, "icp.pkts_recv = %d\n",
62e76326 1298 f->icp.pkts_recv);
071a3ae7 1299 storeAppendPrintf(sentry, "icp.queries_sent = %d\n",
62e76326 1300 f->icp.queries_sent);
071a3ae7 1301 storeAppendPrintf(sentry, "icp.replies_sent = %d\n",
62e76326 1302 f->icp.replies_sent);
071a3ae7 1303 storeAppendPrintf(sentry, "icp.queries_recv = %d\n",
62e76326 1304 f->icp.queries_recv);
071a3ae7 1305 storeAppendPrintf(sentry, "icp.replies_recv = %d\n",
62e76326 1306 f->icp.replies_recv);
071a3ae7 1307 storeAppendPrintf(sentry, "icp.query_timeouts = %d\n",
62e76326 1308 f->icp.query_timeouts);
2e8e29b8 1309 storeAppendPrintf(sentry, "icp.replies_queued = %d\n",
62e76326 1310 f->icp.replies_queued);
12cf1be2 1311 storeAppendPrintf(sentry, "icp.kbytes_sent = %d\n",
62e76326 1312 (int) f->icp.kbytes_sent.kb);
12cf1be2 1313 storeAppendPrintf(sentry, "icp.kbytes_recv = %d\n",
62e76326 1314 (int) f->icp.kbytes_recv.kb);
071a3ae7 1315 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %d\n",
62e76326 1316 (int) f->icp.q_kbytes_sent.kb);
071a3ae7 1317 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %d\n",
62e76326 1318 (int) f->icp.r_kbytes_sent.kb);
071a3ae7 1319 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %d\n",
62e76326 1320 (int) f->icp.q_kbytes_recv.kb);
071a3ae7 1321 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %d\n",
62e76326 1322 (int) f->icp.r_kbytes_recv.kb);
0567f2a6 1323
6cfa8966 1324#if USE_CACHE_DIGESTS
62e76326 1325
071a3ae7 1326 storeAppendPrintf(sentry, "icp.times_used = %d\n",
62e76326 1327 f->icp.times_used);
071a3ae7 1328 storeAppendPrintf(sentry, "cd.times_used = %d\n",
62e76326 1329 f->cd.times_used);
00485c29 1330 storeAppendPrintf(sentry, "cd.msgs_sent = %d\n",
62e76326 1331 f->cd.msgs_sent);
00485c29 1332 storeAppendPrintf(sentry, "cd.msgs_recv = %d\n",
62e76326 1333 f->cd.msgs_recv);
071a3ae7 1334 storeAppendPrintf(sentry, "cd.memory = %d\n",
62e76326 1335 (int) f->cd.memory.kb);
522b517b 1336 storeAppendPrintf(sentry, "cd.local_memory = %d\n",
62e76326 1337 (int) (store_digest ? store_digest->mask_size / 1024 : 0));
00485c29 1338 storeAppendPrintf(sentry, "cd.kbytes_sent = %d\n",
62e76326 1339 (int) f->cd.kbytes_sent.kb);
00485c29 1340 storeAppendPrintf(sentry, "cd.kbytes_recv = %d\n",
62e76326 1341 (int) f->cd.kbytes_recv.kb);
0567f2a6 1342#endif
1343
12cf1be2 1344 storeAppendPrintf(sentry, "unlink.requests = %d\n",
62e76326 1345 f->unlink.requests);
12cf1be2 1346 storeAppendPrintf(sentry, "page_faults = %d\n",
62e76326 1347 f->page_faults);
12cf1be2 1348 storeAppendPrintf(sentry, "select_loops = %d\n",
62e76326 1349 f->select_loops);
12cf1be2 1350 storeAppendPrintf(sentry, "cpu_time = %f\n",
62e76326 1351 f->cputime);
12cf1be2 1352 storeAppendPrintf(sentry, "wall_time = %f\n",
62e76326 1353 tvSubDsec(f->timestamp, current_time));
23dc8aca 1354 storeAppendPrintf(sentry, "swap.outs = %d\n",
62e76326 1355 f->swap.outs);
23dc8aca 1356 storeAppendPrintf(sentry, "swap.ins = %d\n",
62e76326 1357 f->swap.ins);
23dc8aca 1358 storeAppendPrintf(sentry, "swap.files_cleaned = %d\n",
62e76326 1359 f->swap.files_cleaned);
bfae3379 1360 storeAppendPrintf(sentry, "aborted_requests = %d\n",
62e76326 1361 f->aborted_requests);
7ae52c25 1362}
1363
d2db411c 1364void
1365statFreeMemory(void)
1366{
1367 int i;
62e76326 1368
d2db411c 1369 for (i = 0; i < N_COUNT_HIST; i++)
62e76326 1370 statCountersClean(&CountHist[i]);
1371
d2db411c 1372 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
62e76326 1373 statCountersClean(&CountHourHist[i]);
d2db411c 1374}
1375
5e29a294 1376static void
a1e927f6 1377statPeerSelect(StoreEntry * sentry)
1378{
6cfa8966 1379#if USE_CACHE_DIGESTS
83704487 1380 StatCounters *f = &statCounter;
a1e927f6 1381 peer *peer;
1382 const int tot_used = f->cd.times_used + f->icp.times_used;
1383
1384 /* totals */
1385 cacheDigestGuessStatsReport(&f->cd.guess, sentry, "all peers");
1386 /* per-peer */
1387 storeAppendPrintf(sentry, "\nPer-peer statistics:\n");
62e76326 1388
a1e927f6 1389 for (peer = getFirstPeer(); peer; peer = getNextPeer(peer)) {
62e76326 1390 if (peer->digest)
1391 peerDigestStatsReport(peer->digest, sentry);
1392 else
1393 storeAppendPrintf(sentry, "\nNo peer digest from %s\n", peer->host);
1394
1395 storeAppendPrintf(sentry, "\n");
a1e927f6 1396 }
1397
1398 storeAppendPrintf(sentry, "\nAlgorithm usage:\n");
1399 storeAppendPrintf(sentry, "Cache Digest: %7d (%3d%%)\n",
62e76326 1400 f->cd.times_used, xpercentInt(f->cd.times_used, tot_used));
a1e927f6 1401 storeAppendPrintf(sentry, "Icp: %7d (%3d%%)\n",
62e76326 1402 f->icp.times_used, xpercentInt(f->icp.times_used, tot_used));
a1e927f6 1403 storeAppendPrintf(sentry, "Total: %7d (%3d%%)\n",
62e76326 1404 tot_used, xpercentInt(tot_used, tot_used));
a1e927f6 1405#else
62e76326 1406
a1e927f6 1407 storeAppendPrintf(sentry, "peer digests are disabled; no stats is available.\n");
1408#endif
1409}
1410
1411static void
26b164ac 1412statDigestBlob(StoreEntry * sentry)
1413{
071a3ae7 1414 storeAppendPrintf(sentry, "\nCounters:\n");
1415 statCountersDump(sentry);
86e2a291 1416 storeAppendPrintf(sentry, "\n5 Min Averages:\n");
1417 statAvgDump(sentry, 5, 0);
071a3ae7 1418 storeAppendPrintf(sentry, "\nHistograms:\n");
1419 statCountersHistograms(sentry);
1420 storeAppendPrintf(sentry, "\nPeer Digests:\n");
26b164ac 1421 statPeerSelect(sentry);
588d9545 1422 storeAppendPrintf(sentry, "\nLocal Digest:\n");
26b164ac 1423 storeDigestReport(sentry);
1424}
1425
5e29a294 1426static void
12cf1be2 1427statAvg5min(StoreEntry * e)
7ae52c25 1428{
a0f32775 1429 statAvgDump(e, 5, 0);
7ae52c25 1430}
1431
5e29a294 1432static void
12cf1be2 1433statAvg60min(StoreEntry * e)
7ae52c25 1434{
a0f32775 1435 statAvgDump(e, 60, 0);
7ae52c25 1436}
1437
7d94ae33 1438static double
b87b92fb 1439statMedianSvc(int interval, int which)
a9113eb0 1440{
1441 StatCounters *f;
1442 StatCounters *l;
1443 double x;
f8d264b8 1444 assert(interval > 0);
62e76326 1445
f8d264b8 1446 if (interval > N_COUNT_HIST - 1)
62e76326 1447 interval = N_COUNT_HIST - 1;
1448
a9113eb0 1449 f = &CountHist[0];
62e76326 1450
a9113eb0 1451 l = &CountHist[interval];
62e76326 1452
ee1679df 1453 assert(f);
62e76326 1454
ee1679df 1455 assert(l);
62e76326 1456
a9113eb0 1457 switch (which) {
62e76326 1458
b87b92fb 1459 case MEDIAN_HTTP:
62e76326 1460 x = statHistDeltaMedian(&l->client_http.all_svc_time, &f->client_http.all_svc_time);
1461 break;
1462
b87b92fb 1463 case MEDIAN_HIT:
62e76326 1464 x = statHistDeltaMedian(&l->client_http.hit_svc_time, &f->client_http.hit_svc_time);
1465 break;
1466
b87b92fb 1467 case MEDIAN_MISS:
62e76326 1468 x = statHistDeltaMedian(&l->client_http.miss_svc_time, &f->client_http.miss_svc_time);
1469 break;
1470
b87b92fb 1471 case MEDIAN_NM:
62e76326 1472 x = statHistDeltaMedian(&l->client_http.nm_svc_time, &f->client_http.nm_svc_time);
1473 break;
1474
7c9c84ad 1475 case MEDIAN_NH:
62e76326 1476 x = statHistDeltaMedian(&l->client_http.nh_svc_time, &f->client_http.nh_svc_time);
1477 break;
1478
b87b92fb 1479 case MEDIAN_ICP_QUERY:
62e76326 1480 x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
1481 break;
1482
b87b92fb 1483 case MEDIAN_DNS:
62e76326 1484 x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
1485 break;
1486
a9113eb0 1487 default:
62e76326 1488 debug(49, 5) ("get_median_val: unknown type.\n");
1489 x = 0;
a9113eb0 1490 }
62e76326 1491
b87b92fb 1492 return x;
1493}
1494
1495/*
1496 * SNMP wants ints, ick
1497 */
2d72d4fd 1498#if UNUSED_CODE
b87b92fb 1499int
1500get_median_svc(int interval, int which)
1501{
b644367b 1502 return (int) statMedianSvc(interval, which);
a9113eb0 1503}
451b07c5 1504
2d72d4fd 1505#endif
1506
451b07c5 1507StatCounters *
1508snmpStatGet(int minutes)
1509{
2ac76861 1510 return &CountHist[minutes];
451b07c5 1511}
01aebf31 1512
1f3c4622 1513int
1514stat5minClientRequests(void)
1515{
5999b776 1516 assert(N_COUNT_HIST > 5);
83704487 1517 return statCounter.client_http.requests - CountHist[5].client_http.requests;
1f3c4622 1518}
1519
49ad0a8c 1520static double
1521statCPUUsage(int minutes)
979533fa 1522{
49ad0a8c 1523 assert(minutes < N_COUNT_HIST);
1524 return dpercent(CountHist[0].cputime - CountHist[minutes].cputime,
62e76326 1525 tvSubDsec(CountHist[minutes].timestamp, CountHist[0].timestamp));
979533fa 1526}
01aebf31 1527
1d5b6d43 1528extern double
62e76326 1529 statRequestHitRatio(int minutes)
491a980b 1530{
1531 assert(minutes < N_COUNT_HIST);
1532 return dpercent(CountHist[0].client_http.hits -
62e76326 1533 CountHist[minutes].client_http.hits,
1534 CountHist[0].client_http.requests -
1535 CountHist[minutes].client_http.requests);
491a980b 1536}
1537
4f4d1d6e 1538extern double
62e76326 1539 statRequestHitMemoryRatio(int minutes)
4f4d1d6e 1540{
1541 assert(minutes < N_COUNT_HIST);
1542 return dpercent(CountHist[0].client_http.mem_hits -
62e76326 1543 CountHist[minutes].client_http.mem_hits,
1544 CountHist[0].client_http.hits -
1545 CountHist[minutes].client_http.hits);
4f4d1d6e 1546}
1547
1548extern double
62e76326 1549 statRequestHitDiskRatio(int minutes)
4f4d1d6e 1550{
1551 assert(minutes < N_COUNT_HIST);
1552 return dpercent(CountHist[0].client_http.disk_hits -
62e76326 1553 CountHist[minutes].client_http.disk_hits,
1554 CountHist[0].client_http.hits -
1555 CountHist[minutes].client_http.hits);
4f4d1d6e 1556}
1557
1d5b6d43 1558extern double
62e76326 1559 statByteHitRatio(int minutes)
491a980b 1560{
1561 size_t s;
1562 size_t c;
ac342231 1563#if USE_CACHE_DIGESTS
62e76326 1564
ac342231 1565 size_t cd;
1566#endif
1567 /* size_t might be unsigned */
491a980b 1568 assert(minutes < N_COUNT_HIST);
1569 c = CountHist[0].client_http.kbytes_out.kb - CountHist[minutes].client_http.kbytes_out.kb;
1570 s = CountHist[0].server.all.kbytes_in.kb - CountHist[minutes].server.all.kbytes_in.kb;
ac342231 1571#if USE_CACHE_DIGESTS
1572 /*
1573 * This ugly hack is here to prevent the user from seeing a
1574 * negative byte hit ratio. When we fetch a cache digest from
1575 * a neighbor, it gets treated like a cache miss because the
1576 * object is consumed internally. Thus, we subtract cache
1577 * digest bytes out before calculating the byte hit ratio.
1578 */
1579 cd = CountHist[0].cd.kbytes_recv.kb - CountHist[minutes].cd.kbytes_recv.kb;
62e76326 1580
49d7ce5f 1581 if (s < cd)
e4049756 1582 debugs(18, 1, "STRANGE: srv_kbytes=" << s << ", cd_kbytes=" << cd);
62e76326 1583
ac342231 1584 s -= cd;
62e76326 1585
ac342231 1586#endif
62e76326 1587
94e56ef7 1588 if (c > s)
62e76326 1589 return dpercent(c - s, c);
94e56ef7 1590 else
62e76326 1591 return (-1.0 * dpercent(s - c, c));
491a980b 1592}
1593
0f1bc304 1594static void
1595statClientRequests(StoreEntry * s)
1596{
1597 dlink_node *i;
59a1efb2 1598 ClientHttpRequest *http;
0f1bc304 1599 StoreEntry *e;
1600 int fd;
62e76326 1601
0f1bc304 1602 for (i = ClientActiveRequests.head; i; i = i->next) {
59a1efb2 1603 http = static_cast<ClientHttpRequest *>(i->data);
62e76326 1604 assert(http);
a2ac85d9 1605 ConnStateData::Pointer conn = http->getConn();
1606 storeAppendPrintf(s, "Connection: %p\n", conn.getRaw());
62e76326 1607
a2ac85d9 1608 if (conn.getRaw() != NULL) {
62e76326 1609 fd = conn->fd;
1610 storeAppendPrintf(s, "\tFD %d, read %d, wrote %d\n", fd,
1611 fd_table[fd].bytes_read, fd_table[fd].bytes_written);
1612 storeAppendPrintf(s, "\tFD desc: %s\n", fd_table[fd].desc);
1613 storeAppendPrintf(s, "\tin: buf %p, offset %ld, size %ld\n",
1614 conn->in.buf, (long int) conn->in.notYetUsed, (long int) conn->in.allocatedSize);
1615 storeAppendPrintf(s, "\tpeer: %s:%d\n",
1616 inet_ntoa(conn->peer.sin_addr),
1617 ntohs(conn->peer.sin_port));
1618 storeAppendPrintf(s, "\tme: %s:%d\n",
1619 inet_ntoa(conn->me.sin_addr),
1620 ntohs(conn->me.sin_port));
1621 storeAppendPrintf(s, "\tnrequests: %d\n",
1622 conn->nrequests);
62e76326 1623 }
1624
1625 storeAppendPrintf(s, "uri %s\n", http->uri);
1626 storeAppendPrintf(s, "logType %s\n", log_tags[http->logType]);
1627 storeAppendPrintf(s, "out.offset %ld, out.size %lu\n",
1628 (long int) http->out.offset, (unsigned long int) http->out.size);
1629 storeAppendPrintf(s, "req_sz %ld\n", (long int) http->req_sz);
86a2f789 1630 e = http->storeEntry();
62e76326 1631 storeAppendPrintf(s, "entry %p/%s\n", e, e ? e->getMD5Text() : "N/A");
0655fa4d 1632#if 0
1633 /* Not a member anymore */
62e76326 1634 e = http->old_entry;
1635 storeAppendPrintf(s, "old_entry %p/%s\n", e, e ? e->getMD5Text() : "N/A");
0655fa4d 1636#endif
1637
62e76326 1638 storeAppendPrintf(s, "start %ld.%06d (%f seconds ago)\n",
1639 (long int) http->start.tv_sec,
1640 (int) http->start.tv_usec,
1641 tvSubDsec(http->start, current_time));
8faa78e6 1642
d3f603c8 1643 if (http->request->auth_user_request) {
1644 const char *p;
1645
1646 p = http->request->auth_user_request->username();
1647
1648 if (!p)
1649 p = "-";
1650
1651 storeAppendPrintf(s, "username %s\n", p);
1652 }
1653
1654#if DELAY_POOLS
8faa78e6 1655 storeAppendPrintf(s, "delay_pool %d\n", DelayId::DelayClient(http) >> 16);
d3f603c8 1656
8faa78e6 1657#endif
1658
62e76326 1659 storeAppendPrintf(s, "\n");
0f1bc304 1660 }
1661}
1662
01aebf31 1663#if STAT_GRAPHS
1664/*
1665 * urgh, i don't like these, but they do cut the amount of code down immensely
1666 */
1667
1668#define GRAPH_PER_MIN(Y) \
1669 for (i=0;i<(N_COUNT_HIST-2);i++) { \
79d15b05 1670 dt = tvSubDsec(CountHist[i+1].timestamp, CountHist[i].timestamp); \
01aebf31 1671 if (dt <= 0.0) \
1672 break; \
1673 storeAppendPrintf(e, "%lu,%0.2f:", \
1674 CountHist[i].timestamp.tv_sec, \
1675 ((CountHist[i].Y - CountHist[i+1].Y) / dt)); \
1676 }
1677
1678#define GRAPH_PER_HOUR(Y) \
1679 for (i=0;i<(N_COUNT_HOUR_HIST-2);i++) { \
79d15b05 1680 dt = tvSubDsec(CountHourHist[i+1].timestamp, CountHourHist[i].timestamp); \
01aebf31 1681 if (dt <= 0.0) \
1682 break; \
1683 storeAppendPrintf(e, "%lu,%0.2f:", \
1684 CountHourHist[i].timestamp.tv_sec, \
1685 ((CountHourHist[i].Y - CountHourHist[i+1].Y) / dt)); \
1686 }
1687
1688#define GRAPH_TITLE(X,Y) storeAppendPrintf(e,"%s\t%s\t",X,Y);
1689#define GRAPH_END storeAppendPrintf(e,"\n");
1690
1691#define GENGRAPH(X,Y,Z) \
1692 GRAPH_TITLE(Y,Z) \
1693 GRAPH_PER_MIN(X) \
1694 GRAPH_PER_HOUR(X) \
1695 GRAPH_END
1696
1697static void
1698statGraphDump(StoreEntry * e)
1699{
1700 int i;
1701 double dt;
1702
1703 GENGRAPH(client_http.requests, "client_http.requests", "Client HTTP requests/sec");
1704 GENGRAPH(client_http.hits, "client_http.hits", "Client HTTP hits/sec");
1705 GENGRAPH(client_http.errors, "client_http.errors", "Client HTTP errors/sec");
1706 GENGRAPH(client_http.kbytes_in.kb, "client_http.kbytes_in", "Client HTTP kbytes_in/sec");
1707 GENGRAPH(client_http.kbytes_out.kb, "client_http.kbytes_out", "Client HTTP kbytes_out/sec");
1708
1709 /* XXX todo: http median service times */
1710
1711 GENGRAPH(server.all.requests, "server.all.requests", "Server requests/sec");
1712 GENGRAPH(server.all.errors, "server.all.errors", "Server errors/sec");
1713 GENGRAPH(server.all.kbytes_in.kb, "server.all.kbytes_in", "Server total kbytes_in/sec");
1714 GENGRAPH(server.all.kbytes_out.kb, "server.all.kbytes_out", "Server total kbytes_out/sec");
1715
1716 GENGRAPH(server.http.requests, "server.http.requests", "Server HTTP requests/sec");
1717 GENGRAPH(server.http.errors, "server.http.errors", "Server HTTP errors/sec");
1718 GENGRAPH(server.http.kbytes_in.kb, "server.http.kbytes_in", "Server HTTP kbytes_in/sec");
1719 GENGRAPH(server.http.kbytes_out.kb, "server.http.kbytes_out", "Server HTTP kbytes_out/sec");
1720
1721 GENGRAPH(server.ftp.requests, "server.ftp.requests", "Server FTP requests/sec");
1722 GENGRAPH(server.ftp.errors, "server.ftp.errors", "Server FTP errors/sec");
1723 GENGRAPH(server.ftp.kbytes_in.kb, "server.ftp.kbytes_in", "Server FTP kbytes_in/sec");
1724 GENGRAPH(server.ftp.kbytes_out.kb, "server.ftp.kbytes_out", "Server FTP kbytes_out/sec");
1725
1726 GENGRAPH(server.other.requests, "server.other.requests", "Server other requests/sec");
1727 GENGRAPH(server.other.errors, "server.other.errors", "Server other errors/sec");
1728 GENGRAPH(server.other.kbytes_in.kb, "server.other.kbytes_in", "Server other kbytes_in/sec");
1729 GENGRAPH(server.other.kbytes_out.kb, "server.other.kbytes_out", "Server other kbytes_out/sec");
1730
1731 GENGRAPH(icp.pkts_sent, "icp.pkts_sent", "ICP packets sent/sec");
1732 GENGRAPH(icp.pkts_recv, "icp.pkts_recv", "ICP packets received/sec");
1733 GENGRAPH(icp.kbytes_sent.kb, "icp.kbytes_sent", "ICP kbytes_sent/sec");
1734 GENGRAPH(icp.kbytes_recv.kb, "icp.kbytes_recv", "ICP kbytes_received/sec");
1735
1736 /* XXX todo: icp median service times */
1737 /* XXX todo: dns median service times */
1738
1739 GENGRAPH(unlink.requests, "unlink.requests", "Cache File unlink requests/sec");
1740 GENGRAPH(page_faults, "page_faults", "System Page Faults/sec");
1741 GENGRAPH(select_loops, "select_loops", "System Select Loop calls/sec");
1742 GENGRAPH(cputime, "cputime", "CPU utilisation");
1743}
1afe05c5 1744
d96ceb8e 1745#endif /* STAT_GRAPHS */
1746
2d72d4fd 1747int
1748statMemoryAccounted(void)
1749{
d96ceb8e 1750 return memPoolsTotalAllocated();
2d72d4fd 1751}