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