]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stat.cc
Import SN.png correctly as binary.
[thirdparty/squid.git] / src / stat.cc
CommitLineData
30a4f2a8 1/*
262a0e14 2 * $Id$
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.
26ac0430 23 *
30a4f2a8 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.
26ac0430 28 *
30a4f2a8 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"
a553a5a3 36#include "event.h"
c8be6d7b 37#include "StoreClient.h"
2f1431ea 38#if USE_AUTH
2d2b0bb7 39#include "auth/UserRequest.h"
2f1431ea 40#endif
8822ebee 41#include "mgr/Registration.h"
e6ccf245 42#include "Store.h"
d3f603c8 43#include "HttpRequest.h"
8432e271 44#include "log/Tokens.h"
528b2c61 45#include "MemObject.h"
46#include "fde.h"
47#include "mem_node.h"
9a0a18de 48#if USE_DELAY_POOLS
8faa78e6 49#include "DelayId.h"
50#endif
528b2c61 51#include "client_side_request.h"
a46d2c0e 52#include "client_side.h"
0eb49b6d 53#include "MemBuf.h"
a98bcbee 54#include "SquidMath.h"
cc192b50 55#include "SquidTime.h"
8822ebee
AR
56#include "mgr/CountersAction.h"
57#include "mgr/FunAction.h"
58#include "mgr/InfoAction.h"
59#include "mgr/IntervalAction.h"
60#include "mgr/IoAction.h"
61#include "mgr/ServiceTimesAction.h"
4db984be
CT
62#if USE_SSL
63#include "ssl/support.h"
64#endif
528b2c61 65
66/* these are included because they expose stats calls */
67/* TODO: provide a self registration mechanism for those classes
68 * to use during static construction
69 */
70#include "comm.h"
c8f4eac4 71#include "StoreSearch.h"
090089c4 72
ae94d28e 73#define DEBUG_OPENFD 1
74
1da3b90b 75typedef int STOBJFLT(const StoreEntry *);
62e76326 76
c8f4eac4 77class StatObjectsState
62e76326 78{
c8f4eac4 79
80public:
1da3b90b 81 StoreEntry *sentry;
1da3b90b 82 STOBJFLT *filter;
c8f4eac4 83 StoreSearchPointer theSearch;
84
85private:
86 CBDATA_CLASS2(StatObjectsState);
87};
62e76326 88
1da3b90b 89
67508012 90/* LOCALS */
f5b8bbc4 91static const char *describeStatuses(const StoreEntry *);
f5b8bbc4 92static const char *describeTimestamps(const StoreEntry *);
f2908497 93static void statAvgTick(void *notused);
a0f32775 94static void statAvgDump(StoreEntry *, int minutes, int hours);
01aebf31 95#if STAT_GRAPHS
96static void statGraphDump(StoreEntry *);
97#endif
12cf1be2 98static void statCountersInit(StatCounters *);
1d803566 99static void statCountersInitSpecial(StatCounters *);
12cf1be2 100static void statCountersClean(StatCounters *);
2ac76861 101static void statCountersCopy(StatCounters * dest, const StatCounters * orig);
04a28d46 102static double statPctileSvc(double, int, int);
fcc35180 103static void statStoreEntry(MemBuf * mb, StoreEntry * e);
49ad0a8c 104static double statCPUUsage(int minutes);
ed7f5615 105static OBJH stat_objects_get;
106static OBJH stat_vmobjects_get;
ae94d28e 107#if DEBUG_OPENFD
108static OBJH statOpenfdObj;
109#endif
1da3b90b 110static EVH statObjects;
071a3ae7 111static OBJH statCountersDump;
a1e927f6 112static OBJH statPeerSelect;
26b164ac 113static OBJH statDigestBlob;
e9b5ead4 114static OBJH statUtilization;
ba4f8e5a 115static OBJH statCountersHistograms;
0f1bc304 116static OBJH statClientRequests;
8822ebee
AR
117void GetAvgStat(Mgr::IntervalActionData& stats, int minutes, int hours);
118void DumpAvgStat(Mgr::IntervalActionData& stats, StoreEntry* sentry);
119void GetInfo(Mgr::InfoActionData& stats);
120void DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry);
121void DumpMallocStatistics(StoreEntry* sentry);
122void GetCountersStats(Mgr::CountersActionData& stats);
123void DumpCountersStats(Mgr::CountersActionData& stats, StoreEntry* sentry);
124void GetServiceTimesStats(Mgr::ServiceTimesActionData& stats);
125void DumpServiceTimesStats(Mgr::ServiceTimesActionData& stats, StoreEntry* sentry);
126void GetIoStats(Mgr::IoActionData& stats);
127void DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry);
20882fb1 128
32d002cb 129#if XMALLOC_STATISTICS
58cd5bbd 130static void info_get_mallstat(int, int, int, void *);
131static double xm_time;
132static double xm_deltat;
20882fb1 133#endif
30a4f2a8 134
a9113eb0 135StatCounters CountHist[N_COUNT_HIST];
d5649d9f 136static int NCountHist = 0;
a0f32775 137static StatCounters CountHourHist[N_COUNT_HOUR_HIST];
138static int NCountHourHist = 0;
c8f4eac4 139CBDATA_CLASS_INIT(StatObjectsState);
a0f32775 140
d480bbc0 141extern unsigned int mem_pool_alloc_calls;
142extern unsigned int mem_pool_free_calls;
143
5e29a294 144static void
e9b5ead4 145statUtilization(StoreEntry * e)
a0f32775 146{
147 storeAppendPrintf(e, "Cache Utilisation:\n");
148 storeAppendPrintf(e, "\n");
149 storeAppendPrintf(e, "Last 5 minutes:\n");
62e76326 150
a0f32775 151 if (NCountHist >= 5)
62e76326 152 statAvgDump(e, 5, 0);
a0f32775 153 else
62e76326 154 storeAppendPrintf(e, "(no values recorded yet)\n");
155
a0f32775 156 storeAppendPrintf(e, "\n");
62e76326 157
a0f32775 158 storeAppendPrintf(e, "Last 15 minutes:\n");
62e76326 159
a0f32775 160 if (NCountHist >= 15)
62e76326 161 statAvgDump(e, 15, 0);
a0f32775 162 else
62e76326 163 storeAppendPrintf(e, "(no values recorded yet)\n");
164
a0f32775 165 storeAppendPrintf(e, "\n");
62e76326 166
a0f32775 167 storeAppendPrintf(e, "Last hour:\n");
62e76326 168
a0f32775 169 if (NCountHist >= 60)
62e76326 170 statAvgDump(e, 60, 0);
a0f32775 171 else
62e76326 172 storeAppendPrintf(e, "(no values recorded yet)\n");
173
a0f32775 174 storeAppendPrintf(e, "\n");
62e76326 175
a0f32775 176 storeAppendPrintf(e, "Last 8 hours:\n");
62e76326 177
a0f32775 178 if (NCountHourHist >= 8)
62e76326 179 statAvgDump(e, 0, 8);
a0f32775 180 else
62e76326 181 storeAppendPrintf(e, "(no values recorded yet)\n");
182
a0f32775 183 storeAppendPrintf(e, "\n");
62e76326 184
a0f32775 185 storeAppendPrintf(e, "Last day:\n");
62e76326 186
a0f32775 187 if (NCountHourHist >= 24)
62e76326 188 statAvgDump(e, 0, 24);
a0f32775 189 else
62e76326 190 storeAppendPrintf(e, "(no values recorded yet)\n");
191
a0f32775 192 storeAppendPrintf(e, "\n");
62e76326 193
a0f32775 194 storeAppendPrintf(e, "Last 3 days:\n");
62e76326 195
a0f32775 196 if (NCountHourHist >= 72)
62e76326 197 statAvgDump(e, 0, 72);
a0f32775 198 else
62e76326 199 storeAppendPrintf(e, "(no values recorded yet)\n");
200
a0f32775 201 storeAppendPrintf(e, "\n");
62e76326 202
a0f32775 203 storeAppendPrintf(e, "Totals since cache startup:\n");
62e76326 204
a0f32775 205 statCountersDump(e);
206}
f2908497 207
8822ebee
AR
208void
209GetIoStats(Mgr::IoActionData& stats)
210{
211 int i;
212
213 stats.http_reads = IOStats.Http.reads;
214
215 for (i = 0; i < _iostats::histSize; i++) {
216 stats.http_read_hist[i] = IOStats.Http.read_hist[i];
217 }
218
219 stats.ftp_reads = IOStats.Ftp.reads;
220
221 for (i = 0; i < _iostats::histSize; i++) {
222 stats.ftp_read_hist[i] = IOStats.Ftp.read_hist[i];
223 }
224
225 stats.gopher_reads = IOStats.Gopher.reads;
226
227 for (i = 0; i < _iostats::histSize; i++) {
228 stats.gopher_read_hist[i] = IOStats.Gopher.read_hist[i];
229 }
230}
231
232void
233DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry)
30a4f2a8 234{
235 int i;
236
15576b6a 237 storeAppendPrintf(sentry, "HTTP I/O\n");
8822ebee 238 storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.http_reads);
15576b6a 239 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 240
8822ebee
AR
241 for (i = 0; i < _iostats::histSize; i++) {
242 storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
d9fc6862
A
243 i ? (1 << (i - 1)) + 1 : 1,
244 1 << i,
245 stats.http_read_hist[i],
246 Math::doublePercent(stats.http_read_hist[i], stats.http_reads));
30a4f2a8 247 }
248
15576b6a 249 storeAppendPrintf(sentry, "\n");
250 storeAppendPrintf(sentry, "FTP I/O\n");
8822ebee 251 storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.ftp_reads);
15576b6a 252 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 253
8822ebee
AR
254 for (i = 0; i < _iostats::histSize; i++) {
255 storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
d9fc6862
A
256 i ? (1 << (i - 1)) + 1 : 1,
257 1 << i,
258 stats.ftp_read_hist[i],
259 Math::doublePercent(stats.ftp_read_hist[i], stats.ftp_reads));
30a4f2a8 260 }
261
15576b6a 262 storeAppendPrintf(sentry, "\n");
263 storeAppendPrintf(sentry, "Gopher I/O\n");
8822ebee 264 storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.gopher_reads);
15576b6a 265 storeAppendPrintf(sentry, "Read Histogram:\n");
62e76326 266
8822ebee
AR
267 for (i = 0; i < _iostats::histSize; i++) {
268 storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
d9fc6862
A
269 i ? (1 << (i - 1)) + 1 : 1,
270 1 << i,
271 stats.gopher_read_hist[i],
272 Math::doublePercent(stats.gopher_read_hist[i], stats.gopher_reads));
56fa4cad 273 }
274
15576b6a 275 storeAppendPrintf(sentry, "\n");
090089c4 276}
277
0ee4272b 278static const char *
fe4e214f 279describeStatuses(const StoreEntry * entry)
d1a43e28 280{
281 LOCAL_ARRAY(char, buf, 256);
56878878 282 snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
62e76326 283 storeStatusStr[entry->store_status],
284 memStatusStr[entry->mem_status],
285 swapStatusStr[entry->swap_status],
286 pingStatusStr[entry->ping_status]);
d1a43e28 287 return buf;
288}
289
415e0dd2 290const char *
291storeEntryFlags(const StoreEntry * entry)
d1a43e28 292{
293 LOCAL_ARRAY(char, buf, 256);
315005bd 294 int flags = (int) entry->flags;
d1a43e28 295 char *t;
296 buf[0] = '\0';
62e76326 297
7d94ae33 298 if (EBIT_TEST(flags, ENTRY_SPECIAL))
62e76326 299 strcat(buf, "SPECIAL,");
300
7d94ae33 301 if (EBIT_TEST(flags, ENTRY_REVALIDATE))
62e76326 302 strcat(buf, "REVALIDATE,");
303
7d94ae33 304 if (EBIT_TEST(flags, DELAY_SENDING))
62e76326 305 strcat(buf, "DELAY_SENDING,");
306
7d94ae33 307 if (EBIT_TEST(flags, RELEASE_REQUEST))
62e76326 308 strcat(buf, "RELEASE_REQUEST,");
309
7d94ae33 310 if (EBIT_TEST(flags, REFRESH_REQUEST))
62e76326 311 strcat(buf, "REFRESH_REQUEST,");
312
7d94ae33 313 if (EBIT_TEST(flags, ENTRY_CACHABLE))
62e76326 314 strcat(buf, "CACHABLE,");
315
7d94ae33 316 if (EBIT_TEST(flags, ENTRY_DISPATCHED))
62e76326 317 strcat(buf, "DISPATCHED,");
318
7d94ae33 319 if (EBIT_TEST(flags, KEY_PRIVATE))
62e76326 320 strcat(buf, "PRIVATE,");
321
05b0ef8a 322 if (EBIT_TEST(flags, ENTRY_FWD_HDR_WAIT))
62e76326 323 strcat(buf, "FWD_HDR_WAIT,");
324
7d94ae33 325 if (EBIT_TEST(flags, ENTRY_NEGCACHED))
62e76326 326 strcat(buf, "NEGCACHED,");
327
7d94ae33 328 if (EBIT_TEST(flags, ENTRY_VALIDATED))
62e76326 329 strcat(buf, "VALIDATED,");
330
7d94ae33 331 if (EBIT_TEST(flags, ENTRY_BAD_LENGTH))
62e76326 332 strcat(buf, "BAD_LENGTH,");
333
d2e002d1 334 if (EBIT_TEST(flags, ENTRY_ABORTED))
62e76326 335 strcat(buf, "ABORTED,");
336
d1a43e28 337 if ((t = strrchr(buf, ',')))
62e76326 338 *t = '\0';
339
d1a43e28 340 return buf;
341}
342
0ee4272b 343static const char *
fe4e214f 344describeTimestamps(const StoreEntry * entry)
d1a43e28 345{
346 LOCAL_ARRAY(char, buf, 256);
56878878 347 snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
62e76326 348 (int) entry->timestamp,
349 (int) entry->lastref,
350 (int) entry->lastmod,
351 (int) entry->expires);
d1a43e28 352 return buf;
353}
354
b8d8561b 355static void
fcc35180 356statStoreEntry(MemBuf * mb, StoreEntry * e)
090089c4 357{
a5a5de87 358 MemObject *mem = e->mem_obj;
2fe7eff9 359 mb->Printf("KEY %s\n", e->getMD5Text());
360 mb->Printf("\t%s\n", describeStatuses(e));
361 mb->Printf("\t%s\n", storeEntryFlags(e));
362 mb->Printf("\t%s\n", describeTimestamps(e));
363 mb->Printf("\t%d locks, %d clients, %d refs\n",
364 (int) e->lock_count,
365 storePendingNClients(e),
366 (int) e->refcount);
367 mb->Printf("\tSwap Dir %d, File %#08X\n",
368 e->swap_dirn, e->swap_filen);
62e76326 369
528b2c61 370 if (mem != NULL)
fcc35180 371 mem->stat (mb);
62e76326 372
2fe7eff9 373 mb->Printf("\n");
a5a5de87 374}
375
376/* process objects list */
377static void
1da3b90b 378statObjects(void *data)
a5a5de87 379{
e6ccf245 380 StatObjectsState *state = static_cast<StatObjectsState *>(data);
1da3b90b 381 StoreEntry *e;
62e76326 382
c8f4eac4 383 if (state->theSearch->isDone()) {
8822ebee
AR
384 if (UsingSmp())
385 storeAppendPrintf(state->sentry, "} by kid%d\n\n", KidIdentifier);
62e76326 386 state->sentry->complete();
97b5e68f 387 state->sentry->unlock();
62e76326 388 cbdataFree(state);
389 return;
b7fe0ab0 390 } else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) {
97b5e68f 391 state->sentry->unlock();
62e76326 392 cbdataFree(state);
393 return;
a46d2c0e 394 } else if (state->sentry->checkDeferRead(-1)) {
62e76326 395 eventAdd("statObjects", statObjects, state, 0.1, 1);
396 return;
1da3b90b 397 }
62e76326 398
3900307b 399 state->sentry->buffer();
c8f4eac4 400 size_t statCount = 0;
401 MemBuf mb;
2fe7eff9 402 mb.init();
62e76326 403
c8f4eac4 404 while (statCount++ < static_cast<size_t>(Config.Store.objectsPerBucket) && state->
405 theSearch->next()) {
406 e = state->theSearch->currentItem();
62e76326 407
c8f4eac4 408 if (state->filter && 0 == state->filter(e))
409 continue;
62e76326 410
c8f4eac4 411 statStoreEntry(&mb, e);
412 }
fcc35180 413
c8f4eac4 414 if (mb.size)
3900307b 415 state->sentry->append(mb.buf, mb.size);
2fe7eff9 416 mb.clean();
62e76326 417
1da3b90b 418 eventAdd("statObjects", statObjects, state, 0.0, 1);
a5a5de87 419}
420
5e29a294 421static void
1da3b90b 422statObjectsStart(StoreEntry * sentry, STOBJFLT * filter)
423{
c8f4eac4 424 StatObjectsState *state = new StatObjectsState;
1da3b90b 425 state->sentry = sentry;
426 state->filter = filter;
34266cde 427
3d0ac046 428 sentry->lock();
c8f4eac4 429 state->theSearch = Store::Root().search(NULL, NULL);
34266cde 430
1da3b90b 431 eventAdd("statObjects", statObjects, state, 0.0, 1);
432}
433
434static void
435stat_objects_get(StoreEntry * sentry)
436{
437 statObjectsStart(sentry, NULL);
438}
439
440static int
441statObjectsVmFilter(const StoreEntry * e)
090089c4 442{
1da3b90b 443 return e->mem_obj ? 1 : 0;
6684fec0 444}
090089c4 445
5e29a294 446static void
1da3b90b 447stat_vmobjects_get(StoreEntry * sentry)
6684fec0 448{
1da3b90b 449 statObjectsStart(sentry, statObjectsVmFilter);
090089c4 450}
451
ae94d28e 452#if DEBUG_OPENFD
1da3b90b 453static int
454statObjectsOpenfdFilter(const StoreEntry * e)
455{
456 if (e->mem_obj == NULL)
62e76326 457 return 0;
458
2391a162 459 if (e->mem_obj->swapout.sio == NULL)
62e76326 460 return 0;
461
1da3b90b 462 return 1;
463}
464
ae94d28e 465static void
466statOpenfdObj(StoreEntry * sentry)
467{
1da3b90b 468 statObjectsStart(sentry, statObjectsOpenfdFilter);
ae94d28e 469}
1da3b90b 470
ae94d28e 471#endif
472
32d002cb 473#if XMALLOC_STATISTICS
b8d8561b 474static void
58cd5bbd 475info_get_mallstat(int size, int number, int oldnum, void *data)
30a4f2a8 476{
18f2f920 477 StoreEntry *sentry = (StoreEntry *)data;
62e76326 478
77b88b59 479// format: "%12s %15s %6s %12s\n","Alloc Size","Count","Delta","Alloc/sec"
30a4f2a8 480 if (number > 0)
77b88b59 481 storeAppendPrintf(sentry, "%12d %15d %6d %.1f\n", size, number, number - oldnum, xdiv((number - oldnum), xm_deltat));
30a4f2a8 482}
62e76326 483
30a4f2a8 484#endif
090089c4 485
8822ebee
AR
486void
487GetInfo(Mgr::InfoActionData& stats)
090089c4 488{
62e76326 489
090089c4 490 struct rusage rusage;
f2908497 491 double cputime;
492 double runtime;
88738790 493#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 494
88738790 495 struct mstats ms;
eb824054 496#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 497
090089c4 498 struct mallinfo mp;
499#endif
500
f2908497 501 runtime = tvSubDsec(squid_start, current_time);
62e76326 502
f2908497 503 if (runtime == 0.0)
62e76326 504 runtime = 1.0;
505
8822ebee
AR
506 stats.squid_start = squid_start;
507
508 stats.current_time = current_time;
509
510 stats.client_http_clients = statCounter.client_http.clients;
511
512 stats.client_http_requests = statCounter.client_http.requests;
513
514 stats.icp_pkts_recv = statCounter.icp.pkts_recv;
515
516 stats.icp_pkts_sent = statCounter.icp.pkts_sent;
517
518 stats.icp_replies_queued = statCounter.icp.replies_queued;
519
520#if USE_HTCP
521
522 stats.htcp_pkts_recv = statCounter.htcp.pkts_recv;
523
524 stats.htcp_pkts_sent = statCounter.htcp.pkts_sent;
525
526#endif
527
528 stats.request_failure_ratio = request_failure_ratio;
529
530 stats.avg_client_http_requests = statCounter.client_http.requests / (runtime / 60.0);
531
532 stats.avg_icp_messages = (statCounter.icp.pkts_sent + statCounter.icp.pkts_recv) / (runtime / 60.0);
533
534 stats.select_loops = statCounter.select_loops;
535 stats.avg_loop_time = 1000.0 * runtime / statCounter.select_loops;
536
537 stats.request_hit_ratio5 = statRequestHitRatio(5);
538 stats.request_hit_ratio60 = statRequestHitRatio(60);
539
540 stats.byte_hit_ratio5 = statByteHitRatio(5);
541 stats.byte_hit_ratio60 = statByteHitRatio(60);
542
543 stats.request_hit_mem_ratio5 = statRequestHitMemoryRatio(5);
544 stats.request_hit_mem_ratio60 = statRequestHitMemoryRatio(60);
545
546 stats.request_hit_disk_ratio5 = statRequestHitDiskRatio(5);
547 stats.request_hit_disk_ratio60 = statRequestHitDiskRatio(60);
548
549 stats.store_swap_size = store_swap_size;
550 stats.store_swap_max_size = Store::Root().maxSize();
551
552 stats.store_mem_size = mem_node::StoreMemSize();
553 stats.store_pages_max = store_pages_max;
554 stats.store_mem_used = mem_node::InUseCount();
555
556 stats.objects_size = n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0;
557
558 stats.unlink_requests = statCounter.unlink.requests;
559
560 stats.http_requests5 = statPctileSvc(0.5, 5, PCTILE_HTTP);
561 stats.http_requests60 = statPctileSvc(0.5, 60, PCTILE_HTTP);
562
563 stats.cache_misses5 = statPctileSvc(0.5, 5, PCTILE_MISS);
564 stats.cache_misses60 = statPctileSvc(0.5, 60, PCTILE_MISS);
565
566 stats.cache_hits5 = statPctileSvc(0.5, 5, PCTILE_HIT);
567 stats.cache_hits60 = statPctileSvc(0.5, 60, PCTILE_HIT);
568
569 stats.near_hits5 = statPctileSvc(0.5, 5, PCTILE_NH);
570 stats.near_hits60 = statPctileSvc(0.5, 60, PCTILE_NH);
571
572 stats.not_modified_replies5 = statPctileSvc(0.5, 5, PCTILE_NM);
573 stats.not_modified_replies60 = statPctileSvc(0.5, 60, PCTILE_NM);
574
575 stats.dns_lookups5 = statPctileSvc(0.5, 5, PCTILE_DNS);
576 stats.dns_lookups60 = statPctileSvc(0.5, 60, PCTILE_DNS);
577
578 stats.icp_queries5 = statPctileSvc(0.5, 5, PCTILE_ICP_QUERY);
579 stats.icp_queries60 = statPctileSvc(0.5, 60, PCTILE_ICP_QUERY);
580
581 squid_getrusage(&rusage);
582 cputime = rusage_cputime(&rusage);
583
584 stats.up_time = runtime;
585 stats.cpu_time = cputime;
586 stats.cpu_usage = Math::doublePercent(cputime, runtime);
587 stats.cpu_usage5 = statCPUUsage(5);
588 stats.cpu_usage60 = statCPUUsage(60);
589
590#if HAVE_SBRK
591
592 stats.proc_data_seg = ((char *) sbrk(0) - (char *) sbrk_start);
593
594#endif
595
596 stats.maxrss = rusage_maxrss(&rusage);
597
598 stats.page_faults = rusage_pagefaults(&rusage);
599
600#if HAVE_MSTATS && HAVE_GNUMALLOC_H
601
602 ms = mstats();
603
604 stats.ms_bytes_total = ms.bytes_total;
605
606 stats.ms_bytes_free = ms.bytes_free;
607
608#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
609
610 mp = mallinfo();
611
612 stats.mp_arena = mp.arena;
613
614 stats.mp_uordblks = mp.uordblks;
615 stats.mp_ordblks = mp.ordblks;
616
617 stats.mp_usmblks = mp.usmblks;
618 stats.mp_smblks = mp.smblks;
619
620 stats.mp_hblkhd = mp.hblkhd;
621 stats.mp_hblks = mp.hblks;
622
623 stats.mp_fsmblks = mp.fsmblks;
624
625 stats.mp_fordblks = mp.fordblks;
626
627#if HAVE_STRUCT_MALLINFO_MXFAST
628
629 stats.mp_mxfast = mp.mxfast;
630
631 stats.mp_nlblks = mp.nlblks;
632
633 stats.mp_grain = mp.grain;
634
635 stats.mp_uordbytes = mp.uordbytes;
636
637 stats.mp_allocated = mp.allocated;
638
639 stats.mp_treeoverhead = mp.treeoverhead;
640
641#endif /* HAVE_STRUCT_MALLINFO_MXFAST */
642#endif /* HAVE_MALLINFO */
643
644 stats.total_accounted = statMemoryAccounted();
645
646 {
647 MemPoolGlobalStats mp_stats;
648 memPoolGetGlobalStats(&mp_stats);
649#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
650
651 stats.mem_pool_allocated = mp_stats.TheMeter->alloc.level;
652#endif
653
83ddbaf4 654 stats.gb_saved_count = mp_stats.TheMeter->gb_saved.count;
8822ebee
AR
655 stats.gb_freed_count = mp_stats.TheMeter->gb_freed.count;
656 }
657
658 stats.max_fd = Squid_MaxFD;
659 stats.biggest_fd = Biggest_FD;
660 stats.number_fd = Number_FD;
661 stats.opening_fd = Opening_FD;
662 stats.num_fd_free = fdNFree();
663 stats.reserved_fd = RESERVED_FD;
664 stats.store_open_disk_fd = store_open_disk_fd;
665
666 stats.store_entries = StoreEntry::inUseCount();
667 stats.store_mem_entries = MemObject::inUseCount();
668 stats.hot_obj_count = hot_obj_count;
669 stats.n_disk_objects = n_disk_objects;
670}
671
672void
673DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
674{
15576b6a 675 storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
62e76326 676 version_string);
677
be266cb2 678#if _SQUID_WINDOWS_
1a774556 679 if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
680 storeAppendPrintf(sentry,"\nRunning as %s Windows System Service on %s\n",
681 WIN32_Service_name, WIN32_OS_string);
682 storeAppendPrintf(sentry,"Service command line is: %s\n", WIN32_Service_Command_Line);
683 } else
684 storeAppendPrintf(sentry,"Running on %s\n",WIN32_OS_string);
1a774556 685#endif
686
15576b6a 687 storeAppendPrintf(sentry, "Start Time:\t%s\n",
8822ebee 688 mkrfc1123(stats.squid_start.tv_sec));
62e76326 689
15576b6a 690 storeAppendPrintf(sentry, "Current Time:\t%s\n",
8822ebee 691 mkrfc1123(stats.current_time.tv_sec));
62e76326 692
7dbca7a4 693 storeAppendPrintf(sentry, "Connection information for %s:\n",APP_SHORTNAME);
62e76326 694
8822ebee
AR
695 storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%.0f\n",
696 stats.client_http_clients);
62e76326 697
8822ebee
AR
698 storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%.0f\n",
699 stats.client_http_requests);
62e76326 700
8822ebee
AR
701 storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%.0f\n",
702 stats.icp_pkts_recv);
62e76326 703
8822ebee
AR
704 storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%.0f\n",
705 stats.icp_pkts_sent);
62e76326 706
8822ebee
AR
707 storeAppendPrintf(sentry, "\tNumber of queued ICP replies:\t%.0f\n",
708 stats.icp_replies_queued);
62e76326 709
c4ebc830 710#if USE_HTCP
711
8822ebee
AR
712 storeAppendPrintf(sentry, "\tNumber of HTCP messages received:\t%.0f\n",
713 stats.htcp_pkts_recv);
c4ebc830 714
8822ebee
AR
715 storeAppendPrintf(sentry, "\tNumber of HTCP messages sent:\t%.0f\n",
716 stats.htcp_pkts_sent);
c4ebc830 717
718#endif
719
8822ebee 720 double fct = stats.count > 1 ? stats.count : 1.0;
a4ba1105 721 storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f\n",
8822ebee 722 stats.request_failure_ratio / fct);
f2908497 723
b51b0e13 724 storeAppendPrintf(sentry, "\tAverage HTTP requests per minute since start:\t%.1f\n",
61564333 725 stats.avg_client_http_requests);
62e76326 726
b51b0e13 727 storeAppendPrintf(sentry, "\tAverage ICP messages per minute since start:\t%.1f\n",
61564333 728 stats.avg_icp_messages);
62e76326 729
8822ebee
AR
730 storeAppendPrintf(sentry, "\tSelect loop called: %.0f times, %0.3f ms avg\n",
731 stats.select_loops, stats.avg_loop_time / fct);
090089c4 732
7dbca7a4 733 storeAppendPrintf(sentry, "Cache information for %s:\n",APP_SHORTNAME);
62e76326 734
5bf79e53 735 storeAppendPrintf(sentry, "\tHits as %% of all requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
8822ebee
AR
736 stats.request_hit_ratio5 / fct,
737 stats.request_hit_ratio60 / fct);
62e76326 738
5bf79e53 739 storeAppendPrintf(sentry, "\tHits as %% of bytes sent:\t5min: %3.1f%%, 60min: %3.1f%%\n",
8822ebee
AR
740 stats.byte_hit_ratio5 / fct,
741 stats.byte_hit_ratio60 / fct);
62e76326 742
5bf79e53 743 storeAppendPrintf(sentry, "\tMemory hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
8822ebee
AR
744 stats.request_hit_mem_ratio5 / fct,
745 stats.request_hit_mem_ratio60 / fct);
62e76326 746
5bf79e53 747 storeAppendPrintf(sentry, "\tDisk hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
8822ebee
AR
748 stats.request_hit_disk_ratio5 / fct,
749 stats.request_hit_disk_ratio60 / fct);
62e76326 750
8822ebee 751 storeAppendPrintf(sentry, "\tStorage Swap size:\t%.0f KB\n",
904e213e 752 stats.store_swap_size);
62e76326 753
6a52823b 754 storeAppendPrintf(sentry, "\tStorage Swap capacity:\t%4.1f%% used, %4.1f%% free\n",
8822ebee
AR
755 Math::doublePercent(stats.store_swap_size, stats.store_swap_max_size),
756 Math::doublePercent(stats.store_swap_max_size - stats.store_swap_size, stats.store_swap_max_size));
6a52823b 757
8822ebee
AR
758 storeAppendPrintf(sentry, "\tStorage Mem size:\t%.0f KB\n",
759 stats.store_mem_size / 1024);
62e76326 760
8822ebee 761 const double mFree = max(0.0, stats.store_pages_max-stats.store_mem_used);
6a52823b 762 storeAppendPrintf(sentry, "\tStorage Mem capacity:\t%4.1f%% used, %4.1f%% free\n",
8822ebee
AR
763 Math::doublePercent(stats.store_mem_used, stats.store_pages_max),
764 Math::doublePercent(mFree, stats.store_pages_max));
6a52823b 765
0faf70d0 766 storeAppendPrintf(sentry, "\tMean Object Size:\t%0.2f KB\n",
8822ebee 767 stats.objects_size / fct);
62e76326 768
8822ebee
AR
769 storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%.0f\n",
770 stats.unlink_requests);
090089c4 771
b87b92fb 772 storeAppendPrintf(sentry, "Median Service Times (seconds) 5 min 60 min:\n");
62e76326 773
8822ebee 774 fct = stats.count > 1 ? stats.count * 1000.0 : 1000.0;
b87b92fb 775 storeAppendPrintf(sentry, "\tHTTP Requests (All): %8.5f %8.5f\n",
8822ebee
AR
776 stats.http_requests5 / fct,
777 stats.http_requests60 / fct);
62e76326 778
b87b92fb 779 storeAppendPrintf(sentry, "\tCache Misses: %8.5f %8.5f\n",
8822ebee
AR
780 stats.cache_misses5 / fct,
781 stats.cache_misses60 / fct);
62e76326 782
b87b92fb 783 storeAppendPrintf(sentry, "\tCache Hits: %8.5f %8.5f\n",
8822ebee
AR
784 stats.cache_hits5 / fct,
785 stats.cache_hits60 / fct);
62e76326 786
7c9c84ad 787 storeAppendPrintf(sentry, "\tNear Hits: %8.5f %8.5f\n",
8822ebee
AR
788 stats.near_hits5 / fct,
789 stats.near_hits60 / fct);
62e76326 790
b87b92fb 791 storeAppendPrintf(sentry, "\tNot-Modified Replies: %8.5f %8.5f\n",
8822ebee
AR
792 stats.not_modified_replies5 / fct,
793 stats.not_modified_replies60 / fct);
62e76326 794
b87b92fb 795 storeAppendPrintf(sentry, "\tDNS Lookups: %8.5f %8.5f\n",
8822ebee
AR
796 stats.dns_lookups5 / fct,
797 stats.dns_lookups60 / fct);
62e76326 798
8822ebee 799 fct = stats.count > 1 ? stats.count * 1000000.0 : 1000000.0;
b87b92fb 800 storeAppendPrintf(sentry, "\tICP Queries: %8.5f %8.5f\n",
8822ebee
AR
801 stats.icp_queries5 / fct,
802 stats.icp_queries60 / fct);
62e76326 803
7dbca7a4 804 storeAppendPrintf(sentry, "Resource usage for %s:\n", APP_SHORTNAME);
62e76326 805
8822ebee 806 storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", stats.up_time);
62e76326 807
8822ebee 808 storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", stats.cpu_time);
62e76326 809
15576b6a 810 storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
8822ebee 811 stats.cpu_usage);
62e76326 812
979533fa 813 storeAppendPrintf(sentry, "\tCPU Usage, 5 minute avg:\t%.2f%%\n",
8822ebee 814 stats.cpu_usage5);
62e76326 815
49ad0a8c 816 storeAppendPrintf(sentry, "\tCPU Usage, 60 minute avg:\t%.2f%%\n",
8822ebee 817 stats.cpu_usage60);
62e76326 818
a4ba1105 819#if HAVE_SBRK
62e76326 820
8822ebee
AR
821 storeAppendPrintf(sentry, "\tProcess Data Segment Size via sbrk(): %.0f KB\n",
822 stats.proc_data_seg / 1024);
62e76326 823
a4ba1105 824#endif
62e76326 825
8822ebee
AR
826 storeAppendPrintf(sentry, "\tMaximum Resident Size: %.0f KB\n",
827 stats.maxrss);
62e76326 828
8822ebee
AR
829 storeAppendPrintf(sentry, "\tPage faults with physical i/o: %.0f\n",
830 stats.page_faults);
090089c4 831
88738790 832#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 833
7dbca7a4 834 storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",APP_SHORTNAME);
62e76326 835
8822ebee
AR
836 storeAppendPrintf(sentry, "\tTotal space in arena: %6.0f KB\n",
837 stats.ms_bytes_total / 1024);
62e76326 838
8822ebee
AR
839 storeAppendPrintf(sentry, "\tTotal free: %6.0f KB %.0f%%\n",
840 stats.ms_bytes_free / 1024,
841 Math::doublePercent(stats.ms_bytes_free, stats.ms_bytes_total));
62e76326 842
eb824054 843#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 844
7dbca7a4 845 storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",APP_SHORTNAME);
62e76326 846
8822ebee
AR
847 storeAppendPrintf(sentry, "\tTotal space in arena: %6.0f KB\n",
848 stats.mp_arena / 1024);
62e76326 849
8822ebee
AR
850 storeAppendPrintf(sentry, "\tOrdinary blocks: %6.0f KB %6.0f blks\n",
851 stats.mp_uordblks / 1024, stats.mp_ordblks);
62e76326 852
8822ebee
AR
853 storeAppendPrintf(sentry, "\tSmall blocks: %6.0f KB %6.0f blks\n",
854 stats.mp_usmblks / 1024, stats.mp_smblks);
62e76326 855
8822ebee
AR
856 storeAppendPrintf(sentry, "\tHolding blocks: %6.0f KB %6.0f blks\n",
857 stats.mp_hblkhd / 1024, stats.mp_hblks);
62e76326 858
8822ebee
AR
859 storeAppendPrintf(sentry, "\tFree Small blocks: %6.0f KB\n",
860 stats.mp_fsmblks / 1024);
62e76326 861
8822ebee
AR
862 storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6.0f KB\n",
863 stats.mp_fordblks / 1024);
62e76326 864
8822ebee 865 double t = stats.mp_fsmblks + stats.mp_fordblks;
62e76326 866
8822ebee
AR
867 storeAppendPrintf(sentry, "\tTotal in use: %6.0f KB %.0f%%\n",
868 t / 1024, Math::doublePercent(t, stats.mp_arena + stats.mp_hblkhd));
62e76326 869
8822ebee 870 t = stats.mp_fsmblks + stats.mp_fordblks;
62e76326 871
8822ebee
AR
872 storeAppendPrintf(sentry, "\tTotal free: %6.0f KB %.0f%%\n",
873 t / 1024, Math::doublePercent(t, stats.mp_arena + stats.mp_hblkhd));
62e76326 874
8822ebee 875 t = stats.mp_arena + stats.mp_hblkhd;
62e76326 876
8822ebee
AR
877 storeAppendPrintf(sentry, "\tTotal size: %6.0f KB\n",
878 t / 1024);
62e76326 879
6a9f6389 880#if HAVE_STRUCT_MALLINFO_MXFAST
62e76326 881
8822ebee 882 storeAppendPrintf(sentry, "\tmax size of small blocks:\t%.0f\n", stats.mp_mxfast);
62e76326 883
8822ebee
AR
884 storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%.0f\n",
885 stats.mp_nlblks);
62e76326 886
8822ebee 887 storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%.0f\n", stats.mp_grain);
62e76326 888
8822ebee
AR
889 storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%.0f\n"
890 ,stats.mp_uordbytes);
62e76326 891
8822ebee
AR
892 storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%.0f\n",
893 stats.mp_allocated);
62e76326 894
8822ebee
AR
895 storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%.0f\n",
896 stats.mp_treeoverhead);
62e76326 897
6a9f6389 898#endif /* HAVE_STRUCT_MALLINFO_MXFAST */
50bc2565 899#endif /* HAVE_MALLINFO */
62e76326 900
5d1f3c82 901 storeAppendPrintf(sentry, "Memory accounted for:\n");
62e76326 902
d96ceb8e 903#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 904
8822ebee
AR
905 storeAppendPrintf(sentry, "\tTotal accounted: %6.0f KB %3.0f%%\n",
906 stats.total_accounted / 1024, Math::doublePercent(stats.total_accounted, t));
62e76326 907
d96ceb8e 908#else
62e76326 909
8822ebee
AR
910 storeAppendPrintf(sentry, "\tTotal accounted: %6.0f KB\n",
911 stats.total_accounted / 1024);
62e76326 912
d96ceb8e 913#endif
914 {
62e76326 915 MemPoolGlobalStats mp_stats;
916 memPoolGetGlobalStats(&mp_stats);
1ce8e204 917#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 918
8822ebee
AR
919 storeAppendPrintf(sentry, "\tmemPool accounted: %6.0f KB %3.0f%%\n",
920 stats.mem_pool_allocated / 1024,
921 Math::doublePercent(stats.mem_pool_allocated, t));
95c03392 922
8822ebee
AR
923 const double iFree = max(0.0, t - stats.mem_pool_allocated);
924 storeAppendPrintf(sentry, "\tmemPool unaccounted: %6.0f KB %3.0f%%\n",
925 (t - stats.mem_pool_allocated) / 1024,
926 Math::doublePercent(iFree, t));
1ce8e204 927#endif
62e76326 928
929 storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9.0f\n",
8822ebee 930 stats.gb_saved_count);
62e76326 931 storeAppendPrintf(sentry, "\tmemPoolFree calls: %9.0f\n",
8822ebee 932 stats.gb_freed_count);
d96ceb8e 933 }
62e76326 934
7dbca7a4 935 storeAppendPrintf(sentry, "File descriptor usage for %s:\n", APP_SHORTNAME);
8822ebee
AR
936 storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4.0f\n",
937 stats.max_fd);
938 storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4.0f\n",
939 stats.biggest_fd);
940 storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4.0f\n",
941 stats.number_fd);
942 storeAppendPrintf(sentry, "\tFiles queued for open: %4.0f\n",
943 stats.opening_fd);
944 storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4.0f\n",
945 stats.num_fd_free);
946 storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4.0f\n",
947 stats.reserved_fd);
948 storeAppendPrintf(sentry, "\tStore Disk files open: %4.0f\n",
949 stats.store_open_disk_fd);
090089c4 950
15576b6a 951 storeAppendPrintf(sentry, "Internal Data Structures:\n");
8822ebee
AR
952 storeAppendPrintf(sentry, "\t%6.0f StoreEntries\n",
953 stats.store_entries);
954 storeAppendPrintf(sentry, "\t%6.0f StoreEntries with MemObjects\n",
955 stats.store_mem_entries);
956 storeAppendPrintf(sentry, "\t%6.0f Hot Object Cache Items\n",
957 stats.hot_obj_count);
958 storeAppendPrintf(sentry, "\t%6.0f on-disk objects\n",
959 stats.n_disk_objects);
960}
30a4f2a8 961
8822ebee
AR
962void
963DumpMallocStatistics(StoreEntry* sentry)
964{
30a4f2a8 965#if XMALLOC_STATISTICS
62e76326 966
58cd5bbd 967 xm_deltat = current_dtime - xm_time;
968 xm_time = current_dtime;
969 storeAppendPrintf(sentry, "\nMemory allocation statistics\n");
77b88b59 970 storeAppendPrintf(sentry, "%12s %15s %6s %12s\n","Alloc Size","Count","Delta","Alloc/sec");
30a4f2a8 971 malloc_statistics(info_get_mallstat, sentry);
972#endif
090089c4 973}
974
8822ebee
AR
975void
976GetServiceTimesStats(Mgr::ServiceTimesActionData& stats)
977{
978 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
979 double p = (i + 1) * 5 / 100.0;
980 stats.http_requests5[i] = statPctileSvc(p, 5, PCTILE_HTTP);
981 stats.http_requests60[i] = statPctileSvc(p, 60, PCTILE_HTTP);
982
983 stats.cache_misses5[i] = statPctileSvc(p, 5, PCTILE_MISS);
984 stats.cache_misses60[i] = statPctileSvc(p, 60, PCTILE_MISS);
985
986 stats.cache_hits5[i] = statPctileSvc(p, 5, PCTILE_HIT);
987 stats.cache_hits60[i] = statPctileSvc(p, 60, PCTILE_HIT);
988
989 stats.near_hits5[i] = statPctileSvc(p, 5, PCTILE_NH);
990 stats.near_hits60[i] = statPctileSvc(p, 60, PCTILE_NH);
991
992 stats.not_modified_replies5[i] = statPctileSvc(p, 5, PCTILE_NM);
993 stats.not_modified_replies60[i] = statPctileSvc(p, 60, PCTILE_NM);
994
995 stats.dns_lookups5[i] = statPctileSvc(p, 5, PCTILE_DNS);
996 stats.dns_lookups60[i] = statPctileSvc(p, 60, PCTILE_DNS);
997
998 stats.icp_queries5[i] = statPctileSvc(p, 5, PCTILE_ICP_QUERY);
999 stats.icp_queries60[i] = statPctileSvc(p, 60, PCTILE_ICP_QUERY);
1000 }
1001}
1002
1003void
1004DumpServiceTimesStats(Mgr::ServiceTimesActionData& stats, StoreEntry* sentry)
04a28d46 1005{
04a28d46 1006 storeAppendPrintf(sentry, "Service Time Percentiles 5 min 60 min:\n");
8822ebee
AR
1007 double fct = stats.count > 1 ? stats.count * 1000.0 : 1000.0;
1008 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1009 storeAppendPrintf(sentry, "\tHTTP Requests (All): %2d%% %8.5f %8.5f\n",
8822ebee
AR
1010 (i + 1) * 5,
1011 stats.http_requests5[i] / fct,
1012 stats.http_requests60[i] / fct);
04a28d46 1013 }
8822ebee 1014 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1015 storeAppendPrintf(sentry, "\tCache Misses: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1016 (i + 1) * 5,
1017 stats.cache_misses5[i] / fct,
1018 stats.cache_misses60[i] / fct);
04a28d46 1019 }
8822ebee 1020 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1021 storeAppendPrintf(sentry, "\tCache Hits: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1022 (i + 1) * 5,
1023 stats.cache_hits5[i] / fct,
1024 stats.cache_hits60[i] / fct);
04a28d46 1025 }
8822ebee 1026 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1027 storeAppendPrintf(sentry, "\tNear Hits: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1028 (i + 1) * 5,
1029 stats.near_hits5[i] / fct,
1030 stats.near_hits60[i] / fct);
04a28d46 1031 }
8822ebee 1032 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1033 storeAppendPrintf(sentry, "\tNot-Modified Replies: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1034 (i + 1) * 5,
1035 stats.not_modified_replies5[i] / fct,
1036 stats.not_modified_replies60[i] / fct);
04a28d46 1037 }
8822ebee 1038 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1039 storeAppendPrintf(sentry, "\tDNS Lookups: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1040 (i + 1) * 5,
1041 stats.dns_lookups5[i] / fct,
1042 stats.dns_lookups60[i] / fct);
04a28d46 1043 }
8822ebee
AR
1044 fct = stats.count > 1 ? stats.count * 1000000.0 : 1000000.0;
1045 for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
26ac0430 1046 storeAppendPrintf(sentry, "\tICP Queries: %2d%% %8.5f %8.5f\n",
8822ebee
AR
1047 (i + 1) * 5,
1048 stats.icp_queries5[i] / fct,
1049 stats.icp_queries60[i] / fct);
04a28d46 1050 }
1051}
1052
b8d8561b 1053static void
a0f32775 1054statAvgDump(StoreEntry * sentry, int minutes, int hours)
8822ebee
AR
1055{
1056 Mgr::IntervalActionData stats;
1057 GetAvgStat(stats, minutes, hours);
1058 DumpAvgStat(stats, sentry);
1059}
1060
1061#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
1062void
1063GetAvgStat(Mgr::IntervalActionData& stats, int minutes, int hours)
090089c4 1064{
a7c05555 1065 StatCounters *f;
1066 StatCounters *l;
1067 double dt;
1068 double ct;
1069 assert(N_COUNT_HIST > 1);
a0f32775 1070 assert(minutes > 0 || hours > 0);
a7c05555 1071 f = &CountHist[0];
a0f32775 1072 l = f;
62e76326 1073
a0f32775 1074 if (minutes > 0 && hours == 0) {
62e76326 1075 /* checking minute readings ... */
1076
1077 if (minutes > N_COUNT_HIST - 1)
1078 minutes = N_COUNT_HIST - 1;
1079
1080 l = &CountHist[minutes];
a0f32775 1081 } else if (minutes == 0 && hours > 0) {
62e76326 1082 /* checking hour readings ... */
1083
1084 if (hours > N_COUNT_HOUR_HIST - 1)
1085 hours = N_COUNT_HOUR_HIST - 1;
1086
1087 l = &CountHourHist[hours];
a0f32775 1088 } else {
bf8fe701 1089 debugs(18, 1, "statAvgDump: Invalid args, minutes=" << minutes << ", hours=" << hours);
62e76326 1090 return;
a0f32775 1091 }
62e76326 1092
a7c05555 1093 dt = tvSubDsec(l->timestamp, f->timestamp);
1094 ct = f->cputime - l->cputime;
ee1679df 1095
8822ebee
AR
1096 stats.sample_start_time = l->timestamp;
1097 stats.sample_end_time = f->timestamp;
1098
1099 stats.client_http_requests = XAVG(client_http.requests);
1100 stats.client_http_hits = XAVG(client_http.hits);
1101 stats.client_http_errors = XAVG(client_http.errors);
1102 stats.client_http_kbytes_in = XAVG(client_http.kbytes_in.kb);
1103 stats.client_http_kbytes_out = XAVG(client_http.kbytes_out.kb);
1104
1105 stats.client_http_all_median_svc_time = statHistDeltaMedian(&l->client_http.all_svc_time,
d9fc6862 1106 &f->client_http.all_svc_time) / 1000.0;
8822ebee 1107 stats.client_http_miss_median_svc_time = statHistDeltaMedian(&l->client_http.miss_svc_time,
d9fc6862 1108 &f->client_http.miss_svc_time) / 1000.0;
8822ebee 1109 stats.client_http_nm_median_svc_time = statHistDeltaMedian(&l->client_http.nm_svc_time,
d9fc6862 1110 &f->client_http.nm_svc_time) / 1000.0;
8822ebee 1111 stats.client_http_nh_median_svc_time = statHistDeltaMedian(&l->client_http.nh_svc_time,
d9fc6862 1112 &f->client_http.nh_svc_time) / 1000.0;
8822ebee 1113 stats.client_http_hit_median_svc_time = statHistDeltaMedian(&l->client_http.hit_svc_time,
d9fc6862 1114 &f->client_http.hit_svc_time) / 1000.0;
8822ebee
AR
1115
1116 stats.server_all_requests = XAVG(server.all.requests);
1117 stats.server_all_errors = XAVG(server.all.errors);
1118 stats.server_all_kbytes_in = XAVG(server.all.kbytes_in.kb);
1119 stats.server_all_kbytes_out = XAVG(server.all.kbytes_out.kb);
1120
1121 stats.server_http_requests = XAVG(server.http.requests);
1122 stats.server_http_errors = XAVG(server.http.errors);
1123 stats.server_http_kbytes_in = XAVG(server.http.kbytes_in.kb);
1124 stats.server_http_kbytes_out = XAVG(server.http.kbytes_out.kb);
1125
1126 stats.server_ftp_requests = XAVG(server.ftp.requests);
1127 stats.server_ftp_errors = XAVG(server.ftp.errors);
1128 stats.server_ftp_kbytes_in = XAVG(server.ftp.kbytes_in.kb);
1129 stats.server_ftp_kbytes_out = XAVG(server.ftp.kbytes_out.kb);
1130
1131 stats.server_other_requests = XAVG(server.other.requests);
1132 stats.server_other_errors = XAVG(server.other.errors);
1133 stats.server_other_kbytes_in = XAVG(server.other.kbytes_in.kb);
1134 stats.server_other_kbytes_out = XAVG(server.other.kbytes_out.kb);
1135
1136 stats.icp_pkts_sent = XAVG(icp.pkts_sent);
1137 stats.icp_pkts_recv = XAVG(icp.pkts_recv);
1138 stats.icp_queries_sent = XAVG(icp.queries_sent);
1139 stats.icp_replies_sent = XAVG(icp.replies_sent);
1140 stats.icp_queries_recv = XAVG(icp.queries_recv);
1141 stats.icp_replies_recv = XAVG(icp.replies_recv);
1142 stats.icp_replies_queued = XAVG(icp.replies_queued);
1143 stats.icp_query_timeouts = XAVG(icp.query_timeouts);
1144 stats.icp_kbytes_sent = XAVG(icp.kbytes_sent.kb);
1145 stats.icp_kbytes_recv = XAVG(icp.kbytes_recv.kb);
1146 stats.icp_q_kbytes_sent = XAVG(icp.q_kbytes_sent.kb);
1147 stats.icp_r_kbytes_sent = XAVG(icp.r_kbytes_sent.kb);
1148 stats.icp_q_kbytes_recv = XAVG(icp.q_kbytes_recv.kb);
1149 stats.icp_r_kbytes_recv = XAVG(icp.r_kbytes_recv.kb);
1150
1151 stats.icp_query_median_svc_time = statHistDeltaMedian(&l->icp.query_svc_time,
d9fc6862 1152 &f->icp.query_svc_time) / 1000000.0;
8822ebee 1153 stats.icp_reply_median_svc_time = statHistDeltaMedian(&l->icp.reply_svc_time,
d9fc6862 1154 &f->icp.reply_svc_time) / 1000000.0;
8822ebee 1155 stats.dns_median_svc_time = statHistDeltaMedian(&l->dns.svc_time,
d9fc6862 1156 &f->dns.svc_time) / 1000.0;
8822ebee
AR
1157
1158 stats.unlink_requests = XAVG(unlink.requests);
1159 stats.page_faults = XAVG(page_faults);
1160 stats.select_loops = XAVG(select_loops);
1161 stats.select_fds = XAVG(select_fds);
1162 stats.average_select_fd_period = f->select_fds > l->select_fds ?
d9fc6862 1163 (f->select_time - l->select_time) / (f->select_fds - l->select_fds) : 0.0;
8822ebee
AR
1164
1165 stats.median_select_fds = statHistDeltaMedian(&l->select_fds_hist, &f->select_fds_hist);
1166 stats.swap_outs = XAVG(swap.outs);
1167 stats.swap_ins = XAVG(swap.ins);
1168 stats.swap_files_cleaned = XAVG(swap.files_cleaned);
1169 stats.aborted_requests = XAVG(aborted_requests);
1170
1171 stats.syscalls_disk_opens = XAVG(syscalls.disk.opens);
1172 stats.syscalls_disk_closes = XAVG(syscalls.disk.closes);
1173 stats.syscalls_disk_reads = XAVG(syscalls.disk.reads);
1174 stats.syscalls_disk_writes = XAVG(syscalls.disk.writes);
1175 stats.syscalls_disk_seeks = XAVG(syscalls.disk.seeks);
1176 stats.syscalls_disk_unlinks = XAVG(syscalls.disk.unlinks);
1177 stats.syscalls_sock_accepts = XAVG(syscalls.sock.accepts);
1178 stats.syscalls_sock_sockets = XAVG(syscalls.sock.sockets);
1179 stats.syscalls_sock_connects = XAVG(syscalls.sock.connects);
1180 stats.syscalls_sock_binds = XAVG(syscalls.sock.binds);
1181 stats.syscalls_sock_closes = XAVG(syscalls.sock.closes);
1182 stats.syscalls_sock_reads = XAVG(syscalls.sock.reads);
1183 stats.syscalls_sock_writes = XAVG(syscalls.sock.writes);
1184 stats.syscalls_sock_recvfroms = XAVG(syscalls.sock.recvfroms);
1185 stats.syscalls_sock_sendtos = XAVG(syscalls.sock.sendtos);
1186 stats.syscalls_selects = XAVG(syscalls.selects);
1187
1188 stats.cpu_time = ct;
1189 stats.wall_time = dt;
1190}
1191
1192void
1193DumpAvgStat(Mgr::IntervalActionData& stats, StoreEntry* sentry)
1194{
399e85ea 1195 storeAppendPrintf(sentry, "sample_start_time = %d.%d (%s)\n",
8822ebee
AR
1196 (int)stats.sample_start_time.tv_sec,
1197 (int)stats.sample_start_time.tv_usec,
1198 mkrfc1123(stats.sample_start_time.tv_sec));
5843f24a 1199 storeAppendPrintf(sentry, "sample_end_time = %d.%d (%s)\n",
8822ebee
AR
1200 (int)stats.sample_end_time.tv_sec,
1201 (int)stats.sample_end_time.tv_usec,
1202 mkrfc1123(stats.sample_end_time.tv_sec));
a0f32775 1203
a7c05555 1204 storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
8822ebee 1205 stats.client_http_requests);
a7c05555 1206 storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
8822ebee 1207 stats.client_http_hits);
a7c05555 1208 storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
8822ebee 1209 stats.client_http_errors);
a7c05555 1210 storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
8822ebee 1211 stats.client_http_kbytes_in);
a7c05555 1212 storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
8822ebee 1213 stats.client_http_kbytes_out);
ee1679df 1214
8822ebee 1215 double fct = stats.count > 1 ? stats.count : 1.0;
ee1679df 1216 storeAppendPrintf(sentry, "client_http.all_median_svc_time = %f seconds\n",
8822ebee 1217 stats.client_http_all_median_svc_time / fct);
ee1679df 1218 storeAppendPrintf(sentry, "client_http.miss_median_svc_time = %f seconds\n",
8822ebee 1219 stats.client_http_miss_median_svc_time / fct);
ee1679df 1220 storeAppendPrintf(sentry, "client_http.nm_median_svc_time = %f seconds\n",
8822ebee 1221 stats.client_http_nm_median_svc_time / fct);
7c9c84ad 1222 storeAppendPrintf(sentry, "client_http.nh_median_svc_time = %f seconds\n",
8822ebee 1223 stats.client_http_nh_median_svc_time / fct);
ee1679df 1224 storeAppendPrintf(sentry, "client_http.hit_median_svc_time = %f seconds\n",
8822ebee 1225 stats.client_http_hit_median_svc_time / fct);
071a3ae7 1226
a0f32775 1227 storeAppendPrintf(sentry, "server.all.requests = %f/sec\n",
8822ebee 1228 stats.server_all_requests);
a0f32775 1229 storeAppendPrintf(sentry, "server.all.errors = %f/sec\n",
8822ebee 1230 stats.server_all_errors);
a0f32775 1231 storeAppendPrintf(sentry, "server.all.kbytes_in = %f/sec\n",
8822ebee 1232 stats.server_all_kbytes_in);
a0f32775 1233 storeAppendPrintf(sentry, "server.all.kbytes_out = %f/sec\n",
8822ebee 1234 stats.server_all_kbytes_out);
a0f32775 1235
1236 storeAppendPrintf(sentry, "server.http.requests = %f/sec\n",
8822ebee 1237 stats.server_http_requests);
a0f32775 1238 storeAppendPrintf(sentry, "server.http.errors = %f/sec\n",
8822ebee 1239 stats.server_http_errors);
a0f32775 1240 storeAppendPrintf(sentry, "server.http.kbytes_in = %f/sec\n",
8822ebee 1241 stats.server_http_kbytes_in);
a0f32775 1242 storeAppendPrintf(sentry, "server.http.kbytes_out = %f/sec\n",
8822ebee 1243 stats.server_http_kbytes_out);
a0f32775 1244
1245 storeAppendPrintf(sentry, "server.ftp.requests = %f/sec\n",
8822ebee 1246 stats.server_ftp_requests);
a0f32775 1247 storeAppendPrintf(sentry, "server.ftp.errors = %f/sec\n",
8822ebee 1248 stats.server_ftp_errors);
a0f32775 1249 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %f/sec\n",
8822ebee 1250 stats.server_ftp_kbytes_in);
a0f32775 1251 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %f/sec\n",
8822ebee 1252 stats.server_ftp_kbytes_out);
a0f32775 1253
1254 storeAppendPrintf(sentry, "server.other.requests = %f/sec\n",
8822ebee 1255 stats.server_other_requests);
a0f32775 1256 storeAppendPrintf(sentry, "server.other.errors = %f/sec\n",
8822ebee 1257 stats.server_other_errors);
a0f32775 1258 storeAppendPrintf(sentry, "server.other.kbytes_in = %f/sec\n",
8822ebee 1259 stats.server_other_kbytes_in);
a0f32775 1260 storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
8822ebee 1261 stats.server_other_kbytes_out);
ee1679df 1262
a7c05555 1263 storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
8822ebee 1264 stats.icp_pkts_sent);
a7c05555 1265 storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
8822ebee 1266 stats.icp_pkts_recv);
071a3ae7 1267 storeAppendPrintf(sentry, "icp.queries_sent = %f/sec\n",
8822ebee 1268 stats.icp_queries_sent);
071a3ae7 1269 storeAppendPrintf(sentry, "icp.replies_sent = %f/sec\n",
8822ebee 1270 stats.icp_replies_sent);
071a3ae7 1271 storeAppendPrintf(sentry, "icp.queries_recv = %f/sec\n",
8822ebee 1272 stats.icp_queries_recv);
071a3ae7 1273 storeAppendPrintf(sentry, "icp.replies_recv = %f/sec\n",
8822ebee 1274 stats.icp_replies_recv);
2e8e29b8 1275 storeAppendPrintf(sentry, "icp.replies_queued = %f/sec\n",
8822ebee 1276 stats.icp_replies_queued);
071a3ae7 1277 storeAppendPrintf(sentry, "icp.query_timeouts = %f/sec\n",
8822ebee 1278 stats.icp_query_timeouts);
a7c05555 1279 storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
8822ebee 1280 stats.icp_kbytes_sent);
a7c05555 1281 storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
8822ebee 1282 stats.icp_kbytes_recv);
071a3ae7 1283 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %f/sec\n",
8822ebee 1284 stats.icp_q_kbytes_sent);
071a3ae7 1285 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %f/sec\n",
8822ebee 1286 stats.icp_r_kbytes_sent);
071a3ae7 1287 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %f/sec\n",
8822ebee 1288 stats.icp_q_kbytes_recv);
071a3ae7 1289 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %f/sec\n",
8822ebee 1290 stats.icp_r_kbytes_recv);
ee1679df 1291 storeAppendPrintf(sentry, "icp.query_median_svc_time = %f seconds\n",
8822ebee 1292 stats.icp_query_median_svc_time / fct);
ee1679df 1293 storeAppendPrintf(sentry, "icp.reply_median_svc_time = %f seconds\n",
8822ebee 1294 stats.icp_reply_median_svc_time / fct);
9973e9fe 1295 storeAppendPrintf(sentry, "dns.median_svc_time = %f seconds\n",
8822ebee 1296 stats.dns_median_svc_time / fct);
a7c05555 1297 storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
8822ebee 1298 stats.unlink_requests);
a7c05555 1299 storeAppendPrintf(sentry, "page_faults = %f/sec\n",
8822ebee 1300 stats.page_faults);
a7c05555 1301 storeAppendPrintf(sentry, "select_loops = %f/sec\n",
8822ebee 1302 stats.select_loops);
d239c2f5 1303 storeAppendPrintf(sentry, "select_fds = %f/sec\n",
8822ebee 1304 stats.select_fds);
d239c2f5 1305 storeAppendPrintf(sentry, "average_select_fd_period = %f/fd\n",
8822ebee
AR
1306 stats.average_select_fd_period / fct);
1307 storeAppendPrintf(sentry, "median_select_fds = %f\n",
1308 stats.median_select_fds / fct);
23dc8aca 1309 storeAppendPrintf(sentry, "swap.outs = %f/sec\n",
8822ebee 1310 stats.swap_outs);
23dc8aca 1311 storeAppendPrintf(sentry, "swap.ins = %f/sec\n",
8822ebee 1312 stats.swap_ins);
23dc8aca 1313 storeAppendPrintf(sentry, "swap.files_cleaned = %f/sec\n",
8822ebee 1314 stats.swap_files_cleaned);
bfae3379 1315 storeAppendPrintf(sentry, "aborted_requests = %f/sec\n",
8822ebee 1316 stats.aborted_requests);
886f2785 1317
1b3db6d9 1318#if USE_POLL
8822ebee 1319 storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", stats.syscalls_selects);
7d63e639 1320#elif defined(USE_SELECT) || defined(USE_SELECT_WIN32)
8822ebee 1321 storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", stats.syscalls_selects);
886f2785 1322#endif
62e76326 1323
8822ebee
AR
1324 storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", stats.syscalls_disk_opens);
1325 storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", stats.syscalls_disk_closes);
1326 storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", stats.syscalls_disk_reads);
1327 storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", stats.syscalls_disk_writes);
1328 storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", stats.syscalls_disk_seeks);
1329 storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", stats.syscalls_disk_unlinks);
1330 storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", stats.syscalls_sock_accepts);
1331 storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", stats.syscalls_sock_sockets);
1332 storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", stats.syscalls_sock_connects);
1333 storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", stats.syscalls_sock_binds);
1334 storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", stats.syscalls_sock_closes);
1335 storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", stats.syscalls_sock_reads);
1336 storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", stats.syscalls_sock_writes);
1337 storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", stats.syscalls_sock_recvfroms);
1338 storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", stats.syscalls_sock_sendtos);
1339
1340 storeAppendPrintf(sentry, "cpu_time = %f seconds\n", stats.cpu_time);
1341 storeAppendPrintf(sentry, "wall_time = %f seconds\n", stats.wall_time);
1342 storeAppendPrintf(sentry, "cpu_usage = %f%%\n", Math::doublePercent(stats.cpu_time, stats.wall_time));
090089c4 1343}
1344
5f5e883f 1345static void
b8083b1c 1346statRegisterWithCacheManager(void)
62ee09ca 1347{
8822ebee 1348 Mgr::RegisterAction("info", "General Runtime Information",
d9fc6862 1349 &Mgr::InfoAction::Create, 0, 1);
8822ebee 1350 Mgr::RegisterAction("service_times", "Service Times (Percentiles)",
d9fc6862 1351 &Mgr::ServiceTimesAction::Create, 0, 1);
8822ebee 1352 Mgr::RegisterAction("filedescriptors", "Process Filedescriptor Allocation",
d9fc6862 1353 fde::DumpStats, 0, 1);
8822ebee
AR
1354 Mgr::RegisterAction("objects", "All Cache Objects", stat_objects_get, 0, 0);
1355 Mgr::RegisterAction("vm_objects", "In-Memory and In-Transit Objects",
d9fc6862 1356 stat_vmobjects_get, 0, 0);
8822ebee 1357 Mgr::RegisterAction("io", "Server-side network read() size histograms",
d9fc6862 1358 &Mgr::IoAction::Create, 0, 1);
8822ebee 1359 Mgr::RegisterAction("counters", "Traffic and Resource Counters",
d9fc6862 1360 &Mgr::CountersAction::Create, 0, 1);
8822ebee 1361 Mgr::RegisterAction("peer_select", "Peer Selection Algorithms",
d9fc6862 1362 statPeerSelect, 0, 1);
8822ebee 1363 Mgr::RegisterAction("digest_stats", "Cache Digest and ICP blob",
d9fc6862 1364 statDigestBlob, 0, 1);
8822ebee 1365 Mgr::RegisterAction("5min", "5 Minute Average of Counters",
d9fc6862 1366 &Mgr::IntervalAction::Create5min, 0, 1);
8822ebee 1367 Mgr::RegisterAction("60min", "60 Minute Average of Counters",
d9fc6862 1368 &Mgr::IntervalAction::Create60min, 0, 1);
8822ebee 1369 Mgr::RegisterAction("utilization", "Cache Utilization",
d9fc6862 1370 statUtilization, 0, 1);
8822ebee 1371 Mgr::RegisterAction("histograms", "Full Histogram Counts",
d9fc6862 1372 statCountersHistograms, 0, 1);
8822ebee 1373 Mgr::RegisterAction("active_requests",
d9fc6862
A
1374 "Client-side Active Requests",
1375 statClientRequests, 0, 1);
2f1431ea 1376#if USE_AUTH
8822ebee 1377 Mgr::RegisterAction("username_cache",
d9fc6862
A
1378 "Active Cached Usernames",
1379 AuthUser::UsernameCacheStats, 0, 1);
2f1431ea 1380#endif
b8083b1c 1381#if DEBUG_OPENFD
8822ebee 1382 Mgr::RegisterAction("openfd_objects", "Objects with Swapout files open",
d9fc6862 1383 statOpenfdObj, 0, 0);
b8083b1c
FC
1384#endif
1385#if STAT_GRAPHS
8822ebee 1386 Mgr::RegisterAction("graph_variables", "Display cache metrics graphically",
d9fc6862 1387 statGraphDump, 0, 1);
b8083b1c 1388#endif
090089c4 1389}
f2908497 1390
5f5e883f
FC
1391
1392void
1393statInit(void)
1394{
1395 int i;
1396 debugs(18, 5, "statInit: Initializing...");
1397
1398 for (i = 0; i < N_COUNT_HIST; i++)
1399 statCountersInit(&CountHist[i]);
1400
1401 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
1402 statCountersInit(&CountHourHist[i]);
1403
1404 statCountersInit(&statCounter);
1405
1406 eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
1407
1408 ClientActiveRequests.head = NULL;
1409
1410 ClientActiveRequests.tail = NULL;
1411
1412 statRegisterWithCacheManager();
1413}
1414
f2908497 1415static void
1416statAvgTick(void *notused)
1417{
d5649d9f 1418 StatCounters *t = &CountHist[0];
1419 StatCounters *p = &CountHist[1];
83704487 1420 StatCounters *c = &statCounter;
62e76326 1421
f2908497 1422 struct rusage rusage;
b6a2f15e 1423 eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
20903cac 1424 squid_getrusage(&rusage);
1425 c->page_faults = rusage_pagefaults(&rusage);
1426 c->cputime = rusage_cputime(&rusage);
d5649d9f 1427 c->timestamp = current_time;
12cf1be2 1428 /* even if NCountHist is small, we already Init()ed the tail */
2ac76861 1429 statCountersClean(CountHist + N_COUNT_HIST - 1);
41d00cd3 1430 memmove(p, t, (N_COUNT_HIST - 1) * sizeof(StatCounters));
12cf1be2 1431 statCountersCopy(t, c);
d5649d9f 1432 NCountHist++;
a0f32775 1433
1434 if ((NCountHist % COUNT_INTERVAL) == 0) {
62e76326 1435 /* we have an hours worth of readings. store previous hour */
e053c141
FC
1436 StatCounters *t2 = &CountHourHist[0];
1437 StatCounters *p2 = &CountHourHist[1];
1438 StatCounters *c2 = &CountHist[N_COUNT_HIST - 1];
62e76326 1439 statCountersClean(CountHourHist + N_COUNT_HOUR_HIST - 1);
41d00cd3 1440 memmove(p2, t2, (N_COUNT_HOUR_HIST - 1) * sizeof(StatCounters));
e053c141 1441 statCountersCopy(t2, c2);
62e76326 1442 NCountHourHist++;
a0f32775 1443 }
62e76326 1444
b8a46de0 1445 if (Config.warnings.high_rptm > 0) {
04a28d46 1446 int i = (int) statPctileSvc(0.5, 20, PCTILE_HTTP);
62e76326 1447
1448 if (Config.warnings.high_rptm < i)
bf8fe701 1449 debugs(18, 0, "WARNING: Median response time is " << i << " milliseconds");
b8a46de0 1450 }
62e76326 1451
b8a46de0 1452 if (Config.warnings.high_pf) {
62e76326 1453 int i = (CountHist[0].page_faults - CountHist[1].page_faults);
1454 double dt = tvSubDsec(CountHist[0].timestamp, CountHist[1].timestamp);
1455
1456 if (i > 0 && dt > 0.0) {
1457 i /= (int) dt;
1458
1459 if (Config.warnings.high_pf < i)
bf8fe701 1460 debugs(18, 0, "WARNING: Page faults occuring at " << i << "/sec");
62e76326 1461 }
b8a46de0 1462 }
62e76326 1463
b8a46de0 1464 if (Config.warnings.high_memory) {
62e76326 1465 size_t i = 0;
b8a46de0 1466#if HAVE_MSTATS && HAVE_GNUMALLOC_H
62e76326 1467
1468 struct mstats ms = mstats();
1469 i = ms.bytes_total;
b8a46de0 1470#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
62e76326 1471
1472 struct mallinfo mp = mallinfo();
1473 i = mp.arena;
703cc8e8 1474#elif HAVE_SBRK
1475
1476 i = (size_t) ((char *) sbrk(0) - (char *) sbrk_start);
b8a46de0 1477#endif
62e76326 1478
1479 if (Config.warnings.high_memory < i)
bf8fe701 1480 debugs(18, 0, "WARNING: Memory usage at " << ((unsigned long int)(i >> 20)) << " MB");
b8a46de0 1481 }
20903cac 1482}
1483
12cf1be2 1484static void
2ac76861 1485statCountersInit(StatCounters * C)
20903cac 1486{
12cf1be2 1487 assert(C);
1d803566 1488 memset(C, 0, sizeof(*C));
12cf1be2 1489 C->timestamp = current_time;
1d803566 1490 statCountersInitSpecial(C);
1491}
1492
1493/* add special cases here as they arrive */
1494static void
2ac76861 1495statCountersInitSpecial(StatCounters * C)
1d803566 1496{
12cf1be2 1497 /*
1498 * HTTP svc_time hist is kept in milli-seconds; max of 3 hours.
1499 */
1500 statHistLogInit(&C->client_http.all_svc_time, 300, 0.0, 3600000.0 * 3.0);
1501 statHistLogInit(&C->client_http.miss_svc_time, 300, 0.0, 3600000.0 * 3.0);
1502 statHistLogInit(&C->client_http.nm_svc_time, 300, 0.0, 3600000.0 * 3.0);
7c9c84ad 1503 statHistLogInit(&C->client_http.nh_svc_time, 300, 0.0, 3600000.0 * 3.0);
12cf1be2 1504 statHistLogInit(&C->client_http.hit_svc_time, 300, 0.0, 3600000.0 * 3.0);
1505 /*
1506 * ICP svc_time hist is kept in micro-seconds; max of 1 minute.
1507 */
1508 statHistLogInit(&C->icp.query_svc_time, 300, 0.0, 1000000.0 * 60.0);
1509 statHistLogInit(&C->icp.reply_svc_time, 300, 0.0, 1000000.0 * 60.0);
1510 /*
1511 * DNS svc_time hist is kept in milli-seconds; max of 10 minutes.
1512 */
1513 statHistLogInit(&C->dns.svc_time, 300, 0.0, 60000.0 * 10.0);
a1e927f6 1514 /*
69c95dd3 1515 * Cache Digest Stuff
a1e927f6 1516 */
0c511722 1517 statHistEnumInit(&C->cd.on_xition_count, CacheDigestHashFuncCount);
c6ecdbc3 1518 statHistEnumInit(&C->comm_icp_incoming, INCOMING_ICP_MAX);
ef523f99 1519 statHistEnumInit(&C->comm_dns_incoming, INCOMING_DNS_MAX);
c6ecdbc3 1520 statHistEnumInit(&C->comm_http_incoming, INCOMING_HTTP_MAX);
b671cc68 1521 statHistIntInit(&C->select_fds_hist, 256); /* was SQUID_MAXFD, but it is way too much. It is OK to crop this statistics */
0f5607d9 1522}
1523
12cf1be2 1524/* add special cases here as they arrive */
5e29a294 1525static void
2ac76861 1526statCountersClean(StatCounters * C)
0f5607d9 1527{
12cf1be2 1528 assert(C);
1529 statHistClean(&C->client_http.all_svc_time);
1530 statHistClean(&C->client_http.miss_svc_time);
1531 statHistClean(&C->client_http.nm_svc_time);
7c9c84ad 1532 statHistClean(&C->client_http.nh_svc_time);
12cf1be2 1533 statHistClean(&C->client_http.hit_svc_time);
1534 statHistClean(&C->icp.query_svc_time);
1535 statHistClean(&C->icp.reply_svc_time);
1536 statHistClean(&C->dns.svc_time);
c135694e 1537 statHistClean(&C->cd.on_xition_count);
c6ecdbc3 1538 statHistClean(&C->comm_icp_incoming);
a56906d4 1539 statHistClean(&C->comm_dns_incoming);
c6ecdbc3 1540 statHistClean(&C->comm_http_incoming);
26d6ee93 1541 statHistClean(&C->select_fds_hist);
a7c05555 1542}
1543
12cf1be2 1544/* add special cases here as they arrive */
5e29a294 1545static void
2ac76861 1546statCountersCopy(StatCounters * dest, const StatCounters * orig)
45eb7f49 1547{
12cf1be2 1548 assert(dest && orig);
1d803566 1549 /* this should take care of all the fields, but "special" ones */
41d00cd3 1550 memcpy(dest, orig, sizeof(*dest));
1d803566 1551 /* prepare space where to copy special entries */
1552 statCountersInitSpecial(dest);
1553 /* now handle special cases */
1554 /* note: we assert that histogram capacities do not change */
12cf1be2 1555 statHistCopy(&dest->client_http.all_svc_time, &orig->client_http.all_svc_time);
1556 statHistCopy(&dest->client_http.miss_svc_time, &orig->client_http.miss_svc_time);
1557 statHistCopy(&dest->client_http.nm_svc_time, &orig->client_http.nm_svc_time);
7c9c84ad 1558 statHistCopy(&dest->client_http.nh_svc_time, &orig->client_http.nh_svc_time);
12cf1be2 1559 statHistCopy(&dest->client_http.hit_svc_time, &orig->client_http.hit_svc_time);
1560 statHistCopy(&dest->icp.query_svc_time, &orig->icp.query_svc_time);
1561 statHistCopy(&dest->icp.reply_svc_time, &orig->icp.reply_svc_time);
1562 statHistCopy(&dest->dns.svc_time, &orig->dns.svc_time);
c135694e 1563 statHistCopy(&dest->cd.on_xition_count, &orig->cd.on_xition_count);
c6ecdbc3 1564 statHistCopy(&dest->comm_icp_incoming, &orig->comm_icp_incoming);
1565 statHistCopy(&dest->comm_http_incoming, &orig->comm_http_incoming);
26d6ee93 1566 statHistCopy(&dest->select_fds_hist, &orig->select_fds_hist);
45eb7f49 1567}
1568
071a3ae7 1569static void
5d406e78 1570statCountersHistograms(StoreEntry * sentry)
071a3ae7 1571{
83704487 1572 StatCounters *f = &statCounter;
071a3ae7 1573 storeAppendPrintf(sentry, "client_http.all_svc_time histogram:\n");
1574 statHistDump(&f->client_http.all_svc_time, sentry, NULL);
1575 storeAppendPrintf(sentry, "client_http.miss_svc_time histogram:\n");
1576 statHistDump(&f->client_http.miss_svc_time, sentry, NULL);
1577 storeAppendPrintf(sentry, "client_http.nm_svc_time histogram:\n");
1578 statHistDump(&f->client_http.nm_svc_time, sentry, NULL);
7c9c84ad 1579 storeAppendPrintf(sentry, "client_http.nh_svc_time histogram:\n");
1580 statHistDump(&f->client_http.nh_svc_time, sentry, NULL);
071a3ae7 1581 storeAppendPrintf(sentry, "client_http.hit_svc_time histogram:\n");
1582 statHistDump(&f->client_http.hit_svc_time, sentry, NULL);
071a3ae7 1583 storeAppendPrintf(sentry, "icp.query_svc_time histogram:\n");
1584 statHistDump(&f->icp.query_svc_time, sentry, NULL);
1585 storeAppendPrintf(sentry, "icp.reply_svc_time histogram:\n");
1586 statHistDump(&f->icp.reply_svc_time, sentry, NULL);
1587 storeAppendPrintf(sentry, "dns.svc_time histogram:\n");
1588 statHistDump(&f->dns.svc_time, sentry, NULL);
2a73b7cb 1589 storeAppendPrintf(sentry, "select_fds_hist histogram:\n");
1590 statHistDump(&f->select_fds_hist, sentry, NULL);
071a3ae7 1591}
1592
12cf1be2 1593static void
1594statCountersDump(StoreEntry * sentry)
8822ebee
AR
1595{
1596 Mgr::CountersActionData stats;
1597 GetCountersStats(stats);
1598 DumpCountersStats(stats, sentry);
1599}
1600
1601void
1602GetCountersStats(Mgr::CountersActionData& stats)
7ae52c25 1603{
83704487 1604 StatCounters *f = &statCounter;
62e76326 1605
12cf1be2 1606 struct rusage rusage;
1607 squid_getrusage(&rusage);
1608 f->page_faults = rusage_pagefaults(&rusage);
1609 f->cputime = rusage_cputime(&rusage);
1610
8822ebee
AR
1611 stats.sample_time = f->timestamp;
1612 stats.client_http_requests = f->client_http.requests;
1613 stats.client_http_hits = f->client_http.hits;
1614 stats.client_http_errors = f->client_http.errors;
1615 stats.client_http_kbytes_in = f->client_http.kbytes_in.kb;
1616 stats.client_http_kbytes_out = f->client_http.kbytes_out.kb;
1617 stats.client_http_hit_kbytes_out = f->client_http.hit_kbytes_out.kb;
1618
1619 stats.server_all_requests = f->server.all.requests;
1620 stats.server_all_errors = f->server.all.errors;
1621 stats.server_all_kbytes_in = f->server.all.kbytes_in.kb;
1622 stats.server_all_kbytes_out = f->server.all.kbytes_out.kb;
1623
1624 stats.server_http_requests = f->server.http.requests;
1625 stats.server_http_errors = f->server.http.errors;
1626 stats.server_http_kbytes_in = f->server.http.kbytes_in.kb;
1627 stats.server_http_kbytes_out = f->server.http.kbytes_out.kb;
1628
1629 stats.server_ftp_requests = f->server.ftp.requests;
1630 stats.server_ftp_errors = f->server.ftp.errors;
1631 stats.server_ftp_kbytes_in = f->server.ftp.kbytes_in.kb;
1632 stats.server_ftp_kbytes_out = f->server.ftp.kbytes_out.kb;
1633
1634 stats.server_other_requests = f->server.other.requests;
1635 stats.server_other_errors = f->server.other.errors;
1636 stats.server_other_kbytes_in = f->server.other.kbytes_in.kb;
1637 stats.server_other_kbytes_out = f->server.other.kbytes_out.kb;
1638
1639 stats.icp_pkts_sent = f->icp.pkts_sent;
1640 stats.icp_pkts_recv = f->icp.pkts_recv;
1641 stats.icp_queries_sent = f->icp.queries_sent;
1642 stats.icp_replies_sent = f->icp.replies_sent;
1643 stats.icp_queries_recv = f->icp.queries_recv;
1644 stats.icp_replies_recv = f->icp.replies_recv;
1645 stats.icp_query_timeouts = f->icp.query_timeouts;
1646 stats.icp_replies_queued = f->icp.replies_queued;
1647 stats.icp_kbytes_sent = f->icp.kbytes_sent.kb;
1648 stats.icp_kbytes_recv = f->icp.kbytes_recv.kb;
1649 stats.icp_q_kbytes_sent = f->icp.q_kbytes_sent.kb;
1650 stats.icp_r_kbytes_sent = f->icp.r_kbytes_sent.kb;
1651 stats.icp_q_kbytes_recv = f->icp.q_kbytes_recv.kb;
1652 stats.icp_r_kbytes_recv = f->icp.r_kbytes_recv.kb;
1653
1654#if USE_CACHE_DIGESTS
1655
1656 stats.icp_times_used = f->icp.times_used;
1657 stats.cd_times_used = f->cd.times_used;
1658 stats.cd_msgs_sent = f->cd.msgs_sent;
1659 stats.cd_msgs_recv = f->cd.msgs_recv;
1660 stats.cd_memory = f->cd.memory.kb;
1661 stats.cd_local_memory = store_digest ? store_digest->mask_size / 1024 : 0;
1662 stats.cd_kbytes_sent = f->cd.kbytes_sent.kb;
1663 stats.cd_kbytes_recv = f->cd.kbytes_recv.kb;
1664#endif
1665
1666 stats.unlink_requests = f->unlink.requests;
1667 stats.page_faults = f->page_faults;
1668 stats.select_loops = f->select_loops;
1669 stats.cpu_time = f->cputime;
1670 stats.wall_time = tvSubDsec(f->timestamp, current_time);
1671 stats.swap_outs = f->swap.outs;
1672 stats.swap_ins = f->swap.ins;
1673 stats.swap_files_cleaned = f->swap.files_cleaned;
1674 stats.aborted_requests = f->aborted_requests;
1675}
1676
1677void
1678DumpCountersStats(Mgr::CountersActionData& stats, StoreEntry* sentry)
1679{
a0f32775 1680 storeAppendPrintf(sentry, "sample_time = %d.%d (%s)\n",
8822ebee
AR
1681 (int) stats.sample_time.tv_sec,
1682 (int) stats.sample_time.tv_usec,
1683 mkrfc1123(stats.sample_time.tv_sec));
1684 storeAppendPrintf(sentry, "client_http.requests = %.0f\n",
1685 stats.client_http_requests);
1686 storeAppendPrintf(sentry, "client_http.hits = %.0f\n",
1687 stats.client_http_hits);
1688 storeAppendPrintf(sentry, "client_http.errors = %.0f\n",
1689 stats.client_http_errors);
1690 storeAppendPrintf(sentry, "client_http.kbytes_in = %.0f\n",
1691 stats.client_http_kbytes_in);
1692 storeAppendPrintf(sentry, "client_http.kbytes_out = %.0f\n",
1693 stats.client_http_kbytes_out);
1694 storeAppendPrintf(sentry, "client_http.hit_kbytes_out = %.0f\n",
1695 stats.client_http_hit_kbytes_out);
1696
1697 storeAppendPrintf(sentry, "server.all.requests = %.0f\n",
1698 stats.server_all_requests);
1699 storeAppendPrintf(sentry, "server.all.errors = %.0f\n",
1700 stats.server_all_errors);
1701 storeAppendPrintf(sentry, "server.all.kbytes_in = %.0f\n",
1702 stats.server_all_kbytes_in);
1703 storeAppendPrintf(sentry, "server.all.kbytes_out = %.0f\n",
1704 stats.server_all_kbytes_out);
1705
1706 storeAppendPrintf(sentry, "server.http.requests = %.0f\n",
1707 stats.server_http_requests);
1708 storeAppendPrintf(sentry, "server.http.errors = %.0f\n",
1709 stats.server_http_errors);
1710 storeAppendPrintf(sentry, "server.http.kbytes_in = %.0f\n",
1711 stats.server_http_kbytes_in);
1712 storeAppendPrintf(sentry, "server.http.kbytes_out = %.0f\n",
1713 stats.server_http_kbytes_out);
1714
1715 storeAppendPrintf(sentry, "server.ftp.requests = %.0f\n",
1716 stats.server_ftp_requests);
1717 storeAppendPrintf(sentry, "server.ftp.errors = %.0f\n",
1718 stats.server_ftp_errors);
1719 storeAppendPrintf(sentry, "server.ftp.kbytes_in = %.0f\n",
1720 stats.server_ftp_kbytes_in);
1721 storeAppendPrintf(sentry, "server.ftp.kbytes_out = %.0f\n",
1722 stats.server_ftp_kbytes_out);
1723
1724 storeAppendPrintf(sentry, "server.other.requests = %.0f\n",
1725 stats.server_other_requests);
1726 storeAppendPrintf(sentry, "server.other.errors = %.0f\n",
1727 stats.server_other_errors);
1728 storeAppendPrintf(sentry, "server.other.kbytes_in = %.0f\n",
1729 stats.server_other_kbytes_in);
1730 storeAppendPrintf(sentry, "server.other.kbytes_out = %.0f\n",
1731 stats.server_other_kbytes_out);
1732
1733 storeAppendPrintf(sentry, "icp.pkts_sent = %.0f\n",
1734 stats.icp_pkts_sent);
1735 storeAppendPrintf(sentry, "icp.pkts_recv = %.0f\n",
1736 stats.icp_pkts_recv);
1737 storeAppendPrintf(sentry, "icp.queries_sent = %.0f\n",
1738 stats.icp_queries_sent);
1739 storeAppendPrintf(sentry, "icp.replies_sent = %.0f\n",
1740 stats.icp_replies_sent);
1741 storeAppendPrintf(sentry, "icp.queries_recv = %.0f\n",
1742 stats.icp_queries_recv);
1743 storeAppendPrintf(sentry, "icp.replies_recv = %.0f\n",
1744 stats.icp_replies_recv);
1745 storeAppendPrintf(sentry, "icp.query_timeouts = %.0f\n",
1746 stats.icp_query_timeouts);
1747 storeAppendPrintf(sentry, "icp.replies_queued = %.0f\n",
1748 stats.icp_replies_queued);
1749 storeAppendPrintf(sentry, "icp.kbytes_sent = %.0f\n",
1750 stats.icp_kbytes_sent);
1751 storeAppendPrintf(sentry, "icp.kbytes_recv = %.0f\n",
1752 stats.icp_kbytes_recv);
1753 storeAppendPrintf(sentry, "icp.q_kbytes_sent = %.0f\n",
1754 stats.icp_q_kbytes_sent);
1755 storeAppendPrintf(sentry, "icp.r_kbytes_sent = %.0f\n",
1756 stats.icp_r_kbytes_sent);
1757 storeAppendPrintf(sentry, "icp.q_kbytes_recv = %.0f\n",
1758 stats.icp_q_kbytes_recv);
1759 storeAppendPrintf(sentry, "icp.r_kbytes_recv = %.0f\n",
1760 stats.icp_r_kbytes_recv);
0567f2a6 1761
6cfa8966 1762#if USE_CACHE_DIGESTS
62e76326 1763
8822ebee
AR
1764 storeAppendPrintf(sentry, "icp.times_used = %.0f\n",
1765 stats.icp_times_used);
1766 storeAppendPrintf(sentry, "cd.times_used = %.0f\n",
1767 stats.cd_times_used);
1768 storeAppendPrintf(sentry, "cd.msgs_sent = %.0f\n",
1769 stats.cd_msgs_sent);
1770 storeAppendPrintf(sentry, "cd.msgs_recv = %.0f\n",
1771 stats.cd_msgs_recv);
1772 storeAppendPrintf(sentry, "cd.memory = %.0f\n",
1773 stats.cd_memory);
1774 storeAppendPrintf(sentry, "cd.local_memory = %.0f\n",
1775 stats.cd_local_memory);
1776 storeAppendPrintf(sentry, "cd.kbytes_sent = %.0f\n",
1777 stats.cd_kbytes_sent);
1778 storeAppendPrintf(sentry, "cd.kbytes_recv = %.0f\n",
1779 stats.cd_kbytes_recv);
0567f2a6 1780#endif
1781
8822ebee
AR
1782 storeAppendPrintf(sentry, "unlink.requests = %.0f\n",
1783 stats.unlink_requests);
1784 storeAppendPrintf(sentry, "page_faults = %.0f\n",
1785 stats.page_faults);
1786 storeAppendPrintf(sentry, "select_loops = %.0f\n",
1787 stats.select_loops);
12cf1be2 1788 storeAppendPrintf(sentry, "cpu_time = %f\n",
8822ebee 1789 stats.cpu_time);
12cf1be2 1790 storeAppendPrintf(sentry, "wall_time = %f\n",
8822ebee
AR
1791 stats.wall_time);
1792 storeAppendPrintf(sentry, "swap.outs = %.0f\n",
1793 stats.swap_outs);
1794 storeAppendPrintf(sentry, "swap.ins = %.0f\n",
1795 stats.swap_ins);
1796 storeAppendPrintf(sentry, "swap.files_cleaned = %.0f\n",
1797 stats.swap_files_cleaned);
1798 storeAppendPrintf(sentry, "aborted_requests = %.0f\n",
1799 stats.aborted_requests);
7ae52c25 1800}
1801
d2db411c 1802void
1803statFreeMemory(void)
1804{
1805 int i;
62e76326 1806
d2db411c 1807 for (i = 0; i < N_COUNT_HIST; i++)
62e76326 1808 statCountersClean(&CountHist[i]);
1809
d2db411c 1810 for (i = 0; i < N_COUNT_HOUR_HIST; i++)
62e76326 1811 statCountersClean(&CountHourHist[i]);
d2db411c 1812}
1813
5e29a294 1814static void
a1e927f6 1815statPeerSelect(StoreEntry * sentry)
1816{
6cfa8966 1817#if USE_CACHE_DIGESTS
83704487 1818 StatCounters *f = &statCounter;
a1e927f6 1819 peer *peer;
1820 const int tot_used = f->cd.times_used + f->icp.times_used;
1821
1822 /* totals */
1823 cacheDigestGuessStatsReport(&f->cd.guess, sentry, "all peers");
1824 /* per-peer */
1825 storeAppendPrintf(sentry, "\nPer-peer statistics:\n");
62e76326 1826
a1e927f6 1827 for (peer = getFirstPeer(); peer; peer = getNextPeer(peer)) {
62e76326 1828 if (peer->digest)
1829 peerDigestStatsReport(peer->digest, sentry);
1830 else
1831 storeAppendPrintf(sentry, "\nNo peer digest from %s\n", peer->host);
1832
1833 storeAppendPrintf(sentry, "\n");
a1e927f6 1834 }
1835
1836 storeAppendPrintf(sentry, "\nAlgorithm usage:\n");
1837 storeAppendPrintf(sentry, "Cache Digest: %7d (%3d%%)\n",
62e76326 1838 f->cd.times_used, xpercentInt(f->cd.times_used, tot_used));
a1e927f6 1839 storeAppendPrintf(sentry, "Icp: %7d (%3d%%)\n",
62e76326 1840 f->icp.times_used, xpercentInt(f->icp.times_used, tot_used));
a1e927f6 1841 storeAppendPrintf(sentry, "Total: %7d (%3d%%)\n",
62e76326 1842 tot_used, xpercentInt(tot_used, tot_used));
a1e927f6 1843#else
62e76326 1844
a1e927f6 1845 storeAppendPrintf(sentry, "peer digests are disabled; no stats is available.\n");
1846#endif
1847}
1848
1849static void
26b164ac 1850statDigestBlob(StoreEntry * sentry)
1851{
071a3ae7 1852 storeAppendPrintf(sentry, "\nCounters:\n");
1853 statCountersDump(sentry);
86e2a291 1854 storeAppendPrintf(sentry, "\n5 Min Averages:\n");
1855 statAvgDump(sentry, 5, 0);
071a3ae7 1856 storeAppendPrintf(sentry, "\nHistograms:\n");
1857 statCountersHistograms(sentry);
1858 storeAppendPrintf(sentry, "\nPeer Digests:\n");
26b164ac 1859 statPeerSelect(sentry);
588d9545 1860 storeAppendPrintf(sentry, "\nLocal Digest:\n");
26b164ac 1861 storeDigestReport(sentry);
1862}
1863
7d94ae33 1864static double
04a28d46 1865statPctileSvc(double pctile, int interval, int which)
a9113eb0 1866{
1867 StatCounters *f;
1868 StatCounters *l;
1869 double x;
f8d264b8 1870 assert(interval > 0);
62e76326 1871
f8d264b8 1872 if (interval > N_COUNT_HIST - 1)
62e76326 1873 interval = N_COUNT_HIST - 1;
1874
a9113eb0 1875 f = &CountHist[0];
62e76326 1876
a9113eb0 1877 l = &CountHist[interval];
62e76326 1878
ee1679df 1879 assert(f);
62e76326 1880
ee1679df 1881 assert(l);
62e76326 1882
a9113eb0 1883 switch (which) {
62e76326 1884
04a28d46 1885 case PCTILE_HTTP:
1886 x = statHistDeltaPctile(&l->client_http.all_svc_time, &f->client_http.all_svc_time, pctile);
62e76326 1887 break;
1888
04a28d46 1889 case PCTILE_HIT:
1890 x = statHistDeltaPctile(&l->client_http.hit_svc_time, &f->client_http.hit_svc_time, pctile);
62e76326 1891 break;
1892
04a28d46 1893 case PCTILE_MISS:
1894 x = statHistDeltaPctile(&l->client_http.miss_svc_time, &f->client_http.miss_svc_time, pctile);
62e76326 1895 break;
1896
04a28d46 1897 case PCTILE_NM:
1898 x = statHistDeltaPctile(&l->client_http.nm_svc_time, &f->client_http.nm_svc_time, pctile);
62e76326 1899 break;
1900
04a28d46 1901 case PCTILE_NH:
1902 x = statHistDeltaPctile(&l->client_http.nh_svc_time, &f->client_http.nh_svc_time, pctile);
62e76326 1903 break;
1904
04a28d46 1905 case PCTILE_ICP_QUERY:
1906 x = statHistDeltaPctile(&l->icp.query_svc_time, &f->icp.query_svc_time, pctile);
62e76326 1907 break;
1908
04a28d46 1909 case PCTILE_DNS:
1910 x = statHistDeltaPctile(&l->dns.svc_time, &f->dns.svc_time, pctile);
62e76326 1911 break;
1912
a9113eb0 1913 default:
bf8fe701 1914 debugs(49, 5, "statPctileSvc: unknown type.");
62e76326 1915 x = 0;
a9113eb0 1916 }
62e76326 1917
b87b92fb 1918 return x;
1919}
1920
451b07c5 1921StatCounters *
1922snmpStatGet(int minutes)
1923{
2ac76861 1924 return &CountHist[minutes];
451b07c5 1925}
01aebf31 1926
1f3c4622 1927int
1928stat5minClientRequests(void)
1929{
5999b776 1930 assert(N_COUNT_HIST > 5);
83704487 1931 return statCounter.client_http.requests - CountHist[5].client_http.requests;
1f3c4622 1932}
1933
49ad0a8c 1934static double
1935statCPUUsage(int minutes)
979533fa 1936{
49ad0a8c 1937 assert(minutes < N_COUNT_HIST);
a98bcbee 1938 return Math::doublePercent(CountHist[0].cputime - CountHist[minutes].cputime,
f9afa4fb 1939 tvSubDsec(CountHist[minutes].timestamp, CountHist[0].timestamp));
979533fa 1940}
01aebf31 1941
1d5b6d43 1942extern double
e1381638 1943statRequestHitRatio(int minutes)
491a980b 1944{
1945 assert(minutes < N_COUNT_HIST);
a98bcbee 1946 return Math::doublePercent(CountHist[0].client_http.hits -
f9afa4fb
A
1947 CountHist[minutes].client_http.hits,
1948 CountHist[0].client_http.requests -
1949 CountHist[minutes].client_http.requests);
491a980b 1950}
1951
4f4d1d6e 1952extern double
e1381638 1953statRequestHitMemoryRatio(int minutes)
4f4d1d6e 1954{
1955 assert(minutes < N_COUNT_HIST);
a98bcbee 1956 return Math::doublePercent(CountHist[0].client_http.mem_hits -
f9afa4fb
A
1957 CountHist[minutes].client_http.mem_hits,
1958 CountHist[0].client_http.hits -
1959 CountHist[minutes].client_http.hits);
4f4d1d6e 1960}
1961
1962extern double
e1381638 1963statRequestHitDiskRatio(int minutes)
4f4d1d6e 1964{
1965 assert(minutes < N_COUNT_HIST);
a98bcbee 1966 return Math::doublePercent(CountHist[0].client_http.disk_hits -
f9afa4fb
A
1967 CountHist[minutes].client_http.disk_hits,
1968 CountHist[0].client_http.hits -
1969 CountHist[minutes].client_http.hits);
4f4d1d6e 1970}
1971
1d5b6d43 1972extern double
e1381638 1973statByteHitRatio(int minutes)
491a980b 1974{
1975 size_t s;
1976 size_t c;
ac342231 1977#if USE_CACHE_DIGESTS
62e76326 1978
ac342231 1979 size_t cd;
1980#endif
1981 /* size_t might be unsigned */
491a980b 1982 assert(minutes < N_COUNT_HIST);
1983 c = CountHist[0].client_http.kbytes_out.kb - CountHist[minutes].client_http.kbytes_out.kb;
1984 s = CountHist[0].server.all.kbytes_in.kb - CountHist[minutes].server.all.kbytes_in.kb;
ac342231 1985#if USE_CACHE_DIGESTS
1986 /*
1987 * This ugly hack is here to prevent the user from seeing a
1988 * negative byte hit ratio. When we fetch a cache digest from
1989 * a neighbor, it gets treated like a cache miss because the
1990 * object is consumed internally. Thus, we subtract cache
1991 * digest bytes out before calculating the byte hit ratio.
1992 */
1993 cd = CountHist[0].cd.kbytes_recv.kb - CountHist[minutes].cd.kbytes_recv.kb;
62e76326 1994
49d7ce5f 1995 if (s < cd)
e4049756 1996 debugs(18, 1, "STRANGE: srv_kbytes=" << s << ", cd_kbytes=" << cd);
62e76326 1997
ac342231 1998 s -= cd;
62e76326 1999
ac342231 2000#endif
62e76326 2001
94e56ef7 2002 if (c > s)
a98bcbee 2003 return Math::doublePercent(c - s, c);
94e56ef7 2004 else
a98bcbee 2005 return (-1.0 * Math::doublePercent(s - c, c));
491a980b 2006}
2007
0f1bc304 2008static void
2009statClientRequests(StoreEntry * s)
2010{
2011 dlink_node *i;
59a1efb2 2012 ClientHttpRequest *http;
0f1bc304 2013 StoreEntry *e;
2014 int fd;
cc192b50 2015 char buf[MAX_IPSTRLEN];
62e76326 2016
0f1bc304 2017 for (i = ClientActiveRequests.head; i; i = i->next) {
f4bd6296 2018 const char *p = NULL;
59a1efb2 2019 http = static_cast<ClientHttpRequest *>(i->data);
62e76326 2020 assert(http);
9512de47 2021 ConnStateData * conn = http->getConn();
2022 storeAppendPrintf(s, "Connection: %p\n", conn);
62e76326 2023
85a4b153 2024 if (conn != NULL) {
62e76326 2025 fd = conn->fd;
47f6e231 2026 storeAppendPrintf(s, "\tFD %d, read %"PRId64", wrote %"PRId64"\n", fd,
62e76326 2027 fd_table[fd].bytes_read, fd_table[fd].bytes_written);
2028 storeAppendPrintf(s, "\tFD desc: %s\n", fd_table[fd].desc);
2029 storeAppendPrintf(s, "\tin: buf %p, offset %ld, size %ld\n",
2030 conn->in.buf, (long int) conn->in.notYetUsed, (long int) conn->in.allocatedSize);
2031 storeAppendPrintf(s, "\tpeer: %s:%d\n",
cc192b50 2032 conn->peer.NtoA(buf,MAX_IPSTRLEN),
2033 conn->peer.GetPort());
62e76326 2034 storeAppendPrintf(s, "\tme: %s:%d\n",
cc192b50 2035 conn->me.NtoA(buf,MAX_IPSTRLEN),
2036 conn->me.GetPort());
62e76326 2037 storeAppendPrintf(s, "\tnrequests: %d\n",
2038 conn->nrequests);
62e76326 2039 }
2040
2041 storeAppendPrintf(s, "uri %s\n", http->uri);
2042 storeAppendPrintf(s, "logType %s\n", log_tags[http->logType]);
2043 storeAppendPrintf(s, "out.offset %ld, out.size %lu\n",
2044 (long int) http->out.offset, (unsigned long int) http->out.size);
2045 storeAppendPrintf(s, "req_sz %ld\n", (long int) http->req_sz);
86a2f789 2046 e = http->storeEntry();
62e76326 2047 storeAppendPrintf(s, "entry %p/%s\n", e, e ? e->getMD5Text() : "N/A");
0655fa4d 2048#if 0
2049 /* Not a member anymore */
62e76326 2050 e = http->old_entry;
2051 storeAppendPrintf(s, "old_entry %p/%s\n", e, e ? e->getMD5Text() : "N/A");
0655fa4d 2052#endif
2053
62e76326 2054 storeAppendPrintf(s, "start %ld.%06d (%f seconds ago)\n",
9512de47 2055 (long int) http->start_time.tv_sec,
2056 (int) http->start_time.tv_usec,
2057 tvSubDsec(http->start_time, current_time));
2f1431ea 2058#if USE_AUTH
a33a428a 2059 if (http->request->auth_user_request != NULL)
d3f603c8 2060 p = http->request->auth_user_request->username();
2f1431ea
AJ
2061 else
2062#endif
74174c03
A
2063 if (http->request->extacl_user.defined()) {
2064 p = http->request->extacl_user.termedBuf();
2065 }
d3f603c8 2066
85a4b153 2067 if (!p && (conn != NULL && conn->rfc931[0]))
f4bd6296 2068 p = conn->rfc931;
d3f603c8 2069
f4bd6296 2070#if USE_SSL
2071
85a4b153 2072 if (!p && conn != NULL)
f4bd6296 2073 p = sslGetUserEmail(fd_table[conn->fd].ssl);
2074
2075#endif
2076
2077 if (!p)
2078 p = dash_str;
2079
2080 storeAppendPrintf(s, "username %s\n", p);
d3f603c8 2081
9a0a18de 2082#if USE_DELAY_POOLS
65a29f29 2083 storeAppendPrintf(s, "delay_pool %d\n", DelayId::DelayClient(http).pool());
8faa78e6 2084#endif
2085
62e76326 2086 storeAppendPrintf(s, "\n");
0f1bc304 2087 }
2088}
2089
01aebf31 2090#if STAT_GRAPHS
2091/*
2092 * urgh, i don't like these, but they do cut the amount of code down immensely
2093 */
2094
2095#define GRAPH_PER_MIN(Y) \
2096 for (i=0;i<(N_COUNT_HIST-2);i++) { \
79d15b05 2097 dt = tvSubDsec(CountHist[i+1].timestamp, CountHist[i].timestamp); \
01aebf31 2098 if (dt <= 0.0) \
2099 break; \
2100 storeAppendPrintf(e, "%lu,%0.2f:", \
2101 CountHist[i].timestamp.tv_sec, \
2102 ((CountHist[i].Y - CountHist[i+1].Y) / dt)); \
2103 }
2104
2105#define GRAPH_PER_HOUR(Y) \
2106 for (i=0;i<(N_COUNT_HOUR_HIST-2);i++) { \
79d15b05 2107 dt = tvSubDsec(CountHourHist[i+1].timestamp, CountHourHist[i].timestamp); \
01aebf31 2108 if (dt <= 0.0) \
2109 break; \
2110 storeAppendPrintf(e, "%lu,%0.2f:", \
2111 CountHourHist[i].timestamp.tv_sec, \
2112 ((CountHourHist[i].Y - CountHourHist[i+1].Y) / dt)); \
2113 }
2114
2115#define GRAPH_TITLE(X,Y) storeAppendPrintf(e,"%s\t%s\t",X,Y);
2116#define GRAPH_END storeAppendPrintf(e,"\n");
2117
2118#define GENGRAPH(X,Y,Z) \
2119 GRAPH_TITLE(Y,Z) \
2120 GRAPH_PER_MIN(X) \
2121 GRAPH_PER_HOUR(X) \
2122 GRAPH_END
2123
2124static void
2125statGraphDump(StoreEntry * e)
2126{
2127 int i;
2128 double dt;
2129
2130 GENGRAPH(client_http.requests, "client_http.requests", "Client HTTP requests/sec");
2131 GENGRAPH(client_http.hits, "client_http.hits", "Client HTTP hits/sec");
2132 GENGRAPH(client_http.errors, "client_http.errors", "Client HTTP errors/sec");
2133 GENGRAPH(client_http.kbytes_in.kb, "client_http.kbytes_in", "Client HTTP kbytes_in/sec");
2134 GENGRAPH(client_http.kbytes_out.kb, "client_http.kbytes_out", "Client HTTP kbytes_out/sec");
2135
2136 /* XXX todo: http median service times */
2137
2138 GENGRAPH(server.all.requests, "server.all.requests", "Server requests/sec");
2139 GENGRAPH(server.all.errors, "server.all.errors", "Server errors/sec");
2140 GENGRAPH(server.all.kbytes_in.kb, "server.all.kbytes_in", "Server total kbytes_in/sec");
2141 GENGRAPH(server.all.kbytes_out.kb, "server.all.kbytes_out", "Server total kbytes_out/sec");
2142
2143 GENGRAPH(server.http.requests, "server.http.requests", "Server HTTP requests/sec");
2144 GENGRAPH(server.http.errors, "server.http.errors", "Server HTTP errors/sec");
2145 GENGRAPH(server.http.kbytes_in.kb, "server.http.kbytes_in", "Server HTTP kbytes_in/sec");
2146 GENGRAPH(server.http.kbytes_out.kb, "server.http.kbytes_out", "Server HTTP kbytes_out/sec");
2147
2148 GENGRAPH(server.ftp.requests, "server.ftp.requests", "Server FTP requests/sec");
2149 GENGRAPH(server.ftp.errors, "server.ftp.errors", "Server FTP errors/sec");
2150 GENGRAPH(server.ftp.kbytes_in.kb, "server.ftp.kbytes_in", "Server FTP kbytes_in/sec");
2151 GENGRAPH(server.ftp.kbytes_out.kb, "server.ftp.kbytes_out", "Server FTP kbytes_out/sec");
2152
2153 GENGRAPH(server.other.requests, "server.other.requests", "Server other requests/sec");
2154 GENGRAPH(server.other.errors, "server.other.errors", "Server other errors/sec");
2155 GENGRAPH(server.other.kbytes_in.kb, "server.other.kbytes_in", "Server other kbytes_in/sec");
2156 GENGRAPH(server.other.kbytes_out.kb, "server.other.kbytes_out", "Server other kbytes_out/sec");
2157
2158 GENGRAPH(icp.pkts_sent, "icp.pkts_sent", "ICP packets sent/sec");
2159 GENGRAPH(icp.pkts_recv, "icp.pkts_recv", "ICP packets received/sec");
2160 GENGRAPH(icp.kbytes_sent.kb, "icp.kbytes_sent", "ICP kbytes_sent/sec");
2161 GENGRAPH(icp.kbytes_recv.kb, "icp.kbytes_recv", "ICP kbytes_received/sec");
2162
2163 /* XXX todo: icp median service times */
2164 /* XXX todo: dns median service times */
2165
2166 GENGRAPH(unlink.requests, "unlink.requests", "Cache File unlink requests/sec");
2167 GENGRAPH(page_faults, "page_faults", "System Page Faults/sec");
2168 GENGRAPH(select_loops, "select_loops", "System Select Loop calls/sec");
2169 GENGRAPH(cputime, "cputime", "CPU utilisation");
2170}
1afe05c5 2171
d96ceb8e 2172#endif /* STAT_GRAPHS */
2173
2d72d4fd 2174int
2175statMemoryAccounted(void)
2176{
d96ceb8e 2177 return memPoolsTotalAllocated();
2d72d4fd 2178}