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