4 * DEBUG: section 18 Cache Manager Statistics
5 * AUTHOR: Harvest Derived
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37 #include "StoreClient.h"
38 #include "auth/UserRequest.h"
39 #include "mgr/Registration.h"
41 #include "HttpRequest.h"
42 #include "MemObject.h"
48 #include "client_side_request.h"
49 #include "client_side.h"
51 #include "SquidMath.h"
52 #include "SquidTime.h"
53 #include "mgr/CountersAction.h"
54 #include "mgr/FunAction.h"
55 #include "mgr/InfoAction.h"
56 #include "mgr/IntervalAction.h"
57 #include "mgr/IoAction.h"
58 #include "mgr/ServiceTimesAction.h"
60 /* these are included because they expose stats calls */
61 /* TODO: provide a self registration mechanism for those classes
62 * to use during static construction
65 #include "StoreSearch.h"
67 #define DEBUG_OPENFD 1
69 typedef int STOBJFLT(const StoreEntry
*);
71 class StatObjectsState
77 StoreSearchPointer theSearch
;
80 CBDATA_CLASS2(StatObjectsState
);
85 static const char *describeStatuses(const StoreEntry
*);
86 static const char *describeTimestamps(const StoreEntry
*);
87 static void statAvgTick(void *notused
);
88 static void statAvgDump(StoreEntry
*, int minutes
, int hours
);
90 static void statGraphDump(StoreEntry
*);
92 static void statCountersInit(StatCounters
*);
93 static void statCountersInitSpecial(StatCounters
*);
94 static void statCountersClean(StatCounters
*);
95 static void statCountersCopy(StatCounters
* dest
, const StatCounters
* orig
);
96 static double statPctileSvc(double, int, int);
97 static void statStoreEntry(MemBuf
* mb
, StoreEntry
* e
);
98 static double statCPUUsage(int minutes
);
99 static OBJH stat_objects_get
;
100 static OBJH stat_vmobjects_get
;
102 static OBJH statOpenfdObj
;
104 static EVH statObjects
;
105 static OBJH statCountersDump
;
106 static OBJH statPeerSelect
;
107 static OBJH statDigestBlob
;
108 static OBJH statUtilization
;
109 static OBJH statCountersHistograms
;
110 static OBJH statClientRequests
;
111 void GetAvgStat(Mgr::IntervalActionData
& stats
, int minutes
, int hours
);
112 void DumpAvgStat(Mgr::IntervalActionData
& stats
, StoreEntry
* sentry
);
113 void GetInfo(Mgr::InfoActionData
& stats
);
114 void DumpInfo(Mgr::InfoActionData
& stats
, StoreEntry
* sentry
);
115 void DumpMallocStatistics(StoreEntry
* sentry
);
116 void GetCountersStats(Mgr::CountersActionData
& stats
);
117 void DumpCountersStats(Mgr::CountersActionData
& stats
, StoreEntry
* sentry
);
118 void GetServiceTimesStats(Mgr::ServiceTimesActionData
& stats
);
119 void DumpServiceTimesStats(Mgr::ServiceTimesActionData
& stats
, StoreEntry
* sentry
);
120 void GetIoStats(Mgr::IoActionData
& stats
);
121 void DumpIoStats(Mgr::IoActionData
& stats
, StoreEntry
* sentry
);
123 #if XMALLOC_STATISTICS
124 static void info_get_mallstat(int, int, int, void *);
125 static double xm_time
;
126 static double xm_deltat
;
129 StatCounters CountHist
[N_COUNT_HIST
];
130 static int NCountHist
= 0;
131 static StatCounters CountHourHist
[N_COUNT_HOUR_HIST
];
132 static int NCountHourHist
= 0;
133 CBDATA_CLASS_INIT(StatObjectsState
);
135 extern unsigned int mem_pool_alloc_calls
;
136 extern unsigned int mem_pool_free_calls
;
139 statUtilization(StoreEntry
* e
)
141 storeAppendPrintf(e
, "Cache Utilisation:\n");
142 storeAppendPrintf(e
, "\n");
143 storeAppendPrintf(e
, "Last 5 minutes:\n");
146 statAvgDump(e
, 5, 0);
148 storeAppendPrintf(e
, "(no values recorded yet)\n");
150 storeAppendPrintf(e
, "\n");
152 storeAppendPrintf(e
, "Last 15 minutes:\n");
154 if (NCountHist
>= 15)
155 statAvgDump(e
, 15, 0);
157 storeAppendPrintf(e
, "(no values recorded yet)\n");
159 storeAppendPrintf(e
, "\n");
161 storeAppendPrintf(e
, "Last hour:\n");
163 if (NCountHist
>= 60)
164 statAvgDump(e
, 60, 0);
166 storeAppendPrintf(e
, "(no values recorded yet)\n");
168 storeAppendPrintf(e
, "\n");
170 storeAppendPrintf(e
, "Last 8 hours:\n");
172 if (NCountHourHist
>= 8)
173 statAvgDump(e
, 0, 8);
175 storeAppendPrintf(e
, "(no values recorded yet)\n");
177 storeAppendPrintf(e
, "\n");
179 storeAppendPrintf(e
, "Last day:\n");
181 if (NCountHourHist
>= 24)
182 statAvgDump(e
, 0, 24);
184 storeAppendPrintf(e
, "(no values recorded yet)\n");
186 storeAppendPrintf(e
, "\n");
188 storeAppendPrintf(e
, "Last 3 days:\n");
190 if (NCountHourHist
>= 72)
191 statAvgDump(e
, 0, 72);
193 storeAppendPrintf(e
, "(no values recorded yet)\n");
195 storeAppendPrintf(e
, "\n");
197 storeAppendPrintf(e
, "Totals since cache startup:\n");
203 GetIoStats(Mgr::IoActionData
& stats
)
207 stats
.http_reads
= IOStats
.Http
.reads
;
209 for (i
= 0; i
< _iostats::histSize
; i
++) {
210 stats
.http_read_hist
[i
] = IOStats
.Http
.read_hist
[i
];
213 stats
.ftp_reads
= IOStats
.Ftp
.reads
;
215 for (i
= 0; i
< _iostats::histSize
; i
++) {
216 stats
.ftp_read_hist
[i
] = IOStats
.Ftp
.read_hist
[i
];
219 stats
.gopher_reads
= IOStats
.Gopher
.reads
;
221 for (i
= 0; i
< _iostats::histSize
; i
++) {
222 stats
.gopher_read_hist
[i
] = IOStats
.Gopher
.read_hist
[i
];
227 DumpIoStats(Mgr::IoActionData
& stats
, StoreEntry
* sentry
)
231 storeAppendPrintf(sentry
, "HTTP I/O\n");
232 storeAppendPrintf(sentry
, "number of reads: %.0f\n", stats
.http_reads
);
233 storeAppendPrintf(sentry
, "Read Histogram:\n");
235 for (i
= 0; i
< _iostats::histSize
; i
++) {
236 storeAppendPrintf(sentry
, "%5d-%5d: %9.0f %2.0f%%\n",
237 i
? (1 << (i
- 1)) + 1 : 1,
239 stats
.http_read_hist
[i
],
240 Math::doublePercent(stats
.http_read_hist
[i
], stats
.http_reads
));
243 storeAppendPrintf(sentry
, "\n");
244 storeAppendPrintf(sentry
, "FTP I/O\n");
245 storeAppendPrintf(sentry
, "number of reads: %.0f\n", stats
.ftp_reads
);
246 storeAppendPrintf(sentry
, "Read Histogram:\n");
248 for (i
= 0; i
< _iostats::histSize
; i
++) {
249 storeAppendPrintf(sentry
, "%5d-%5d: %9.0f %2.0f%%\n",
250 i
? (1 << (i
- 1)) + 1 : 1,
252 stats
.ftp_read_hist
[i
],
253 Math::doublePercent(stats
.ftp_read_hist
[i
], stats
.ftp_reads
));
256 storeAppendPrintf(sentry
, "\n");
257 storeAppendPrintf(sentry
, "Gopher I/O\n");
258 storeAppendPrintf(sentry
, "number of reads: %.0f\n", stats
.gopher_reads
);
259 storeAppendPrintf(sentry
, "Read Histogram:\n");
261 for (i
= 0; i
< _iostats::histSize
; i
++) {
262 storeAppendPrintf(sentry
, "%5d-%5d: %9.0f %2.0f%%\n",
263 i
? (1 << (i
- 1)) + 1 : 1,
265 stats
.gopher_read_hist
[i
],
266 Math::doublePercent(stats
.gopher_read_hist
[i
], stats
.gopher_reads
));
269 storeAppendPrintf(sentry
, "\n");
273 describeStatuses(const StoreEntry
* entry
)
275 LOCAL_ARRAY(char, buf
, 256);
276 snprintf(buf
, 256, "%-13s %-13s %-12s %-12s",
277 storeStatusStr
[entry
->store_status
],
278 memStatusStr
[entry
->mem_status
],
279 swapStatusStr
[entry
->swap_status
],
280 pingStatusStr
[entry
->ping_status
]);
285 storeEntryFlags(const StoreEntry
* entry
)
287 LOCAL_ARRAY(char, buf
, 256);
288 int flags
= (int) entry
->flags
;
292 if (EBIT_TEST(flags
, ENTRY_SPECIAL
))
293 strcat(buf
, "SPECIAL,");
295 if (EBIT_TEST(flags
, ENTRY_REVALIDATE
))
296 strcat(buf
, "REVALIDATE,");
298 if (EBIT_TEST(flags
, DELAY_SENDING
))
299 strcat(buf
, "DELAY_SENDING,");
301 if (EBIT_TEST(flags
, RELEASE_REQUEST
))
302 strcat(buf
, "RELEASE_REQUEST,");
304 if (EBIT_TEST(flags
, REFRESH_REQUEST
))
305 strcat(buf
, "REFRESH_REQUEST,");
307 if (EBIT_TEST(flags
, ENTRY_CACHABLE
))
308 strcat(buf
, "CACHABLE,");
310 if (EBIT_TEST(flags
, ENTRY_DISPATCHED
))
311 strcat(buf
, "DISPATCHED,");
313 if (EBIT_TEST(flags
, KEY_PRIVATE
))
314 strcat(buf
, "PRIVATE,");
316 if (EBIT_TEST(flags
, ENTRY_FWD_HDR_WAIT
))
317 strcat(buf
, "FWD_HDR_WAIT,");
319 if (EBIT_TEST(flags
, ENTRY_NEGCACHED
))
320 strcat(buf
, "NEGCACHED,");
322 if (EBIT_TEST(flags
, ENTRY_VALIDATED
))
323 strcat(buf
, "VALIDATED,");
325 if (EBIT_TEST(flags
, ENTRY_BAD_LENGTH
))
326 strcat(buf
, "BAD_LENGTH,");
328 if (EBIT_TEST(flags
, ENTRY_ABORTED
))
329 strcat(buf
, "ABORTED,");
331 if ((t
= strrchr(buf
, ',')))
338 describeTimestamps(const StoreEntry
* entry
)
340 LOCAL_ARRAY(char, buf
, 256);
341 snprintf(buf
, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
342 (int) entry
->timestamp
,
343 (int) entry
->lastref
,
344 (int) entry
->lastmod
,
345 (int) entry
->expires
);
350 statStoreEntry(MemBuf
* mb
, StoreEntry
* e
)
352 MemObject
*mem
= e
->mem_obj
;
353 mb
->Printf("KEY %s\n", e
->getMD5Text());
354 mb
->Printf("\t%s\n", describeStatuses(e
));
355 mb
->Printf("\t%s\n", storeEntryFlags(e
));
356 mb
->Printf("\t%s\n", describeTimestamps(e
));
357 mb
->Printf("\t%d locks, %d clients, %d refs\n",
359 storePendingNClients(e
),
361 mb
->Printf("\tSwap Dir %d, File %#08X\n",
362 e
->swap_dirn
, e
->swap_filen
);
370 /* process objects list */
372 statObjects(void *data
)
374 StatObjectsState
*state
= static_cast<StatObjectsState
*>(data
);
377 if (state
->theSearch
->isDone()) {
379 storeAppendPrintf(state
->sentry
, "} by kid%d\n\n", KidIdentifier
);
380 state
->sentry
->complete();
381 state
->sentry
->unlock();
384 } else if (EBIT_TEST(state
->sentry
->flags
, ENTRY_ABORTED
)) {
385 state
->sentry
->unlock();
388 } else if (state
->sentry
->checkDeferRead(-1)) {
389 eventAdd("statObjects", statObjects
, state
, 0.1, 1);
393 state
->sentry
->buffer();
394 size_t statCount
= 0;
398 while (statCount
++ < static_cast<size_t>(Config
.Store
.objectsPerBucket
) && state
->
400 e
= state
->theSearch
->currentItem();
402 if (state
->filter
&& 0 == state
->filter(e
))
405 statStoreEntry(&mb
, e
);
409 state
->sentry
->append(mb
.buf
, mb
.size
);
412 eventAdd("statObjects", statObjects
, state
, 0.0, 1);
416 statObjectsStart(StoreEntry
* sentry
, STOBJFLT
* filter
)
418 StatObjectsState
*state
= new StatObjectsState
;
419 state
->sentry
= sentry
;
420 state
->filter
= filter
;
423 state
->theSearch
= Store::Root().search(NULL
, NULL
);
425 eventAdd("statObjects", statObjects
, state
, 0.0, 1);
429 stat_objects_get(StoreEntry
* sentry
)
431 statObjectsStart(sentry
, NULL
);
435 statObjectsVmFilter(const StoreEntry
* e
)
437 return e
->mem_obj
? 1 : 0;
441 stat_vmobjects_get(StoreEntry
* sentry
)
443 statObjectsStart(sentry
, statObjectsVmFilter
);
448 statObjectsOpenfdFilter(const StoreEntry
* e
)
450 if (e
->mem_obj
== NULL
)
453 if (e
->mem_obj
->swapout
.sio
== NULL
)
460 statOpenfdObj(StoreEntry
* sentry
)
462 statObjectsStart(sentry
, statObjectsOpenfdFilter
);
467 #if XMALLOC_STATISTICS
469 info_get_mallstat(int size
, int number
, int oldnum
, void *data
)
471 StoreEntry
*sentry
= (StoreEntry
*)data
;
473 // format: "%12s %15s %6s %12s\n","Alloc Size","Count","Delta","Alloc/sec"
475 storeAppendPrintf(sentry
, "%12d %15d %6d %.1f\n", size
, number
, number
- oldnum
, xdiv((number
- oldnum
), xm_deltat
));
481 GetInfo(Mgr::InfoActionData
& stats
)
484 struct rusage rusage
;
487 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
490 #elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
495 runtime
= tvSubDsec(squid_start
, current_time
);
500 stats
.squid_start
= squid_start
;
502 stats
.current_time
= current_time
;
504 stats
.client_http_clients
= statCounter
.client_http
.clients
;
506 stats
.client_http_requests
= statCounter
.client_http
.requests
;
508 stats
.icp_pkts_recv
= statCounter
.icp
.pkts_recv
;
510 stats
.icp_pkts_sent
= statCounter
.icp
.pkts_sent
;
512 stats
.icp_replies_queued
= statCounter
.icp
.replies_queued
;
516 stats
.htcp_pkts_recv
= statCounter
.htcp
.pkts_recv
;
518 stats
.htcp_pkts_sent
= statCounter
.htcp
.pkts_sent
;
522 stats
.request_failure_ratio
= request_failure_ratio
;
524 stats
.avg_client_http_requests
= statCounter
.client_http
.requests
/ (runtime
/ 60.0);
526 stats
.avg_icp_messages
= (statCounter
.icp
.pkts_sent
+ statCounter
.icp
.pkts_recv
) / (runtime
/ 60.0);
528 stats
.select_loops
= statCounter
.select_loops
;
529 stats
.avg_loop_time
= 1000.0 * runtime
/ statCounter
.select_loops
;
531 stats
.request_hit_ratio5
= statRequestHitRatio(5);
532 stats
.request_hit_ratio60
= statRequestHitRatio(60);
534 stats
.byte_hit_ratio5
= statByteHitRatio(5);
535 stats
.byte_hit_ratio60
= statByteHitRatio(60);
537 stats
.request_hit_mem_ratio5
= statRequestHitMemoryRatio(5);
538 stats
.request_hit_mem_ratio60
= statRequestHitMemoryRatio(60);
540 stats
.request_hit_disk_ratio5
= statRequestHitDiskRatio(5);
541 stats
.request_hit_disk_ratio60
= statRequestHitDiskRatio(60);
543 stats
.store_swap_size
= store_swap_size
;
544 stats
.store_swap_max_size
= Store::Root().maxSize();
546 stats
.store_mem_size
= mem_node::StoreMemSize();
547 stats
.store_pages_max
= store_pages_max
;
548 stats
.store_mem_used
= mem_node::InUseCount();
550 stats
.objects_size
= n_disk_objects
? (double) store_swap_size
/ n_disk_objects
: 0.0;
552 stats
.unlink_requests
= statCounter
.unlink
.requests
;
554 stats
.http_requests5
= statPctileSvc(0.5, 5, PCTILE_HTTP
);
555 stats
.http_requests60
= statPctileSvc(0.5, 60, PCTILE_HTTP
);
557 stats
.cache_misses5
= statPctileSvc(0.5, 5, PCTILE_MISS
);
558 stats
.cache_misses60
= statPctileSvc(0.5, 60, PCTILE_MISS
);
560 stats
.cache_hits5
= statPctileSvc(0.5, 5, PCTILE_HIT
);
561 stats
.cache_hits60
= statPctileSvc(0.5, 60, PCTILE_HIT
);
563 stats
.near_hits5
= statPctileSvc(0.5, 5, PCTILE_NH
);
564 stats
.near_hits60
= statPctileSvc(0.5, 60, PCTILE_NH
);
566 stats
.not_modified_replies5
= statPctileSvc(0.5, 5, PCTILE_NM
);
567 stats
.not_modified_replies60
= statPctileSvc(0.5, 60, PCTILE_NM
);
569 stats
.dns_lookups5
= statPctileSvc(0.5, 5, PCTILE_DNS
);
570 stats
.dns_lookups60
= statPctileSvc(0.5, 60, PCTILE_DNS
);
572 stats
.icp_queries5
= statPctileSvc(0.5, 5, PCTILE_ICP_QUERY
);
573 stats
.icp_queries60
= statPctileSvc(0.5, 60, PCTILE_ICP_QUERY
);
575 squid_getrusage(&rusage
);
576 cputime
= rusage_cputime(&rusage
);
578 stats
.up_time
= runtime
;
579 stats
.cpu_time
= cputime
;
580 stats
.cpu_usage
= Math::doublePercent(cputime
, runtime
);
581 stats
.cpu_usage5
= statCPUUsage(5);
582 stats
.cpu_usage60
= statCPUUsage(60);
586 stats
.proc_data_seg
= ((char *) sbrk(0) - (char *) sbrk_start
);
590 stats
.maxrss
= rusage_maxrss(&rusage
);
592 stats
.page_faults
= rusage_pagefaults(&rusage
);
594 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
598 stats
.ms_bytes_total
= ms
.bytes_total
;
600 stats
.ms_bytes_free
= ms
.bytes_free
;
602 #elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
606 stats
.mp_arena
= mp
.arena
;
608 stats
.mp_uordblks
= mp
.uordblks
;
609 stats
.mp_ordblks
= mp
.ordblks
;
611 stats
.mp_usmblks
= mp
.usmblks
;
612 stats
.mp_smblks
= mp
.smblks
;
614 stats
.mp_hblkhd
= mp
.hblkhd
;
615 stats
.mp_hblks
= mp
.hblks
;
617 stats
.mp_fsmblks
= mp
.fsmblks
;
619 stats
.mp_fordblks
= mp
.fordblks
;
621 #if HAVE_STRUCT_MALLINFO_MXFAST
623 stats
.mp_mxfast
= mp
.mxfast
;
625 stats
.mp_nlblks
= mp
.nlblks
;
627 stats
.mp_grain
= mp
.grain
;
629 stats
.mp_uordbytes
= mp
.uordbytes
;
631 stats
.mp_allocated
= mp
.allocated
;
633 stats
.mp_treeoverhead
= mp
.treeoverhead
;
635 #endif /* HAVE_STRUCT_MALLINFO_MXFAST */
636 #endif /* HAVE_MALLINFO */
638 stats
.total_accounted
= statMemoryAccounted();
641 MemPoolGlobalStats mp_stats
;
642 memPoolGetGlobalStats(&mp_stats
);
643 #if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
645 stats
.mem_pool_allocated
= mp_stats
.TheMeter
->alloc
.level
;
648 stats
.gb_freed_count
= mp_stats
.TheMeter
->gb_saved
.count
;
649 stats
.gb_freed_count
= mp_stats
.TheMeter
->gb_freed
.count
;
652 stats
.max_fd
= Squid_MaxFD
;
653 stats
.biggest_fd
= Biggest_FD
;
654 stats
.number_fd
= Number_FD
;
655 stats
.opening_fd
= Opening_FD
;
656 stats
.num_fd_free
= fdNFree();
657 stats
.reserved_fd
= RESERVED_FD
;
658 stats
.store_open_disk_fd
= store_open_disk_fd
;
660 stats
.store_entries
= StoreEntry::inUseCount();
661 stats
.store_mem_entries
= MemObject::inUseCount();
662 stats
.hot_obj_count
= hot_obj_count
;
663 stats
.n_disk_objects
= n_disk_objects
;
667 DumpInfo(Mgr::InfoActionData
& stats
, StoreEntry
* sentry
)
669 storeAppendPrintf(sentry
, "Squid Object Cache: Version %s\n",
674 if (WIN32_run_mode
== _WIN_SQUID_RUN_MODE_SERVICE
) {
675 storeAppendPrintf(sentry
,"\nRunning as %s Windows System Service on %s\n",
676 WIN32_Service_name
, WIN32_OS_string
);
677 storeAppendPrintf(sentry
,"Service command line is: %s\n", WIN32_Service_Command_Line
);
679 storeAppendPrintf(sentry
,"Running on %s\n",WIN32_OS_string
);
683 storeAppendPrintf(sentry
, "Start Time:\t%s\n",
684 mkrfc1123(stats
.squid_start
.tv_sec
));
686 storeAppendPrintf(sentry
, "Current Time:\t%s\n",
687 mkrfc1123(stats
.current_time
.tv_sec
));
689 storeAppendPrintf(sentry
, "Connection information for %s:\n",APP_SHORTNAME
);
691 storeAppendPrintf(sentry
, "\tNumber of clients accessing cache:\t%.0f\n",
692 stats
.client_http_clients
);
694 storeAppendPrintf(sentry
, "\tNumber of HTTP requests received:\t%.0f\n",
695 stats
.client_http_requests
);
697 storeAppendPrintf(sentry
, "\tNumber of ICP messages received:\t%.0f\n",
698 stats
.icp_pkts_recv
);
700 storeAppendPrintf(sentry
, "\tNumber of ICP messages sent:\t%.0f\n",
701 stats
.icp_pkts_sent
);
703 storeAppendPrintf(sentry
, "\tNumber of queued ICP replies:\t%.0f\n",
704 stats
.icp_replies_queued
);
708 storeAppendPrintf(sentry
, "\tNumber of HTCP messages received:\t%.0f\n",
709 stats
.htcp_pkts_recv
);
711 storeAppendPrintf(sentry
, "\tNumber of HTCP messages sent:\t%.0f\n",
712 stats
.htcp_pkts_sent
);
716 double fct
= stats
.count
> 1 ? stats
.count
: 1.0;
717 storeAppendPrintf(sentry
, "\tRequest failure ratio:\t%5.2f\n",
718 stats
.request_failure_ratio
/ fct
);
720 storeAppendPrintf(sentry
, "\tAverage HTTP requests per minute since start:\t%.1f\n",
721 stats
.avg_client_http_requests
/ fct
);
723 storeAppendPrintf(sentry
, "\tAverage ICP messages per minute since start:\t%.1f\n",
724 stats
.avg_icp_messages
/ fct
);
726 storeAppendPrintf(sentry
, "\tSelect loop called: %.0f times, %0.3f ms avg\n",
727 stats
.select_loops
, stats
.avg_loop_time
/ fct
);
729 storeAppendPrintf(sentry
, "Cache information for %s:\n",APP_SHORTNAME
);
731 storeAppendPrintf(sentry
, "\tHits as %% of all requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
732 stats
.request_hit_ratio5
/ fct
,
733 stats
.request_hit_ratio60
/ fct
);
735 storeAppendPrintf(sentry
, "\tHits as %% of bytes sent:\t5min: %3.1f%%, 60min: %3.1f%%\n",
736 stats
.byte_hit_ratio5
/ fct
,
737 stats
.byte_hit_ratio60
/ fct
);
739 storeAppendPrintf(sentry
, "\tMemory hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
740 stats
.request_hit_mem_ratio5
/ fct
,
741 stats
.request_hit_mem_ratio60
/ fct
);
743 storeAppendPrintf(sentry
, "\tDisk hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
744 stats
.request_hit_disk_ratio5
/ fct
,
745 stats
.request_hit_disk_ratio60
/ fct
);
747 storeAppendPrintf(sentry
, "\tStorage Swap size:\t%.0f KB\n",
748 stats
.store_swap_size
/ 1024);
750 storeAppendPrintf(sentry
, "\tStorage Swap capacity:\t%4.1f%% used, %4.1f%% free\n",
751 Math::doublePercent(stats
.store_swap_size
, stats
.store_swap_max_size
),
752 Math::doublePercent(stats
.store_swap_max_size
- stats
.store_swap_size
, stats
.store_swap_max_size
));
754 storeAppendPrintf(sentry
, "\tStorage Mem size:\t%.0f KB\n",
755 stats
.store_mem_size
/ 1024);
757 const double mFree
= max(0.0, stats
.store_pages_max
-stats
.store_mem_used
);
758 storeAppendPrintf(sentry
, "\tStorage Mem capacity:\t%4.1f%% used, %4.1f%% free\n",
759 Math::doublePercent(stats
.store_mem_used
, stats
.store_pages_max
),
760 Math::doublePercent(mFree
, stats
.store_pages_max
));
762 storeAppendPrintf(sentry
, "\tMean Object Size:\t%0.2f KB\n",
763 stats
.objects_size
/ fct
);
765 storeAppendPrintf(sentry
, "\tRequests given to unlinkd:\t%.0f\n",
766 stats
.unlink_requests
);
768 storeAppendPrintf(sentry
, "Median Service Times (seconds) 5 min 60 min:\n");
770 fct
= stats
.count
> 1 ? stats
.count
* 1000.0 : 1000.0;
771 storeAppendPrintf(sentry
, "\tHTTP Requests (All): %8.5f %8.5f\n",
772 stats
.http_requests5
/ fct
,
773 stats
.http_requests60
/ fct
);
775 storeAppendPrintf(sentry
, "\tCache Misses: %8.5f %8.5f\n",
776 stats
.cache_misses5
/ fct
,
777 stats
.cache_misses60
/ fct
);
779 storeAppendPrintf(sentry
, "\tCache Hits: %8.5f %8.5f\n",
780 stats
.cache_hits5
/ fct
,
781 stats
.cache_hits60
/ fct
);
783 storeAppendPrintf(sentry
, "\tNear Hits: %8.5f %8.5f\n",
784 stats
.near_hits5
/ fct
,
785 stats
.near_hits60
/ fct
);
787 storeAppendPrintf(sentry
, "\tNot-Modified Replies: %8.5f %8.5f\n",
788 stats
.not_modified_replies5
/ fct
,
789 stats
.not_modified_replies60
/ fct
);
791 storeAppendPrintf(sentry
, "\tDNS Lookups: %8.5f %8.5f\n",
792 stats
.dns_lookups5
/ fct
,
793 stats
.dns_lookups60
/ fct
);
795 fct
= stats
.count
> 1 ? stats
.count
* 1000000.0 : 1000000.0;
796 storeAppendPrintf(sentry
, "\tICP Queries: %8.5f %8.5f\n",
797 stats
.icp_queries5
/ fct
,
798 stats
.icp_queries60
/ fct
);
800 storeAppendPrintf(sentry
, "Resource usage for %s:\n", APP_SHORTNAME
);
802 storeAppendPrintf(sentry
, "\tUP Time:\t%.3f seconds\n", stats
.up_time
);
804 storeAppendPrintf(sentry
, "\tCPU Time:\t%.3f seconds\n", stats
.cpu_time
);
806 storeAppendPrintf(sentry
, "\tCPU Usage:\t%.2f%%\n",
809 storeAppendPrintf(sentry
, "\tCPU Usage, 5 minute avg:\t%.2f%%\n",
812 storeAppendPrintf(sentry
, "\tCPU Usage, 60 minute avg:\t%.2f%%\n",
817 storeAppendPrintf(sentry
, "\tProcess Data Segment Size via sbrk(): %.0f KB\n",
818 stats
.proc_data_seg
/ 1024);
822 storeAppendPrintf(sentry
, "\tMaximum Resident Size: %.0f KB\n",
825 storeAppendPrintf(sentry
, "\tPage faults with physical i/o: %.0f\n",
828 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
830 storeAppendPrintf(sentry
, "Memory usage for %s via mstats():\n",APP_SHORTNAME
);
832 storeAppendPrintf(sentry
, "\tTotal space in arena: %6.0f KB\n",
833 stats
.ms_bytes_total
/ 1024);
835 storeAppendPrintf(sentry
, "\tTotal free: %6.0f KB %.0f%%\n",
836 stats
.ms_bytes_free
/ 1024,
837 Math::doublePercent(stats
.ms_bytes_free
, stats
.ms_bytes_total
));
839 #elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
841 storeAppendPrintf(sentry
, "Memory usage for %s via mallinfo():\n",APP_SHORTNAME
);
843 storeAppendPrintf(sentry
, "\tTotal space in arena: %6.0f KB\n",
844 stats
.mp_arena
/ 1024);
846 storeAppendPrintf(sentry
, "\tOrdinary blocks: %6.0f KB %6.0f blks\n",
847 stats
.mp_uordblks
/ 1024, stats
.mp_ordblks
);
849 storeAppendPrintf(sentry
, "\tSmall blocks: %6.0f KB %6.0f blks\n",
850 stats
.mp_usmblks
/ 1024, stats
.mp_smblks
);
852 storeAppendPrintf(sentry
, "\tHolding blocks: %6.0f KB %6.0f blks\n",
853 stats
.mp_hblkhd
/ 1024, stats
.mp_hblks
);
855 storeAppendPrintf(sentry
, "\tFree Small blocks: %6.0f KB\n",
856 stats
.mp_fsmblks
/ 1024);
858 storeAppendPrintf(sentry
, "\tFree Ordinary blocks: %6.0f KB\n",
859 stats
.mp_fordblks
/ 1024);
861 double t
= stats
.mp_fsmblks
+ stats
.mp_fordblks
;
863 storeAppendPrintf(sentry
, "\tTotal in use: %6.0f KB %.0f%%\n",
864 t
/ 1024, Math::doublePercent(t
, stats
.mp_arena
+ stats
.mp_hblkhd
));
866 t
= stats
.mp_fsmblks
+ stats
.mp_fordblks
;
868 storeAppendPrintf(sentry
, "\tTotal free: %6.0f KB %.0f%%\n",
869 t
/ 1024, Math::doublePercent(t
, stats
.mp_arena
+ stats
.mp_hblkhd
));
871 t
= stats
.mp_arena
+ stats
.mp_hblkhd
;
873 storeAppendPrintf(sentry
, "\tTotal size: %6.0f KB\n",
876 #if HAVE_STRUCT_MALLINFO_MXFAST
878 storeAppendPrintf(sentry
, "\tmax size of small blocks:\t%.0f\n", stats
.mp_mxfast
);
880 storeAppendPrintf(sentry
, "\tnumber of small blocks in a holding block:\t%.0f\n",
883 storeAppendPrintf(sentry
, "\tsmall block rounding factor:\t%.0f\n", stats
.mp_grain
);
885 storeAppendPrintf(sentry
, "\tspace (including overhead) allocated in ord. blks:\t%.0f\n"
886 ,stats
.mp_uordbytes
);
888 storeAppendPrintf(sentry
, "\tnumber of ordinary blocks allocated:\t%.0f\n",
891 storeAppendPrintf(sentry
, "\tbytes used in maintaining the free tree:\t%.0f\n",
892 stats
.mp_treeoverhead
);
894 #endif /* HAVE_STRUCT_MALLINFO_MXFAST */
895 #endif /* HAVE_MALLINFO */
897 storeAppendPrintf(sentry
, "Memory accounted for:\n");
899 #if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
901 storeAppendPrintf(sentry
, "\tTotal accounted: %6.0f KB %3.0f%%\n",
902 stats
.total_accounted
/ 1024, Math::doublePercent(stats
.total_accounted
, t
));
906 storeAppendPrintf(sentry
, "\tTotal accounted: %6.0f KB\n",
907 stats
.total_accounted
/ 1024);
911 MemPoolGlobalStats mp_stats
;
912 memPoolGetGlobalStats(&mp_stats
);
913 #if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
915 storeAppendPrintf(sentry
, "\tmemPool accounted: %6.0f KB %3.0f%%\n",
916 stats
.mem_pool_allocated
/ 1024,
917 Math::doublePercent(stats
.mem_pool_allocated
, t
));
919 const double iFree
= max(0.0, t
- stats
.mem_pool_allocated
);
920 storeAppendPrintf(sentry
, "\tmemPool unaccounted: %6.0f KB %3.0f%%\n",
921 (t
- stats
.mem_pool_allocated
) / 1024,
922 Math::doublePercent(iFree
, t
));
925 storeAppendPrintf(sentry
, "\tmemPoolAlloc calls: %9.0f\n",
926 stats
.gb_saved_count
);
927 storeAppendPrintf(sentry
, "\tmemPoolFree calls: %9.0f\n",
928 stats
.gb_freed_count
);
931 storeAppendPrintf(sentry
, "File descriptor usage for %s:\n", APP_SHORTNAME
);
932 storeAppendPrintf(sentry
, "\tMaximum number of file descriptors: %4.0f\n",
934 storeAppendPrintf(sentry
, "\tLargest file desc currently in use: %4.0f\n",
936 storeAppendPrintf(sentry
, "\tNumber of file desc currently in use: %4.0f\n",
938 storeAppendPrintf(sentry
, "\tFiles queued for open: %4.0f\n",
940 storeAppendPrintf(sentry
, "\tAvailable number of file descriptors: %4.0f\n",
942 storeAppendPrintf(sentry
, "\tReserved number of file descriptors: %4.0f\n",
944 storeAppendPrintf(sentry
, "\tStore Disk files open: %4.0f\n",
945 stats
.store_open_disk_fd
);
947 storeAppendPrintf(sentry
, "Internal Data Structures:\n");
948 storeAppendPrintf(sentry
, "\t%6.0f StoreEntries\n",
949 stats
.store_entries
);
950 storeAppendPrintf(sentry
, "\t%6.0f StoreEntries with MemObjects\n",
951 stats
.store_mem_entries
);
952 storeAppendPrintf(sentry
, "\t%6.0f Hot Object Cache Items\n",
953 stats
.hot_obj_count
);
954 storeAppendPrintf(sentry
, "\t%6.0f on-disk objects\n",
955 stats
.n_disk_objects
);
959 DumpMallocStatistics(StoreEntry
* sentry
)
961 #if XMALLOC_STATISTICS
963 xm_deltat
= current_dtime
- xm_time
;
964 xm_time
= current_dtime
;
965 storeAppendPrintf(sentry
, "\nMemory allocation statistics\n");
966 storeAppendPrintf(sentry
, "%12s %15s %6s %12s\n","Alloc Size","Count","Delta","Alloc/sec");
967 malloc_statistics(info_get_mallstat
, sentry
);
972 GetServiceTimesStats(Mgr::ServiceTimesActionData
& stats
)
974 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
975 double p
= (i
+ 1) * 5 / 100.0;
976 stats
.http_requests5
[i
] = statPctileSvc(p
, 5, PCTILE_HTTP
);
977 stats
.http_requests60
[i
] = statPctileSvc(p
, 60, PCTILE_HTTP
);
979 stats
.cache_misses5
[i
] = statPctileSvc(p
, 5, PCTILE_MISS
);
980 stats
.cache_misses60
[i
] = statPctileSvc(p
, 60, PCTILE_MISS
);
982 stats
.cache_hits5
[i
] = statPctileSvc(p
, 5, PCTILE_HIT
);
983 stats
.cache_hits60
[i
] = statPctileSvc(p
, 60, PCTILE_HIT
);
985 stats
.near_hits5
[i
] = statPctileSvc(p
, 5, PCTILE_NH
);
986 stats
.near_hits60
[i
] = statPctileSvc(p
, 60, PCTILE_NH
);
988 stats
.not_modified_replies5
[i
] = statPctileSvc(p
, 5, PCTILE_NM
);
989 stats
.not_modified_replies60
[i
] = statPctileSvc(p
, 60, PCTILE_NM
);
991 stats
.dns_lookups5
[i
] = statPctileSvc(p
, 5, PCTILE_DNS
);
992 stats
.dns_lookups60
[i
] = statPctileSvc(p
, 60, PCTILE_DNS
);
994 stats
.icp_queries5
[i
] = statPctileSvc(p
, 5, PCTILE_ICP_QUERY
);
995 stats
.icp_queries60
[i
] = statPctileSvc(p
, 60, PCTILE_ICP_QUERY
);
1000 DumpServiceTimesStats(Mgr::ServiceTimesActionData
& stats
, StoreEntry
* sentry
)
1002 storeAppendPrintf(sentry
, "Service Time Percentiles 5 min 60 min:\n");
1003 double fct
= stats
.count
> 1 ? stats
.count
* 1000.0 : 1000.0;
1004 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1005 storeAppendPrintf(sentry
, "\tHTTP Requests (All): %2d%% %8.5f %8.5f\n",
1007 stats
.http_requests5
[i
] / fct
,
1008 stats
.http_requests60
[i
] / fct
);
1010 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1011 storeAppendPrintf(sentry
, "\tCache Misses: %2d%% %8.5f %8.5f\n",
1013 stats
.cache_misses5
[i
] / fct
,
1014 stats
.cache_misses60
[i
] / fct
);
1016 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1017 storeAppendPrintf(sentry
, "\tCache Hits: %2d%% %8.5f %8.5f\n",
1019 stats
.cache_hits5
[i
] / fct
,
1020 stats
.cache_hits60
[i
] / fct
);
1022 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1023 storeAppendPrintf(sentry
, "\tNear Hits: %2d%% %8.5f %8.5f\n",
1025 stats
.near_hits5
[i
] / fct
,
1026 stats
.near_hits60
[i
] / fct
);
1028 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1029 storeAppendPrintf(sentry
, "\tNot-Modified Replies: %2d%% %8.5f %8.5f\n",
1031 stats
.not_modified_replies5
[i
] / fct
,
1032 stats
.not_modified_replies60
[i
] / fct
);
1034 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1035 storeAppendPrintf(sentry
, "\tDNS Lookups: %2d%% %8.5f %8.5f\n",
1037 stats
.dns_lookups5
[i
] / fct
,
1038 stats
.dns_lookups60
[i
] / fct
);
1040 fct
= stats
.count
> 1 ? stats
.count
* 1000000.0 : 1000000.0;
1041 for (int i
= 0; i
< Mgr::ServiceTimesActionData::seriesSize
; ++i
) {
1042 storeAppendPrintf(sentry
, "\tICP Queries: %2d%% %8.5f %8.5f\n",
1044 stats
.icp_queries5
[i
] / fct
,
1045 stats
.icp_queries60
[i
] / fct
);
1050 statAvgDump(StoreEntry
* sentry
, int minutes
, int hours
)
1052 Mgr::IntervalActionData stats
;
1053 GetAvgStat(stats
, minutes
, hours
);
1054 DumpAvgStat(stats
, sentry
);
1057 #define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
1059 GetAvgStat(Mgr::IntervalActionData
& stats
, int minutes
, int hours
)
1065 assert(N_COUNT_HIST
> 1);
1066 assert(minutes
> 0 || hours
> 0);
1070 if (minutes
> 0 && hours
== 0) {
1071 /* checking minute readings ... */
1073 if (minutes
> N_COUNT_HIST
- 1)
1074 minutes
= N_COUNT_HIST
- 1;
1076 l
= &CountHist
[minutes
];
1077 } else if (minutes
== 0 && hours
> 0) {
1078 /* checking hour readings ... */
1080 if (hours
> N_COUNT_HOUR_HIST
- 1)
1081 hours
= N_COUNT_HOUR_HIST
- 1;
1083 l
= &CountHourHist
[hours
];
1085 debugs(18, 1, "statAvgDump: Invalid args, minutes=" << minutes
<< ", hours=" << hours
);
1089 dt
= tvSubDsec(l
->timestamp
, f
->timestamp
);
1090 ct
= f
->cputime
- l
->cputime
;
1092 stats
.sample_start_time
= l
->timestamp
;
1093 stats
.sample_end_time
= f
->timestamp
;
1095 stats
.client_http_requests
= XAVG(client_http
.requests
);
1096 stats
.client_http_hits
= XAVG(client_http
.hits
);
1097 stats
.client_http_errors
= XAVG(client_http
.errors
);
1098 stats
.client_http_kbytes_in
= XAVG(client_http
.kbytes_in
.kb
);
1099 stats
.client_http_kbytes_out
= XAVG(client_http
.kbytes_out
.kb
);
1101 stats
.client_http_all_median_svc_time
= statHistDeltaMedian(&l
->client_http
.all_svc_time
,
1102 &f
->client_http
.all_svc_time
) / 1000.0;
1103 stats
.client_http_miss_median_svc_time
= statHistDeltaMedian(&l
->client_http
.miss_svc_time
,
1104 &f
->client_http
.miss_svc_time
) / 1000.0;
1105 stats
.client_http_nm_median_svc_time
= statHistDeltaMedian(&l
->client_http
.nm_svc_time
,
1106 &f
->client_http
.nm_svc_time
) / 1000.0;
1107 stats
.client_http_nh_median_svc_time
= statHistDeltaMedian(&l
->client_http
.nh_svc_time
,
1108 &f
->client_http
.nh_svc_time
) / 1000.0;
1109 stats
.client_http_hit_median_svc_time
= statHistDeltaMedian(&l
->client_http
.hit_svc_time
,
1110 &f
->client_http
.hit_svc_time
) / 1000.0;
1112 stats
.server_all_requests
= XAVG(server
.all
.requests
);
1113 stats
.server_all_errors
= XAVG(server
.all
.errors
);
1114 stats
.server_all_kbytes_in
= XAVG(server
.all
.kbytes_in
.kb
);
1115 stats
.server_all_kbytes_out
= XAVG(server
.all
.kbytes_out
.kb
);
1117 stats
.server_http_requests
= XAVG(server
.http
.requests
);
1118 stats
.server_http_errors
= XAVG(server
.http
.errors
);
1119 stats
.server_http_kbytes_in
= XAVG(server
.http
.kbytes_in
.kb
);
1120 stats
.server_http_kbytes_out
= XAVG(server
.http
.kbytes_out
.kb
);
1122 stats
.server_ftp_requests
= XAVG(server
.ftp
.requests
);
1123 stats
.server_ftp_errors
= XAVG(server
.ftp
.errors
);
1124 stats
.server_ftp_kbytes_in
= XAVG(server
.ftp
.kbytes_in
.kb
);
1125 stats
.server_ftp_kbytes_out
= XAVG(server
.ftp
.kbytes_out
.kb
);
1127 stats
.server_other_requests
= XAVG(server
.other
.requests
);
1128 stats
.server_other_errors
= XAVG(server
.other
.errors
);
1129 stats
.server_other_kbytes_in
= XAVG(server
.other
.kbytes_in
.kb
);
1130 stats
.server_other_kbytes_out
= XAVG(server
.other
.kbytes_out
.kb
);
1132 stats
.icp_pkts_sent
= XAVG(icp
.pkts_sent
);
1133 stats
.icp_pkts_recv
= XAVG(icp
.pkts_recv
);
1134 stats
.icp_queries_sent
= XAVG(icp
.queries_sent
);
1135 stats
.icp_replies_sent
= XAVG(icp
.replies_sent
);
1136 stats
.icp_queries_recv
= XAVG(icp
.queries_recv
);
1137 stats
.icp_replies_recv
= XAVG(icp
.replies_recv
);
1138 stats
.icp_replies_queued
= XAVG(icp
.replies_queued
);
1139 stats
.icp_query_timeouts
= XAVG(icp
.query_timeouts
);
1140 stats
.icp_kbytes_sent
= XAVG(icp
.kbytes_sent
.kb
);
1141 stats
.icp_kbytes_recv
= XAVG(icp
.kbytes_recv
.kb
);
1142 stats
.icp_q_kbytes_sent
= XAVG(icp
.q_kbytes_sent
.kb
);
1143 stats
.icp_r_kbytes_sent
= XAVG(icp
.r_kbytes_sent
.kb
);
1144 stats
.icp_q_kbytes_recv
= XAVG(icp
.q_kbytes_recv
.kb
);
1145 stats
.icp_r_kbytes_recv
= XAVG(icp
.r_kbytes_recv
.kb
);
1147 stats
.icp_query_median_svc_time
= statHistDeltaMedian(&l
->icp
.query_svc_time
,
1148 &f
->icp
.query_svc_time
) / 1000000.0;
1149 stats
.icp_reply_median_svc_time
= statHistDeltaMedian(&l
->icp
.reply_svc_time
,
1150 &f
->icp
.reply_svc_time
) / 1000000.0;
1151 stats
.dns_median_svc_time
= statHistDeltaMedian(&l
->dns
.svc_time
,
1152 &f
->dns
.svc_time
) / 1000.0;
1154 stats
.unlink_requests
= XAVG(unlink
.requests
);
1155 stats
.page_faults
= XAVG(page_faults
);
1156 stats
.select_loops
= XAVG(select_loops
);
1157 stats
.select_fds
= XAVG(select_fds
);
1158 stats
.average_select_fd_period
= f
->select_fds
> l
->select_fds
?
1159 (f
->select_time
- l
->select_time
) / (f
->select_fds
- l
->select_fds
) : 0.0;
1161 stats
.median_select_fds
= statHistDeltaMedian(&l
->select_fds_hist
, &f
->select_fds_hist
);
1162 stats
.swap_outs
= XAVG(swap
.outs
);
1163 stats
.swap_ins
= XAVG(swap
.ins
);
1164 stats
.swap_files_cleaned
= XAVG(swap
.files_cleaned
);
1165 stats
.aborted_requests
= XAVG(aborted_requests
);
1167 stats
.syscalls_disk_opens
= XAVG(syscalls
.disk
.opens
);
1168 stats
.syscalls_disk_closes
= XAVG(syscalls
.disk
.closes
);
1169 stats
.syscalls_disk_reads
= XAVG(syscalls
.disk
.reads
);
1170 stats
.syscalls_disk_writes
= XAVG(syscalls
.disk
.writes
);
1171 stats
.syscalls_disk_seeks
= XAVG(syscalls
.disk
.seeks
);
1172 stats
.syscalls_disk_unlinks
= XAVG(syscalls
.disk
.unlinks
);
1173 stats
.syscalls_sock_accepts
= XAVG(syscalls
.sock
.accepts
);
1174 stats
.syscalls_sock_sockets
= XAVG(syscalls
.sock
.sockets
);
1175 stats
.syscalls_sock_connects
= XAVG(syscalls
.sock
.connects
);
1176 stats
.syscalls_sock_binds
= XAVG(syscalls
.sock
.binds
);
1177 stats
.syscalls_sock_closes
= XAVG(syscalls
.sock
.closes
);
1178 stats
.syscalls_sock_reads
= XAVG(syscalls
.sock
.reads
);
1179 stats
.syscalls_sock_writes
= XAVG(syscalls
.sock
.writes
);
1180 stats
.syscalls_sock_recvfroms
= XAVG(syscalls
.sock
.recvfroms
);
1181 stats
.syscalls_sock_sendtos
= XAVG(syscalls
.sock
.sendtos
);
1182 stats
.syscalls_selects
= XAVG(syscalls
.selects
);
1184 stats
.cpu_time
= ct
;
1185 stats
.wall_time
= dt
;
1189 DumpAvgStat(Mgr::IntervalActionData
& stats
, StoreEntry
* sentry
)
1191 storeAppendPrintf(sentry
, "sample_start_time = %d.%d (%s)\n",
1192 (int)stats
.sample_start_time
.tv_sec
,
1193 (int)stats
.sample_start_time
.tv_usec
,
1194 mkrfc1123(stats
.sample_start_time
.tv_sec
));
1195 storeAppendPrintf(sentry
, "sample_end_time = %d.%d (%s)\n",
1196 (int)stats
.sample_end_time
.tv_sec
,
1197 (int)stats
.sample_end_time
.tv_usec
,
1198 mkrfc1123(stats
.sample_end_time
.tv_sec
));
1200 storeAppendPrintf(sentry
, "client_http.requests = %f/sec\n",
1201 stats
.client_http_requests
);
1202 storeAppendPrintf(sentry
, "client_http.hits = %f/sec\n",
1203 stats
.client_http_hits
);
1204 storeAppendPrintf(sentry
, "client_http.errors = %f/sec\n",
1205 stats
.client_http_errors
);
1206 storeAppendPrintf(sentry
, "client_http.kbytes_in = %f/sec\n",
1207 stats
.client_http_kbytes_in
);
1208 storeAppendPrintf(sentry
, "client_http.kbytes_out = %f/sec\n",
1209 stats
.client_http_kbytes_out
);
1211 double fct
= stats
.count
> 1 ? stats
.count
: 1.0;
1212 storeAppendPrintf(sentry
, "client_http.all_median_svc_time = %f seconds\n",
1213 stats
.client_http_all_median_svc_time
/ fct
);
1214 storeAppendPrintf(sentry
, "client_http.miss_median_svc_time = %f seconds\n",
1215 stats
.client_http_miss_median_svc_time
/ fct
);
1216 storeAppendPrintf(sentry
, "client_http.nm_median_svc_time = %f seconds\n",
1217 stats
.client_http_nm_median_svc_time
/ fct
);
1218 storeAppendPrintf(sentry
, "client_http.nh_median_svc_time = %f seconds\n",
1219 stats
.client_http_nh_median_svc_time
/ fct
);
1220 storeAppendPrintf(sentry
, "client_http.hit_median_svc_time = %f seconds\n",
1221 stats
.client_http_hit_median_svc_time
/ fct
);
1223 storeAppendPrintf(sentry
, "server.all.requests = %f/sec\n",
1224 stats
.server_all_requests
);
1225 storeAppendPrintf(sentry
, "server.all.errors = %f/sec\n",
1226 stats
.server_all_errors
);
1227 storeAppendPrintf(sentry
, "server.all.kbytes_in = %f/sec\n",
1228 stats
.server_all_kbytes_in
);
1229 storeAppendPrintf(sentry
, "server.all.kbytes_out = %f/sec\n",
1230 stats
.server_all_kbytes_out
);
1232 storeAppendPrintf(sentry
, "server.http.requests = %f/sec\n",
1233 stats
.server_http_requests
);
1234 storeAppendPrintf(sentry
, "server.http.errors = %f/sec\n",
1235 stats
.server_http_errors
);
1236 storeAppendPrintf(sentry
, "server.http.kbytes_in = %f/sec\n",
1237 stats
.server_http_kbytes_in
);
1238 storeAppendPrintf(sentry
, "server.http.kbytes_out = %f/sec\n",
1239 stats
.server_http_kbytes_out
);
1241 storeAppendPrintf(sentry
, "server.ftp.requests = %f/sec\n",
1242 stats
.server_ftp_requests
);
1243 storeAppendPrintf(sentry
, "server.ftp.errors = %f/sec\n",
1244 stats
.server_ftp_errors
);
1245 storeAppendPrintf(sentry
, "server.ftp.kbytes_in = %f/sec\n",
1246 stats
.server_ftp_kbytes_in
);
1247 storeAppendPrintf(sentry
, "server.ftp.kbytes_out = %f/sec\n",
1248 stats
.server_ftp_kbytes_out
);
1250 storeAppendPrintf(sentry
, "server.other.requests = %f/sec\n",
1251 stats
.server_other_requests
);
1252 storeAppendPrintf(sentry
, "server.other.errors = %f/sec\n",
1253 stats
.server_other_errors
);
1254 storeAppendPrintf(sentry
, "server.other.kbytes_in = %f/sec\n",
1255 stats
.server_other_kbytes_in
);
1256 storeAppendPrintf(sentry
, "server.other.kbytes_out = %f/sec\n",
1257 stats
.server_other_kbytes_out
);
1259 storeAppendPrintf(sentry
, "icp.pkts_sent = %f/sec\n",
1260 stats
.icp_pkts_sent
);
1261 storeAppendPrintf(sentry
, "icp.pkts_recv = %f/sec\n",
1262 stats
.icp_pkts_recv
);
1263 storeAppendPrintf(sentry
, "icp.queries_sent = %f/sec\n",
1264 stats
.icp_queries_sent
);
1265 storeAppendPrintf(sentry
, "icp.replies_sent = %f/sec\n",
1266 stats
.icp_replies_sent
);
1267 storeAppendPrintf(sentry
, "icp.queries_recv = %f/sec\n",
1268 stats
.icp_queries_recv
);
1269 storeAppendPrintf(sentry
, "icp.replies_recv = %f/sec\n",
1270 stats
.icp_replies_recv
);
1271 storeAppendPrintf(sentry
, "icp.replies_queued = %f/sec\n",
1272 stats
.icp_replies_queued
);
1273 storeAppendPrintf(sentry
, "icp.query_timeouts = %f/sec\n",
1274 stats
.icp_query_timeouts
);
1275 storeAppendPrintf(sentry
, "icp.kbytes_sent = %f/sec\n",
1276 stats
.icp_kbytes_sent
);
1277 storeAppendPrintf(sentry
, "icp.kbytes_recv = %f/sec\n",
1278 stats
.icp_kbytes_recv
);
1279 storeAppendPrintf(sentry
, "icp.q_kbytes_sent = %f/sec\n",
1280 stats
.icp_q_kbytes_sent
);
1281 storeAppendPrintf(sentry
, "icp.r_kbytes_sent = %f/sec\n",
1282 stats
.icp_r_kbytes_sent
);
1283 storeAppendPrintf(sentry
, "icp.q_kbytes_recv = %f/sec\n",
1284 stats
.icp_q_kbytes_recv
);
1285 storeAppendPrintf(sentry
, "icp.r_kbytes_recv = %f/sec\n",
1286 stats
.icp_r_kbytes_recv
);
1287 storeAppendPrintf(sentry
, "icp.query_median_svc_time = %f seconds\n",
1288 stats
.icp_query_median_svc_time
/ fct
);
1289 storeAppendPrintf(sentry
, "icp.reply_median_svc_time = %f seconds\n",
1290 stats
.icp_reply_median_svc_time
/ fct
);
1291 storeAppendPrintf(sentry
, "dns.median_svc_time = %f seconds\n",
1292 stats
.dns_median_svc_time
/ fct
);
1293 storeAppendPrintf(sentry
, "unlink.requests = %f/sec\n",
1294 stats
.unlink_requests
);
1295 storeAppendPrintf(sentry
, "page_faults = %f/sec\n",
1297 storeAppendPrintf(sentry
, "select_loops = %f/sec\n",
1298 stats
.select_loops
);
1299 storeAppendPrintf(sentry
, "select_fds = %f/sec\n",
1301 storeAppendPrintf(sentry
, "average_select_fd_period = %f/fd\n",
1302 stats
.average_select_fd_period
/ fct
);
1303 storeAppendPrintf(sentry
, "median_select_fds = %f\n",
1304 stats
.median_select_fds
/ fct
);
1305 storeAppendPrintf(sentry
, "swap.outs = %f/sec\n",
1307 storeAppendPrintf(sentry
, "swap.ins = %f/sec\n",
1309 storeAppendPrintf(sentry
, "swap.files_cleaned = %f/sec\n",
1310 stats
.swap_files_cleaned
);
1311 storeAppendPrintf(sentry
, "aborted_requests = %f/sec\n",
1312 stats
.aborted_requests
);
1315 storeAppendPrintf(sentry
, "syscalls.polls = %f/sec\n", stats
.syscalls_selects
);
1316 #elif defined(USE_SELECT) || defined(USE_SELECT_WIN32)
1317 storeAppendPrintf(sentry
, "syscalls.selects = %f/sec\n", stats
.syscalls_selects
);
1320 storeAppendPrintf(sentry
, "syscalls.disk.opens = %f/sec\n", stats
.syscalls_disk_opens
);
1321 storeAppendPrintf(sentry
, "syscalls.disk.closes = %f/sec\n", stats
.syscalls_disk_closes
);
1322 storeAppendPrintf(sentry
, "syscalls.disk.reads = %f/sec\n", stats
.syscalls_disk_reads
);
1323 storeAppendPrintf(sentry
, "syscalls.disk.writes = %f/sec\n", stats
.syscalls_disk_writes
);
1324 storeAppendPrintf(sentry
, "syscalls.disk.seeks = %f/sec\n", stats
.syscalls_disk_seeks
);
1325 storeAppendPrintf(sentry
, "syscalls.disk.unlinks = %f/sec\n", stats
.syscalls_disk_unlinks
);
1326 storeAppendPrintf(sentry
, "syscalls.sock.accepts = %f/sec\n", stats
.syscalls_sock_accepts
);
1327 storeAppendPrintf(sentry
, "syscalls.sock.sockets = %f/sec\n", stats
.syscalls_sock_sockets
);
1328 storeAppendPrintf(sentry
, "syscalls.sock.connects = %f/sec\n", stats
.syscalls_sock_connects
);
1329 storeAppendPrintf(sentry
, "syscalls.sock.binds = %f/sec\n", stats
.syscalls_sock_binds
);
1330 storeAppendPrintf(sentry
, "syscalls.sock.closes = %f/sec\n", stats
.syscalls_sock_closes
);
1331 storeAppendPrintf(sentry
, "syscalls.sock.reads = %f/sec\n", stats
.syscalls_sock_reads
);
1332 storeAppendPrintf(sentry
, "syscalls.sock.writes = %f/sec\n", stats
.syscalls_sock_writes
);
1333 storeAppendPrintf(sentry
, "syscalls.sock.recvfroms = %f/sec\n", stats
.syscalls_sock_recvfroms
);
1334 storeAppendPrintf(sentry
, "syscalls.sock.sendtos = %f/sec\n", stats
.syscalls_sock_sendtos
);
1336 storeAppendPrintf(sentry
, "cpu_time = %f seconds\n", stats
.cpu_time
);
1337 storeAppendPrintf(sentry
, "wall_time = %f seconds\n", stats
.wall_time
);
1338 storeAppendPrintf(sentry
, "cpu_usage = %f%%\n", Math::doublePercent(stats
.cpu_time
, stats
.wall_time
));
1342 statRegisterWithCacheManager(void)
1344 Mgr::RegisterAction("info", "General Runtime Information",
1345 &Mgr::InfoAction::Create
, 0, 1);
1346 Mgr::RegisterAction("service_times", "Service Times (Percentiles)",
1347 &Mgr::ServiceTimesAction::Create
, 0, 1);
1348 Mgr::RegisterAction("filedescriptors", "Process Filedescriptor Allocation",
1349 fde::DumpStats
, 0, 1);
1350 Mgr::RegisterAction("objects", "All Cache Objects", stat_objects_get
, 0, 0);
1351 Mgr::RegisterAction("vm_objects", "In-Memory and In-Transit Objects",
1352 stat_vmobjects_get
, 0, 0);
1353 Mgr::RegisterAction("io", "Server-side network read() size histograms",
1354 &Mgr::IoAction::Create
, 0, 1);
1355 Mgr::RegisterAction("counters", "Traffic and Resource Counters",
1356 &Mgr::CountersAction::Create
, 0, 1);
1357 Mgr::RegisterAction("peer_select", "Peer Selection Algorithms",
1358 statPeerSelect
, 0, 1);
1359 Mgr::RegisterAction("digest_stats", "Cache Digest and ICP blob",
1360 statDigestBlob
, 0, 1);
1361 Mgr::RegisterAction("5min", "5 Minute Average of Counters",
1362 &Mgr::IntervalAction::Create5min
, 0, 1);
1363 Mgr::RegisterAction("60min", "60 Minute Average of Counters",
1364 &Mgr::IntervalAction::Create60min
, 0, 1);
1365 Mgr::RegisterAction("utilization", "Cache Utilization",
1366 statUtilization
, 0, 1);
1367 Mgr::RegisterAction("histograms", "Full Histogram Counts",
1368 statCountersHistograms
, 0, 1);
1369 Mgr::RegisterAction("active_requests",
1370 "Client-side Active Requests",
1371 statClientRequests
, 0, 1);
1372 Mgr::RegisterAction("username_cache",
1373 "Active Cached Usernames",
1374 AuthUser::UsernameCacheStats
, 0, 1);
1376 Mgr::RegisterAction("openfd_objects", "Objects with Swapout files open",
1377 statOpenfdObj
, 0, 0);
1380 Mgr::RegisterAction("graph_variables", "Display cache metrics graphically",
1381 statGraphDump
, 0, 1);
1390 debugs(18, 5, "statInit: Initializing...");
1392 for (i
= 0; i
< N_COUNT_HIST
; i
++)
1393 statCountersInit(&CountHist
[i
]);
1395 for (i
= 0; i
< N_COUNT_HOUR_HIST
; i
++)
1396 statCountersInit(&CountHourHist
[i
]);
1398 statCountersInit(&statCounter
);
1400 eventAdd("statAvgTick", statAvgTick
, NULL
, (double) COUNT_INTERVAL
, 1);
1402 ClientActiveRequests
.head
= NULL
;
1404 ClientActiveRequests
.tail
= NULL
;
1406 statRegisterWithCacheManager();
1410 statAvgTick(void *notused
)
1412 StatCounters
*t
= &CountHist
[0];
1413 StatCounters
*p
= &CountHist
[1];
1414 StatCounters
*c
= &statCounter
;
1416 struct rusage rusage
;
1417 eventAdd("statAvgTick", statAvgTick
, NULL
, (double) COUNT_INTERVAL
, 1);
1418 squid_getrusage(&rusage
);
1419 c
->page_faults
= rusage_pagefaults(&rusage
);
1420 c
->cputime
= rusage_cputime(&rusage
);
1421 c
->timestamp
= current_time
;
1422 /* even if NCountHist is small, we already Init()ed the tail */
1423 statCountersClean(CountHist
+ N_COUNT_HIST
- 1);
1424 xmemmove(p
, t
, (N_COUNT_HIST
- 1) * sizeof(StatCounters
));
1425 statCountersCopy(t
, c
);
1428 if ((NCountHist
% COUNT_INTERVAL
) == 0) {
1429 /* we have an hours worth of readings. store previous hour */
1430 StatCounters
*t2
= &CountHourHist
[0];
1431 StatCounters
*p2
= &CountHourHist
[1];
1432 StatCounters
*c2
= &CountHist
[N_COUNT_HIST
- 1];
1433 statCountersClean(CountHourHist
+ N_COUNT_HOUR_HIST
- 1);
1434 xmemmove(p2
, t2
, (N_COUNT_HOUR_HIST
- 1) * sizeof(StatCounters
));
1435 statCountersCopy(t2
, c2
);
1439 if (Config
.warnings
.high_rptm
> 0) {
1440 int i
= (int) statPctileSvc(0.5, 20, PCTILE_HTTP
);
1442 if (Config
.warnings
.high_rptm
< i
)
1443 debugs(18, 0, "WARNING: Median response time is " << i
<< " milliseconds");
1446 if (Config
.warnings
.high_pf
) {
1447 int i
= (CountHist
[0].page_faults
- CountHist
[1].page_faults
);
1448 double dt
= tvSubDsec(CountHist
[0].timestamp
, CountHist
[1].timestamp
);
1450 if (i
> 0 && dt
> 0.0) {
1453 if (Config
.warnings
.high_pf
< i
)
1454 debugs(18, 0, "WARNING: Page faults occuring at " << i
<< "/sec");
1458 if (Config
.warnings
.high_memory
) {
1460 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
1462 struct mstats ms
= mstats();
1464 #elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
1466 struct mallinfo mp
= mallinfo();
1470 i
= (size_t) ((char *) sbrk(0) - (char *) sbrk_start
);
1473 if (Config
.warnings
.high_memory
< i
)
1474 debugs(18, 0, "WARNING: Memory usage at " << ((unsigned long int)(i
>> 20)) << " MB");
1479 statCountersInit(StatCounters
* C
)
1482 memset(C
, 0, sizeof(*C
));
1483 C
->timestamp
= current_time
;
1484 statCountersInitSpecial(C
);
1487 /* add special cases here as they arrive */
1489 statCountersInitSpecial(StatCounters
* C
)
1492 * HTTP svc_time hist is kept in milli-seconds; max of 3 hours.
1494 statHistLogInit(&C
->client_http
.all_svc_time
, 300, 0.0, 3600000.0 * 3.0);
1495 statHistLogInit(&C
->client_http
.miss_svc_time
, 300, 0.0, 3600000.0 * 3.0);
1496 statHistLogInit(&C
->client_http
.nm_svc_time
, 300, 0.0, 3600000.0 * 3.0);
1497 statHistLogInit(&C
->client_http
.nh_svc_time
, 300, 0.0, 3600000.0 * 3.0);
1498 statHistLogInit(&C
->client_http
.hit_svc_time
, 300, 0.0, 3600000.0 * 3.0);
1500 * ICP svc_time hist is kept in micro-seconds; max of 1 minute.
1502 statHistLogInit(&C
->icp
.query_svc_time
, 300, 0.0, 1000000.0 * 60.0);
1503 statHistLogInit(&C
->icp
.reply_svc_time
, 300, 0.0, 1000000.0 * 60.0);
1505 * DNS svc_time hist is kept in milli-seconds; max of 10 minutes.
1507 statHistLogInit(&C
->dns
.svc_time
, 300, 0.0, 60000.0 * 10.0);
1509 * Cache Digest Stuff
1511 statHistEnumInit(&C
->cd
.on_xition_count
, CacheDigestHashFuncCount
);
1512 statHistEnumInit(&C
->comm_icp_incoming
, INCOMING_ICP_MAX
);
1513 statHistEnumInit(&C
->comm_dns_incoming
, INCOMING_DNS_MAX
);
1514 statHistEnumInit(&C
->comm_http_incoming
, INCOMING_HTTP_MAX
);
1515 statHistIntInit(&C
->select_fds_hist
, 256); /* was SQUID_MAXFD, but it is way too much. It is OK to crop this statistics */
1518 /* add special cases here as they arrive */
1520 statCountersClean(StatCounters
* C
)
1523 statHistClean(&C
->client_http
.all_svc_time
);
1524 statHistClean(&C
->client_http
.miss_svc_time
);
1525 statHistClean(&C
->client_http
.nm_svc_time
);
1526 statHistClean(&C
->client_http
.nh_svc_time
);
1527 statHistClean(&C
->client_http
.hit_svc_time
);
1528 statHistClean(&C
->icp
.query_svc_time
);
1529 statHistClean(&C
->icp
.reply_svc_time
);
1530 statHistClean(&C
->dns
.svc_time
);
1531 statHistClean(&C
->cd
.on_xition_count
);
1532 statHistClean(&C
->comm_icp_incoming
);
1533 statHistClean(&C
->comm_dns_incoming
);
1534 statHistClean(&C
->comm_http_incoming
);
1535 statHistClean(&C
->select_fds_hist
);
1538 /* add special cases here as they arrive */
1540 statCountersCopy(StatCounters
* dest
, const StatCounters
* orig
)
1542 assert(dest
&& orig
);
1543 /* this should take care of all the fields, but "special" ones */
1544 xmemcpy(dest
, orig
, sizeof(*dest
));
1545 /* prepare space where to copy special entries */
1546 statCountersInitSpecial(dest
);
1547 /* now handle special cases */
1548 /* note: we assert that histogram capacities do not change */
1549 statHistCopy(&dest
->client_http
.all_svc_time
, &orig
->client_http
.all_svc_time
);
1550 statHistCopy(&dest
->client_http
.miss_svc_time
, &orig
->client_http
.miss_svc_time
);
1551 statHistCopy(&dest
->client_http
.nm_svc_time
, &orig
->client_http
.nm_svc_time
);
1552 statHistCopy(&dest
->client_http
.nh_svc_time
, &orig
->client_http
.nh_svc_time
);
1553 statHistCopy(&dest
->client_http
.hit_svc_time
, &orig
->client_http
.hit_svc_time
);
1554 statHistCopy(&dest
->icp
.query_svc_time
, &orig
->icp
.query_svc_time
);
1555 statHistCopy(&dest
->icp
.reply_svc_time
, &orig
->icp
.reply_svc_time
);
1556 statHistCopy(&dest
->dns
.svc_time
, &orig
->dns
.svc_time
);
1557 statHistCopy(&dest
->cd
.on_xition_count
, &orig
->cd
.on_xition_count
);
1558 statHistCopy(&dest
->comm_icp_incoming
, &orig
->comm_icp_incoming
);
1559 statHistCopy(&dest
->comm_http_incoming
, &orig
->comm_http_incoming
);
1560 statHistCopy(&dest
->select_fds_hist
, &orig
->select_fds_hist
);
1564 statCountersHistograms(StoreEntry
* sentry
)
1566 StatCounters
*f
= &statCounter
;
1567 storeAppendPrintf(sentry
, "client_http.all_svc_time histogram:\n");
1568 statHistDump(&f
->client_http
.all_svc_time
, sentry
, NULL
);
1569 storeAppendPrintf(sentry
, "client_http.miss_svc_time histogram:\n");
1570 statHistDump(&f
->client_http
.miss_svc_time
, sentry
, NULL
);
1571 storeAppendPrintf(sentry
, "client_http.nm_svc_time histogram:\n");
1572 statHistDump(&f
->client_http
.nm_svc_time
, sentry
, NULL
);
1573 storeAppendPrintf(sentry
, "client_http.nh_svc_time histogram:\n");
1574 statHistDump(&f
->client_http
.nh_svc_time
, sentry
, NULL
);
1575 storeAppendPrintf(sentry
, "client_http.hit_svc_time histogram:\n");
1576 statHistDump(&f
->client_http
.hit_svc_time
, sentry
, NULL
);
1577 storeAppendPrintf(sentry
, "icp.query_svc_time histogram:\n");
1578 statHistDump(&f
->icp
.query_svc_time
, sentry
, NULL
);
1579 storeAppendPrintf(sentry
, "icp.reply_svc_time histogram:\n");
1580 statHistDump(&f
->icp
.reply_svc_time
, sentry
, NULL
);
1581 storeAppendPrintf(sentry
, "dns.svc_time histogram:\n");
1582 statHistDump(&f
->dns
.svc_time
, sentry
, NULL
);
1583 storeAppendPrintf(sentry
, "select_fds_hist histogram:\n");
1584 statHistDump(&f
->select_fds_hist
, sentry
, NULL
);
1588 statCountersDump(StoreEntry
* sentry
)
1590 Mgr::CountersActionData stats
;
1591 GetCountersStats(stats
);
1592 DumpCountersStats(stats
, sentry
);
1596 GetCountersStats(Mgr::CountersActionData
& stats
)
1598 StatCounters
*f
= &statCounter
;
1600 struct rusage rusage
;
1601 squid_getrusage(&rusage
);
1602 f
->page_faults
= rusage_pagefaults(&rusage
);
1603 f
->cputime
= rusage_cputime(&rusage
);
1605 stats
.sample_time
= f
->timestamp
;
1606 stats
.client_http_requests
= f
->client_http
.requests
;
1607 stats
.client_http_hits
= f
->client_http
.hits
;
1608 stats
.client_http_errors
= f
->client_http
.errors
;
1609 stats
.client_http_kbytes_in
= f
->client_http
.kbytes_in
.kb
;
1610 stats
.client_http_kbytes_out
= f
->client_http
.kbytes_out
.kb
;
1611 stats
.client_http_hit_kbytes_out
= f
->client_http
.hit_kbytes_out
.kb
;
1613 stats
.server_all_requests
= f
->server
.all
.requests
;
1614 stats
.server_all_errors
= f
->server
.all
.errors
;
1615 stats
.server_all_kbytes_in
= f
->server
.all
.kbytes_in
.kb
;
1616 stats
.server_all_kbytes_out
= f
->server
.all
.kbytes_out
.kb
;
1618 stats
.server_http_requests
= f
->server
.http
.requests
;
1619 stats
.server_http_errors
= f
->server
.http
.errors
;
1620 stats
.server_http_kbytes_in
= f
->server
.http
.kbytes_in
.kb
;
1621 stats
.server_http_kbytes_out
= f
->server
.http
.kbytes_out
.kb
;
1623 stats
.server_ftp_requests
= f
->server
.ftp
.requests
;
1624 stats
.server_ftp_errors
= f
->server
.ftp
.errors
;
1625 stats
.server_ftp_kbytes_in
= f
->server
.ftp
.kbytes_in
.kb
;
1626 stats
.server_ftp_kbytes_out
= f
->server
.ftp
.kbytes_out
.kb
;
1628 stats
.server_other_requests
= f
->server
.other
.requests
;
1629 stats
.server_other_errors
= f
->server
.other
.errors
;
1630 stats
.server_other_kbytes_in
= f
->server
.other
.kbytes_in
.kb
;
1631 stats
.server_other_kbytes_out
= f
->server
.other
.kbytes_out
.kb
;
1633 stats
.icp_pkts_sent
= f
->icp
.pkts_sent
;
1634 stats
.icp_pkts_recv
= f
->icp
.pkts_recv
;
1635 stats
.icp_queries_sent
= f
->icp
.queries_sent
;
1636 stats
.icp_replies_sent
= f
->icp
.replies_sent
;
1637 stats
.icp_queries_recv
= f
->icp
.queries_recv
;
1638 stats
.icp_replies_recv
= f
->icp
.replies_recv
;
1639 stats
.icp_query_timeouts
= f
->icp
.query_timeouts
;
1640 stats
.icp_replies_queued
= f
->icp
.replies_queued
;
1641 stats
.icp_kbytes_sent
= f
->icp
.kbytes_sent
.kb
;
1642 stats
.icp_kbytes_recv
= f
->icp
.kbytes_recv
.kb
;
1643 stats
.icp_q_kbytes_sent
= f
->icp
.q_kbytes_sent
.kb
;
1644 stats
.icp_r_kbytes_sent
= f
->icp
.r_kbytes_sent
.kb
;
1645 stats
.icp_q_kbytes_recv
= f
->icp
.q_kbytes_recv
.kb
;
1646 stats
.icp_r_kbytes_recv
= f
->icp
.r_kbytes_recv
.kb
;
1648 #if USE_CACHE_DIGESTS
1650 stats
.icp_times_used
= f
->icp
.times_used
;
1651 stats
.cd_times_used
= f
->cd
.times_used
;
1652 stats
.cd_msgs_sent
= f
->cd
.msgs_sent
;
1653 stats
.cd_msgs_recv
= f
->cd
.msgs_recv
;
1654 stats
.cd_memory
= f
->cd
.memory
.kb
;
1655 stats
.cd_local_memory
= store_digest
? store_digest
->mask_size
/ 1024 : 0;
1656 stats
.cd_kbytes_sent
= f
->cd
.kbytes_sent
.kb
;
1657 stats
.cd_kbytes_recv
= f
->cd
.kbytes_recv
.kb
;
1660 stats
.unlink_requests
= f
->unlink
.requests
;
1661 stats
.page_faults
= f
->page_faults
;
1662 stats
.select_loops
= f
->select_loops
;
1663 stats
.cpu_time
= f
->cputime
;
1664 stats
.wall_time
= tvSubDsec(f
->timestamp
, current_time
);
1665 stats
.swap_outs
= f
->swap
.outs
;
1666 stats
.swap_ins
= f
->swap
.ins
;
1667 stats
.swap_files_cleaned
= f
->swap
.files_cleaned
;
1668 stats
.aborted_requests
= f
->aborted_requests
;
1672 DumpCountersStats(Mgr::CountersActionData
& stats
, StoreEntry
* sentry
)
1674 storeAppendPrintf(sentry
, "sample_time = %d.%d (%s)\n",
1675 (int) stats
.sample_time
.tv_sec
,
1676 (int) stats
.sample_time
.tv_usec
,
1677 mkrfc1123(stats
.sample_time
.tv_sec
));
1678 storeAppendPrintf(sentry
, "client_http.requests = %.0f\n",
1679 stats
.client_http_requests
);
1680 storeAppendPrintf(sentry
, "client_http.hits = %.0f\n",
1681 stats
.client_http_hits
);
1682 storeAppendPrintf(sentry
, "client_http.errors = %.0f\n",
1683 stats
.client_http_errors
);
1684 storeAppendPrintf(sentry
, "client_http.kbytes_in = %.0f\n",
1685 stats
.client_http_kbytes_in
);
1686 storeAppendPrintf(sentry
, "client_http.kbytes_out = %.0f\n",
1687 stats
.client_http_kbytes_out
);
1688 storeAppendPrintf(sentry
, "client_http.hit_kbytes_out = %.0f\n",
1689 stats
.client_http_hit_kbytes_out
);
1691 storeAppendPrintf(sentry
, "server.all.requests = %.0f\n",
1692 stats
.server_all_requests
);
1693 storeAppendPrintf(sentry
, "server.all.errors = %.0f\n",
1694 stats
.server_all_errors
);
1695 storeAppendPrintf(sentry
, "server.all.kbytes_in = %.0f\n",
1696 stats
.server_all_kbytes_in
);
1697 storeAppendPrintf(sentry
, "server.all.kbytes_out = %.0f\n",
1698 stats
.server_all_kbytes_out
);
1700 storeAppendPrintf(sentry
, "server.http.requests = %.0f\n",
1701 stats
.server_http_requests
);
1702 storeAppendPrintf(sentry
, "server.http.errors = %.0f\n",
1703 stats
.server_http_errors
);
1704 storeAppendPrintf(sentry
, "server.http.kbytes_in = %.0f\n",
1705 stats
.server_http_kbytes_in
);
1706 storeAppendPrintf(sentry
, "server.http.kbytes_out = %.0f\n",
1707 stats
.server_http_kbytes_out
);
1709 storeAppendPrintf(sentry
, "server.ftp.requests = %.0f\n",
1710 stats
.server_ftp_requests
);
1711 storeAppendPrintf(sentry
, "server.ftp.errors = %.0f\n",
1712 stats
.server_ftp_errors
);
1713 storeAppendPrintf(sentry
, "server.ftp.kbytes_in = %.0f\n",
1714 stats
.server_ftp_kbytes_in
);
1715 storeAppendPrintf(sentry
, "server.ftp.kbytes_out = %.0f\n",
1716 stats
.server_ftp_kbytes_out
);
1718 storeAppendPrintf(sentry
, "server.other.requests = %.0f\n",
1719 stats
.server_other_requests
);
1720 storeAppendPrintf(sentry
, "server.other.errors = %.0f\n",
1721 stats
.server_other_errors
);
1722 storeAppendPrintf(sentry
, "server.other.kbytes_in = %.0f\n",
1723 stats
.server_other_kbytes_in
);
1724 storeAppendPrintf(sentry
, "server.other.kbytes_out = %.0f\n",
1725 stats
.server_other_kbytes_out
);
1727 storeAppendPrintf(sentry
, "icp.pkts_sent = %.0f\n",
1728 stats
.icp_pkts_sent
);
1729 storeAppendPrintf(sentry
, "icp.pkts_recv = %.0f\n",
1730 stats
.icp_pkts_recv
);
1731 storeAppendPrintf(sentry
, "icp.queries_sent = %.0f\n",
1732 stats
.icp_queries_sent
);
1733 storeAppendPrintf(sentry
, "icp.replies_sent = %.0f\n",
1734 stats
.icp_replies_sent
);
1735 storeAppendPrintf(sentry
, "icp.queries_recv = %.0f\n",
1736 stats
.icp_queries_recv
);
1737 storeAppendPrintf(sentry
, "icp.replies_recv = %.0f\n",
1738 stats
.icp_replies_recv
);
1739 storeAppendPrintf(sentry
, "icp.query_timeouts = %.0f\n",
1740 stats
.icp_query_timeouts
);
1741 storeAppendPrintf(sentry
, "icp.replies_queued = %.0f\n",
1742 stats
.icp_replies_queued
);
1743 storeAppendPrintf(sentry
, "icp.kbytes_sent = %.0f\n",
1744 stats
.icp_kbytes_sent
);
1745 storeAppendPrintf(sentry
, "icp.kbytes_recv = %.0f\n",
1746 stats
.icp_kbytes_recv
);
1747 storeAppendPrintf(sentry
, "icp.q_kbytes_sent = %.0f\n",
1748 stats
.icp_q_kbytes_sent
);
1749 storeAppendPrintf(sentry
, "icp.r_kbytes_sent = %.0f\n",
1750 stats
.icp_r_kbytes_sent
);
1751 storeAppendPrintf(sentry
, "icp.q_kbytes_recv = %.0f\n",
1752 stats
.icp_q_kbytes_recv
);
1753 storeAppendPrintf(sentry
, "icp.r_kbytes_recv = %.0f\n",
1754 stats
.icp_r_kbytes_recv
);
1756 #if USE_CACHE_DIGESTS
1758 storeAppendPrintf(sentry
, "icp.times_used = %.0f\n",
1759 stats
.icp_times_used
);
1760 storeAppendPrintf(sentry
, "cd.times_used = %.0f\n",
1761 stats
.cd_times_used
);
1762 storeAppendPrintf(sentry
, "cd.msgs_sent = %.0f\n",
1763 stats
.cd_msgs_sent
);
1764 storeAppendPrintf(sentry
, "cd.msgs_recv = %.0f\n",
1765 stats
.cd_msgs_recv
);
1766 storeAppendPrintf(sentry
, "cd.memory = %.0f\n",
1768 storeAppendPrintf(sentry
, "cd.local_memory = %.0f\n",
1769 stats
.cd_local_memory
);
1770 storeAppendPrintf(sentry
, "cd.kbytes_sent = %.0f\n",
1771 stats
.cd_kbytes_sent
);
1772 storeAppendPrintf(sentry
, "cd.kbytes_recv = %.0f\n",
1773 stats
.cd_kbytes_recv
);
1776 storeAppendPrintf(sentry
, "unlink.requests = %.0f\n",
1777 stats
.unlink_requests
);
1778 storeAppendPrintf(sentry
, "page_faults = %.0f\n",
1780 storeAppendPrintf(sentry
, "select_loops = %.0f\n",
1781 stats
.select_loops
);
1782 storeAppendPrintf(sentry
, "cpu_time = %f\n",
1784 storeAppendPrintf(sentry
, "wall_time = %f\n",
1786 storeAppendPrintf(sentry
, "swap.outs = %.0f\n",
1788 storeAppendPrintf(sentry
, "swap.ins = %.0f\n",
1790 storeAppendPrintf(sentry
, "swap.files_cleaned = %.0f\n",
1791 stats
.swap_files_cleaned
);
1792 storeAppendPrintf(sentry
, "aborted_requests = %.0f\n",
1793 stats
.aborted_requests
);
1797 statFreeMemory(void)
1801 for (i
= 0; i
< N_COUNT_HIST
; i
++)
1802 statCountersClean(&CountHist
[i
]);
1804 for (i
= 0; i
< N_COUNT_HOUR_HIST
; i
++)
1805 statCountersClean(&CountHourHist
[i
]);
1809 statPeerSelect(StoreEntry
* sentry
)
1811 #if USE_CACHE_DIGESTS
1812 StatCounters
*f
= &statCounter
;
1814 const int tot_used
= f
->cd
.times_used
+ f
->icp
.times_used
;
1817 cacheDigestGuessStatsReport(&f
->cd
.guess
, sentry
, "all peers");
1819 storeAppendPrintf(sentry
, "\nPer-peer statistics:\n");
1821 for (peer
= getFirstPeer(); peer
; peer
= getNextPeer(peer
)) {
1823 peerDigestStatsReport(peer
->digest
, sentry
);
1825 storeAppendPrintf(sentry
, "\nNo peer digest from %s\n", peer
->host
);
1827 storeAppendPrintf(sentry
, "\n");
1830 storeAppendPrintf(sentry
, "\nAlgorithm usage:\n");
1831 storeAppendPrintf(sentry
, "Cache Digest: %7d (%3d%%)\n",
1832 f
->cd
.times_used
, xpercentInt(f
->cd
.times_used
, tot_used
));
1833 storeAppendPrintf(sentry
, "Icp: %7d (%3d%%)\n",
1834 f
->icp
.times_used
, xpercentInt(f
->icp
.times_used
, tot_used
));
1835 storeAppendPrintf(sentry
, "Total: %7d (%3d%%)\n",
1836 tot_used
, xpercentInt(tot_used
, tot_used
));
1839 storeAppendPrintf(sentry
, "peer digests are disabled; no stats is available.\n");
1844 statDigestBlob(StoreEntry
* sentry
)
1846 storeAppendPrintf(sentry
, "\nCounters:\n");
1847 statCountersDump(sentry
);
1848 storeAppendPrintf(sentry
, "\n5 Min Averages:\n");
1849 statAvgDump(sentry
, 5, 0);
1850 storeAppendPrintf(sentry
, "\nHistograms:\n");
1851 statCountersHistograms(sentry
);
1852 storeAppendPrintf(sentry
, "\nPeer Digests:\n");
1853 statPeerSelect(sentry
);
1854 storeAppendPrintf(sentry
, "\nLocal Digest:\n");
1855 storeDigestReport(sentry
);
1859 statPctileSvc(double pctile
, int interval
, int which
)
1864 assert(interval
> 0);
1866 if (interval
> N_COUNT_HIST
- 1)
1867 interval
= N_COUNT_HIST
- 1;
1871 l
= &CountHist
[interval
];
1880 x
= statHistDeltaPctile(&l
->client_http
.all_svc_time
, &f
->client_http
.all_svc_time
, pctile
);
1884 x
= statHistDeltaPctile(&l
->client_http
.hit_svc_time
, &f
->client_http
.hit_svc_time
, pctile
);
1888 x
= statHistDeltaPctile(&l
->client_http
.miss_svc_time
, &f
->client_http
.miss_svc_time
, pctile
);
1892 x
= statHistDeltaPctile(&l
->client_http
.nm_svc_time
, &f
->client_http
.nm_svc_time
, pctile
);
1896 x
= statHistDeltaPctile(&l
->client_http
.nh_svc_time
, &f
->client_http
.nh_svc_time
, pctile
);
1899 case PCTILE_ICP_QUERY
:
1900 x
= statHistDeltaPctile(&l
->icp
.query_svc_time
, &f
->icp
.query_svc_time
, pctile
);
1904 x
= statHistDeltaPctile(&l
->dns
.svc_time
, &f
->dns
.svc_time
, pctile
);
1908 debugs(49, 5, "statPctileSvc: unknown type.");
1916 snmpStatGet(int minutes
)
1918 return &CountHist
[minutes
];
1922 stat5minClientRequests(void)
1924 assert(N_COUNT_HIST
> 5);
1925 return statCounter
.client_http
.requests
- CountHist
[5].client_http
.requests
;
1929 statCPUUsage(int minutes
)
1931 assert(minutes
< N_COUNT_HIST
);
1932 return Math::doublePercent(CountHist
[0].cputime
- CountHist
[minutes
].cputime
,
1933 tvSubDsec(CountHist
[minutes
].timestamp
, CountHist
[0].timestamp
));
1937 statRequestHitRatio(int minutes
)
1939 assert(minutes
< N_COUNT_HIST
);
1940 return Math::doublePercent(CountHist
[0].client_http
.hits
-
1941 CountHist
[minutes
].client_http
.hits
,
1942 CountHist
[0].client_http
.requests
-
1943 CountHist
[minutes
].client_http
.requests
);
1947 statRequestHitMemoryRatio(int minutes
)
1949 assert(minutes
< N_COUNT_HIST
);
1950 return Math::doublePercent(CountHist
[0].client_http
.mem_hits
-
1951 CountHist
[minutes
].client_http
.mem_hits
,
1952 CountHist
[0].client_http
.hits
-
1953 CountHist
[minutes
].client_http
.hits
);
1957 statRequestHitDiskRatio(int minutes
)
1959 assert(minutes
< N_COUNT_HIST
);
1960 return Math::doublePercent(CountHist
[0].client_http
.disk_hits
-
1961 CountHist
[minutes
].client_http
.disk_hits
,
1962 CountHist
[0].client_http
.hits
-
1963 CountHist
[minutes
].client_http
.hits
);
1967 statByteHitRatio(int minutes
)
1971 #if USE_CACHE_DIGESTS
1975 /* size_t might be unsigned */
1976 assert(minutes
< N_COUNT_HIST
);
1977 c
= CountHist
[0].client_http
.kbytes_out
.kb
- CountHist
[minutes
].client_http
.kbytes_out
.kb
;
1978 s
= CountHist
[0].server
.all
.kbytes_in
.kb
- CountHist
[minutes
].server
.all
.kbytes_in
.kb
;
1979 #if USE_CACHE_DIGESTS
1981 * This ugly hack is here to prevent the user from seeing a
1982 * negative byte hit ratio. When we fetch a cache digest from
1983 * a neighbor, it gets treated like a cache miss because the
1984 * object is consumed internally. Thus, we subtract cache
1985 * digest bytes out before calculating the byte hit ratio.
1987 cd
= CountHist
[0].cd
.kbytes_recv
.kb
- CountHist
[minutes
].cd
.kbytes_recv
.kb
;
1990 debugs(18, 1, "STRANGE: srv_kbytes=" << s
<< ", cd_kbytes=" << cd
);
1997 return Math::doublePercent(c
- s
, c
);
1999 return (-1.0 * Math::doublePercent(s
- c
, c
));
2003 statClientRequests(StoreEntry
* s
)
2006 ClientHttpRequest
*http
;
2009 char buf
[MAX_IPSTRLEN
];
2011 for (i
= ClientActiveRequests
.head
; i
; i
= i
->next
) {
2012 const char *p
= NULL
;
2013 http
= static_cast<ClientHttpRequest
*>(i
->data
);
2015 ConnStateData
* conn
= http
->getConn();
2016 storeAppendPrintf(s
, "Connection: %p\n", conn
);
2020 storeAppendPrintf(s
, "\tFD %d, read %"PRId64
", wrote %"PRId64
"\n", fd
,
2021 fd_table
[fd
].bytes_read
, fd_table
[fd
].bytes_written
);
2022 storeAppendPrintf(s
, "\tFD desc: %s\n", fd_table
[fd
].desc
);
2023 storeAppendPrintf(s
, "\tin: buf %p, offset %ld, size %ld\n",
2024 conn
->in
.buf
, (long int) conn
->in
.notYetUsed
, (long int) conn
->in
.allocatedSize
);
2025 storeAppendPrintf(s
, "\tpeer: %s:%d\n",
2026 conn
->peer
.NtoA(buf
,MAX_IPSTRLEN
),
2027 conn
->peer
.GetPort());
2028 storeAppendPrintf(s
, "\tme: %s:%d\n",
2029 conn
->me
.NtoA(buf
,MAX_IPSTRLEN
),
2030 conn
->me
.GetPort());
2031 storeAppendPrintf(s
, "\tnrequests: %d\n",
2035 storeAppendPrintf(s
, "uri %s\n", http
->uri
);
2036 storeAppendPrintf(s
, "logType %s\n", log_tags
[http
->logType
]);
2037 storeAppendPrintf(s
, "out.offset %ld, out.size %lu\n",
2038 (long int) http
->out
.offset
, (unsigned long int) http
->out
.size
);
2039 storeAppendPrintf(s
, "req_sz %ld\n", (long int) http
->req_sz
);
2040 e
= http
->storeEntry();
2041 storeAppendPrintf(s
, "entry %p/%s\n", e
, e
? e
->getMD5Text() : "N/A");
2043 /* Not a member anymore */
2044 e
= http
->old_entry
;
2045 storeAppendPrintf(s
, "old_entry %p/%s\n", e
, e
? e
->getMD5Text() : "N/A");
2048 storeAppendPrintf(s
, "start %ld.%06d (%f seconds ago)\n",
2049 (long int) http
->start_time
.tv_sec
,
2050 (int) http
->start_time
.tv_usec
,
2051 tvSubDsec(http
->start_time
, current_time
));
2053 if (http
->request
->auth_user_request
!= NULL
)
2054 p
= http
->request
->auth_user_request
->username();
2055 else if (http
->request
->extacl_user
.defined()) {
2056 p
= http
->request
->extacl_user
.termedBuf();
2059 if (!p
&& (conn
!= NULL
&& conn
->rfc931
[0]))
2064 if (!p
&& conn
!= NULL
)
2065 p
= sslGetUserEmail(fd_table
[conn
->fd
].ssl
);
2072 storeAppendPrintf(s
, "username %s\n", p
);
2075 storeAppendPrintf(s
, "delay_pool %d\n", DelayId::DelayClient(http
).pool());
2078 storeAppendPrintf(s
, "\n");
2084 * urgh, i don't like these, but they do cut the amount of code down immensely
2087 #define GRAPH_PER_MIN(Y) \
2088 for (i=0;i<(N_COUNT_HIST-2);i++) { \
2089 dt = tvSubDsec(CountHist[i+1].timestamp, CountHist[i].timestamp); \
2092 storeAppendPrintf(e, "%lu,%0.2f:", \
2093 CountHist[i].timestamp.tv_sec, \
2094 ((CountHist[i].Y - CountHist[i+1].Y) / dt)); \
2097 #define GRAPH_PER_HOUR(Y) \
2098 for (i=0;i<(N_COUNT_HOUR_HIST-2);i++) { \
2099 dt = tvSubDsec(CountHourHist[i+1].timestamp, CountHourHist[i].timestamp); \
2102 storeAppendPrintf(e, "%lu,%0.2f:", \
2103 CountHourHist[i].timestamp.tv_sec, \
2104 ((CountHourHist[i].Y - CountHourHist[i+1].Y) / dt)); \
2107 #define GRAPH_TITLE(X,Y) storeAppendPrintf(e,"%s\t%s\t",X,Y);
2108 #define GRAPH_END storeAppendPrintf(e,"\n");
2110 #define GENGRAPH(X,Y,Z) \
2117 statGraphDump(StoreEntry
* e
)
2122 GENGRAPH(client_http
.requests
, "client_http.requests", "Client HTTP requests/sec");
2123 GENGRAPH(client_http
.hits
, "client_http.hits", "Client HTTP hits/sec");
2124 GENGRAPH(client_http
.errors
, "client_http.errors", "Client HTTP errors/sec");
2125 GENGRAPH(client_http
.kbytes_in
.kb
, "client_http.kbytes_in", "Client HTTP kbytes_in/sec");
2126 GENGRAPH(client_http
.kbytes_out
.kb
, "client_http.kbytes_out", "Client HTTP kbytes_out/sec");
2128 /* XXX todo: http median service times */
2130 GENGRAPH(server
.all
.requests
, "server.all.requests", "Server requests/sec");
2131 GENGRAPH(server
.all
.errors
, "server.all.errors", "Server errors/sec");
2132 GENGRAPH(server
.all
.kbytes_in
.kb
, "server.all.kbytes_in", "Server total kbytes_in/sec");
2133 GENGRAPH(server
.all
.kbytes_out
.kb
, "server.all.kbytes_out", "Server total kbytes_out/sec");
2135 GENGRAPH(server
.http
.requests
, "server.http.requests", "Server HTTP requests/sec");
2136 GENGRAPH(server
.http
.errors
, "server.http.errors", "Server HTTP errors/sec");
2137 GENGRAPH(server
.http
.kbytes_in
.kb
, "server.http.kbytes_in", "Server HTTP kbytes_in/sec");
2138 GENGRAPH(server
.http
.kbytes_out
.kb
, "server.http.kbytes_out", "Server HTTP kbytes_out/sec");
2140 GENGRAPH(server
.ftp
.requests
, "server.ftp.requests", "Server FTP requests/sec");
2141 GENGRAPH(server
.ftp
.errors
, "server.ftp.errors", "Server FTP errors/sec");
2142 GENGRAPH(server
.ftp
.kbytes_in
.kb
, "server.ftp.kbytes_in", "Server FTP kbytes_in/sec");
2143 GENGRAPH(server
.ftp
.kbytes_out
.kb
, "server.ftp.kbytes_out", "Server FTP kbytes_out/sec");
2145 GENGRAPH(server
.other
.requests
, "server.other.requests", "Server other requests/sec");
2146 GENGRAPH(server
.other
.errors
, "server.other.errors", "Server other errors/sec");
2147 GENGRAPH(server
.other
.kbytes_in
.kb
, "server.other.kbytes_in", "Server other kbytes_in/sec");
2148 GENGRAPH(server
.other
.kbytes_out
.kb
, "server.other.kbytes_out", "Server other kbytes_out/sec");
2150 GENGRAPH(icp
.pkts_sent
, "icp.pkts_sent", "ICP packets sent/sec");
2151 GENGRAPH(icp
.pkts_recv
, "icp.pkts_recv", "ICP packets received/sec");
2152 GENGRAPH(icp
.kbytes_sent
.kb
, "icp.kbytes_sent", "ICP kbytes_sent/sec");
2153 GENGRAPH(icp
.kbytes_recv
.kb
, "icp.kbytes_recv", "ICP kbytes_received/sec");
2155 /* XXX todo: icp median service times */
2156 /* XXX todo: dns median service times */
2158 GENGRAPH(unlink
.requests
, "unlink.requests", "Cache File unlink requests/sec");
2159 GENGRAPH(page_faults
, "page_faults", "System Page Faults/sec");
2160 GENGRAPH(select_loops
, "select_loops", "System Select Loop calls/sec");
2161 GENGRAPH(cputime
, "cputime", "CPU utilisation");
2164 #endif /* STAT_GRAPHS */
2167 statMemoryAccounted(void)
2169 return memPoolsTotalAllocated();