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