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