@@ -24,12 +24,7 @@ private function panels(): string {
2424 try {
2525 $ info = $ this ->memcached ->getServerStats ();
2626
27- $ bytes = (int ) $ info ['bytes ' ];
28- $ max_bytes = (int ) $ info ['limit_maxbytes ' ];
29- $ get_hits = (int ) $ info ['get_hits ' ];
30- $ get_misses = (int ) $ info ['get_misses ' ];
31- $ memory_usage = round (($ bytes / $ max_bytes ) * 100 , 2 );
32- $ hit_rate = $ get_hits !== 0 ? round (($ get_hits / ($ get_hits + $ get_misses )) * 100 , 2 ) : 0 ;
27+ $ memory_usage = round (($ info ['bytes ' ] / $ info ['limit_maxbytes ' ]) * 100 , 2 );
3328
3429 $ panels = [
3530 [
@@ -38,31 +33,34 @@ private function panels(): string {
3833 'data ' => [
3934 'Version ' => $ info ['version ' ],
4035 'Open connections ' => $ info ['curr_connections ' ],
41- 'Uptime ' => Format::seconds (( int ) $ info ['uptime ' ]),
36+ 'Uptime ' => Format::seconds ($ info ['uptime ' ]),
4237 ],
4338 ],
4439 [
4540 'title ' => 'Memory ' ,
4641 'data ' => [
47- 'Total ' => Format::bytes ($ max_bytes , 0 ),
48- ['Used ' , Format::bytes ($ bytes ).' ( ' .$ memory_usage .'%) ' , $ memory_usage ],
49- 'Free ' => Format::bytes ($ max_bytes - $ bytes ),
42+ 'Total ' => Format::bytes ($ info [ ' limit_maxbytes ' ] , 0 ),
43+ ['Used ' , Format::bytes ($ info [ ' bytes ' ] ).' ( ' .$ memory_usage .'%) ' , $ memory_usage ],
44+ 'Free ' => Format::bytes ($ info [ ' limit_maxbytes ' ] - $ info [ ' bytes ' ] ),
5045 ],
5146 ],
5247 [
53- 'title ' => 'Stats ' ,
48+ 'title ' => 'Keys ' ,
5449 'data ' => [
55- 'Keys ' => Format::number (count ($ this ->all_keys )),
56- ['Hits / Misses ' , Format::number ($ get_hits ).' / ' .Format::number ($ get_misses ).' (Rate ' .$ hit_rate .'%) ' , $ hit_rate , 'higher ' ],
57- 'Evictions ' => Format::number ((int ) $ info ['evictions ' ]),
50+ 'Current ' => Format::number ($ info ['curr_items ' ]),
51+ 'Total (since start) ' => Format::number ($ info ['total_items ' ]),
52+ 'Evictions ' => Format::number ($ info ['evictions ' ]),
53+ 'Reclaimed ' => Format::number ($ info ['reclaimed ' ]),
54+ 'Expired Unfetched ' => Format::number ($ info ['expired_unfetched ' ]),
55+ 'Evicted Unfetched ' => Format::number ($ info ['evicted_unfetched ' ]),
5856 ],
5957 ],
6058 [
6159 'title ' => 'Connections ' ,
6260 'data ' => [
63- 'Current ' => Format::number (( int ) $ info ['curr_connections ' ]).' / ' .Format::number (( int ) $ info ['max_connections ' ]),
64- 'Total ' => Format::number (( int ) $ info ['total_connections ' ]),
65- 'Rejected ' => Format::number (( int ) $ info ['rejected_connections ' ]),
61+ 'Current ' => Format::number ($ info ['curr_connections ' ]).' / ' .Format::number ($ info ['max_connections ' ]). ' max ' ,
62+ 'Total ' => Format::number ($ info ['total_connections ' ]),
63+ 'Rejected ' => Format::number ($ info ['rejected_connections ' ]),
6664 ],
6765 ],
6866 ];
@@ -88,6 +86,10 @@ private function moreInfo(): string {
8886 try {
8987 $ info = $ this ->memcached ->getServerStats ();
9088
89+ foreach (['settings ' , 'sizes ' , 'conns ' ] as $ type ) {
90+ $ info += [$ type => $ this ->memcached ->getServerStats ($ type )];
91+ }
92+
9193 if (extension_loaded ('memcached ' ) || extension_loaded ('memcache ' )) {
9294 $ memcached = extension_loaded ('memcached ' ) ? 'd ' : '' ;
9395 $ info += Helpers::getExtIniInfo ('memcache ' .$ memcached );
@@ -199,6 +201,7 @@ private function form(): string {
199201
200202 /**
201203 * @return array<int, array<string, string|int>>
204+ * @throws MemcachedException
202205 */
203206 private function getAllKeys (): array {
204207 static $ keys = [];
@@ -208,7 +211,9 @@ private function getAllKeys(): array {
208211
209212 $ time = time ();
210213
211- foreach ($ this ->all_keys as $ key_data ) {
214+ $ all_keys = $ this ->memcached ->getKeys ();
215+
216+ foreach ($ all_keys as $ key_data ) {
212217 $ key_data = $ this ->memcached ->parseLine ($ key_data );
213218
214219 $ key = $ key_data ['key ' ];
@@ -233,19 +238,108 @@ private function getAllKeys(): array {
233238 return $ keys ;
234239 }
235240
241+ private function commandsStats (): string {
242+ try {
243+ $ info = $ this ->memcached ->getServerStats ();
244+
245+ $ rate = static function (int $ hits , int $ total ): float {
246+ return $ hits !== 0 ? round (($ hits / $ total ) * 100 , 2 ) : 0 ;
247+ };
248+
249+ $ get_hit_rate = $ rate ($ info ['get_hits ' ], $ info ['cmd_get ' ]);
250+ $ delete_hit_rate = $ rate ($ info ['delete_hits ' ], $ info ['delete_hits ' ] + $ info ['delete_misses ' ]);
251+ $ incr_hit_rate = $ rate ($ info ['incr_hits ' ], $ info ['incr_hits ' ] + $ info ['incr_misses ' ]);
252+ $ decr_hit_rate = $ rate ($ info ['decr_hits ' ], $ info ['decr_hits ' ] + $ info ['decr_misses ' ]);
253+ $ cas_hit_rate = $ rate ($ info ['cas_hits ' ], $ info ['cas_hits ' ] + $ info ['cas_misses ' ]);
254+ $ touch_hit_rate = $ rate ($ info ['touch_hits ' ], $ info ['cmd_touch ' ]);
255+
256+ $ commands = [
257+ [
258+ 'title ' => 'get ' ,
259+ 'data ' => [
260+ 'Hits ' => Format::number ($ info ['get_hits ' ]),
261+ 'Misses ' => Format::number ($ info ['get_misses ' ]),
262+ ['Hit Rate ' , $ get_hit_rate .'% ' , $ get_hit_rate , 'higher ' ],
263+ ],
264+ ],
265+ [
266+ 'title ' => 'delete ' ,
267+ 'data ' => [
268+ 'Hits ' => Format::number ($ info ['delete_hits ' ]),
269+ 'Misses ' => Format::number ($ info ['delete_misses ' ]),
270+ ['Hit Rate ' , $ delete_hit_rate .'% ' , $ delete_hit_rate , 'higher ' ],
271+ ],
272+ ],
273+ [
274+ 'title ' => 'incr ' ,
275+ 'data ' => [
276+ 'Hits ' => Format::number ($ info ['incr_hits ' ]),
277+ 'Misses ' => Format::number ($ info ['incr_misses ' ]),
278+ ['Hit Rate ' , $ incr_hit_rate .'% ' , $ incr_hit_rate , 'higher ' ],
279+ ],
280+ ],
281+ [
282+ 'title ' => 'decr ' ,
283+ 'data ' => [
284+ 'Hits ' => Format::number ($ info ['decr_hits ' ]),
285+ 'Misses ' => Format::number ($ info ['decr_misses ' ]),
286+ ['Hit Rate ' , $ decr_hit_rate .'% ' , $ decr_hit_rate , 'higher ' ],
287+ ],
288+ ],
289+ [
290+ 'title ' => 'touch ' ,
291+ 'data ' => [
292+ 'Hits ' => Format::number ($ info ['touch_hits ' ]),
293+ 'Misses ' => Format::number ($ info ['touch_misses ' ]),
294+ ['Hit Rate ' , $ touch_hit_rate .'% ' , $ touch_hit_rate , 'higher ' ],
295+ ],
296+ ],
297+ [
298+ 'title ' => 'cas ' ,
299+ 'data ' => [
300+ 'Hits ' => Format::number ($ info ['cas_hits ' ]),
301+ 'Misses ' => Format::number ($ info ['cas_misses ' ]),
302+ ['Hit Rate ' , $ cas_hit_rate .'% ' , $ cas_hit_rate , 'higher ' ],
303+ 'Bad Value ' => $ info ['cas_badval ' ],
304+ ],
305+ ],
306+ [
307+ 'title ' => 'set ' ,
308+ 'data ' => [
309+ 'Total ' => Format::number ($ info ['cmd_set ' ]),
310+ ],
311+ ],
312+ [
313+ 'title ' => 'flush ' ,
314+ 'data ' => [
315+ 'Total ' => Format::number ($ info ['cmd_flush ' ]),
316+ ],
317+ ],
318+ ];
319+ } catch (MemcachedException $ e ) {
320+ $ commands = ['error ' => $ e ->getMessage ()];
321+ }
322+
323+ return $ this ->template ->render ('dashboards/memcached ' , ['commands ' => $ commands ]);
324+ }
325+
236326 /**
237327 * @throws MemcachedException
238328 */
239329 private function mainDashboard (): string {
240- $ keys = $ this ->getAllKeys ();
241-
242330 if (isset ($ _POST ['submit_import_key ' ])) {
243331 Helpers::import (
244332 fn (string $ key ): bool => $ this ->memcached ->exists ($ key ),
245333 fn (string $ key , string $ value , int $ ttl ): bool => $ this ->memcached ->set ($ key , base64_decode ($ value ), $ ttl )
246334 );
247335 }
248336
337+ if (Http::get ('tab ' ) === 'commands_stats ' ) {
338+ return $ this ->commandsStats ();
339+ }
340+
341+ $ keys = $ this ->getAllKeys ();
342+
249343 if (isset ($ _GET ['export_btn ' ])) {
250344 Helpers::export ($ keys , 'memcached_backup ' , fn (string $ key ): string => base64_encode ($ this ->memcached ->getKey ($ key )));
251345 }
@@ -254,7 +348,7 @@ private function mainDashboard(): string {
254348
255349 return $ this ->template ->render ('dashboards/memcached ' , [
256350 'keys ' => $ paginator ->getPaginated (),
257- 'all_keys ' => count ($ this -> all_keys ),
351+ 'all_keys ' => count ($ keys ),
258352 'paginator ' => $ paginator ->render (),
259353 'view_key ' => Http::queryString ([], ['view ' => 'key ' , 'key ' => '__key__ ' ]),
260354 ]);
0 commit comments