php监控memcache

  1 <?php
  2 /*
  3   +----------------------------------------------------------------------+
  4   | PHP Version 5                                                        |
  5   +----------------------------------------------------------------------+
  6   | Copyright (c) 1997-2004 The PHP Group                                |
  7   +----------------------------------------------------------------------+
  8   | This source file is subject to version 3.0 of the PHP license,       |
  9   | that is bundled with this package in the file LICENSE, and is        |
 10   | available through the world-wide-web at the following url:           |
 11   | http://www.php.net/license/3_0.txt.                                  |
 12   | If you did not receive a copy of the PHP license and are unable to   |
 13   | obtain it through the world-wide-web, please send a note to          |
 14   | license@php.net so we can mail you a copy immediately.               |
 15   +----------------------------------------------------------------------+
 16   | Author:  Harun Yayli <harunyayli at gmail.com>                       |
 17   +----------------------------------------------------------------------+
 18 */
 19 
 20 $VERSION='$Id: memcache.php,v 1.1.2.3 2008/08/28 18:07:54 mikl Exp $';
 21 
 22 define('ADMIN_USERNAME','memcache');     // Admin Username
 23 define('ADMIN_PASSWORD','password');      // Admin Password
 24 define('DATE_FORMAT','Y/m/d H:i:s');
 25 define('GRAPH_SIZE',200);
 26 define('MAX_ITEM_DUMP',50);
 27 
 28 $MEMCACHE_SERVERS[] = '127.0.0.1:12000'; // add more as an array
 29 $MEMCACHE_SERVERS[] = '127.0.0.1:12000'; // add more as an array
 30 
 31 
 32 ////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
 33 
 34 ///////////////// Password protect ////////////////////////////////////////////////////////////////
 35 if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
 36            $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {
 37             Header("WWW-Authenticate: Basic realm=\"Memcache Login\"");
 38             Header("HTTP/1.0 401 Unauthorized");
 39 
 40             echo <<<EOB
 41                 <html><body>
 42                 <h1>Rejected!</h1>
 43                 <big>Wrong Username or Password!</big>
 44                 </body></html>
 45 EOB;
 46             exit;
 47 }
 48 
 49 ///////////MEMCACHE FUNCTIONS /////////////////////////////////////////////////////////////////////
 50 
 51 function sendMemcacheCommands($command){
 52     global $MEMCACHE_SERVERS;
 53     $result = array();
 54 
 55     foreach($MEMCACHE_SERVERS as $server){
 56         $strs = explode(':',$server);
 57         $host = $strs[0];
 58         $port = $strs[1];
 59         $result[$server] = sendMemcacheCommand($host,$port,$command);
 60     }
 61     return $result;
 62 }
 63 function sendMemcacheCommand($server,$port,$command){
 64 
 65     $s = @fsockopen($server,$port);
 66     if (!$s){
 67         die("Cant connect to:".$server.':'.$port);
 68     }
 69 
 70     fwrite($s, $command."\r\n");
 71 
 72     $buf='';
 73     while ((!feof($s))) {
 74         $buf .= fgets($s, 256);
 75         if (strpos($buf,"END\r\n")!==false){ // stat says end
 76             break;
 77         }
 78         if (strpos($buf,"DELETED\r\n")!==false || strpos($buf,"NOT_FOUND\r\n")!==false){ // delete says these
 79             break;
 80         }
 81         if (strpos($buf,"OK\r\n")!==false){ // flush_all says ok
 82             break;
 83         }
 84     }
 85     fclose($s);
 86     return parseMemcacheResults($buf);
 87 }
 88 function parseMemcacheResults($str){
 89     
 90     $res = array();
 91     $lines = explode("\r\n",$str);
 92     $cnt = count($lines);
 93     for($i=0; $i< $cnt; $i++){
 94         $line = $lines[$i];
 95         $l = explode(' ',$line,3);
 96         if (count($l)==3){
 97             $res[$l[0]][$l[1]]=$l[2];
 98             if ($l[0]=='VALUE'){ // next line is the value
 99                 $res[$l[0]][$l[1]] = array();
100                 list ($flag,$size)=explode(' ',$l[2]);
101                 $res[$l[0]][$l[1]]['stat']=array('flag'=>$flag,'size'=>$size);
102                 $res[$l[0]][$l[1]]['value']=$lines[++$i];
103             }
104         }elseif($line=='DELETED' || $line=='NOT_FOUND' || $line=='OK'){
105             return $line;
106         }
107     }
108     return $res;
109 
110 }
111 
112 function dumpCacheSlab($server,$slabId,$limit){
113     list($host,$port) = explode(':',$server);
114     $resp = sendMemcacheCommand($host,$port,'stats cachedump '.$slabId.' '.$limit);
115 
116    return $resp;
117 
118 }
119 
120 function flushServer($server){
121     list($host,$port) = explode(':',$server);
122     $resp = sendMemcacheCommand($host,$port,'flush_all');
123     return $resp;
124 }
125 function getCacheItems(){
126  $items = sendMemcacheCommands('stats items');
127  $serverItems = array();
128  $totalItems = array();
129  foreach ($items as $server=>$itemlist){
130     $serverItems[$server] = array();
131     $totalItems[$server]=0;
132     if (!isset($itemlist['STAT'])){
133         continue;
134     }
135 
136     $iteminfo = $itemlist['STAT'];
137 
138     foreach($iteminfo as $keyinfo=>$value){
139         if (preg_match('/items\:(\d+?)\:(.+?)$/',$keyinfo,$matches)){
140             $serverItems[$server][$matches[1]][$matches[2]] = $value;
141             if ($matches[2]=='number'){
142                 $totalItems[$server] +=$value;
143             }
144         }
145     }
146  }
147  return array('items'=>$serverItems,'counts'=>$totalItems);
148 }
149 function getMemcacheStats($total=true){
150     $resp = sendMemcacheCommands('stats');
151     if ($total){
152         $res = array();
153         foreach($resp as $server=>$r){
154             foreach($r['STAT'] as $key=>$row){
155                 if (!isset($res[$key])){
156                     $res[$key]=null;
157                 }
158                 switch ($key){
159                     case 'pid':
160                         $res['pid'][$server]=$row;
161                         break;
162                     case 'uptime':
163                         $res['uptime'][$server]=$row;
164                         break;
165                     case 'time':
166                         $res['time'][$server]=$row;
167                         break;
168                     case 'version':
169                         $res['version'][$server]=$row;
170                         break;
171                     case 'pointer_size':
172                         $res['pointer_size'][$server]=$row;
173                         break;
174                     case 'rusage_user':
175                         $res['rusage_user'][$server]=$row;
176                         break;
177                     case 'rusage_system':
178                         $res['rusage_system'][$server]=$row;
179                         break;
180                     case 'curr_items':
181                         $res['curr_items']+=$row;
182                         break;
183                     case 'total_items':
184                         $res['total_items']+=$row;
185                         break;
186                     case 'bytes':
187                         $res['bytes']+=$row;
188                         break;
189                     case 'curr_connections':
190                         $res['curr_connections']+=$row;
191                         break;
192                     case 'total_connections':
193                         $res['total_connections']+=$row;
194                         break;
195                     case 'connection_structures':
196                         $res['connection_structures']+=$row;
197                         break;
198                     case 'cmd_get':
199                         $res['cmd_get']+=$row;
200                         break;
201                     case 'cmd_set':
202                         $res['cmd_set']+=$row;
203                         break;
204                     case 'get_hits':
205                         $res['get_hits']+=$row;
206                         break;
207                     case 'get_misses':
208                         $res['get_misses']+=$row;
209                         break;
210                     case 'evictions':
211                         $res['evictions']+=$row;
212                         break;
213                     case 'bytes_read':
214                         $res['bytes_read']+=$row;
215                         break;
216                     case 'bytes_written':
217                         $res['bytes_written']+=$row;
218                         break;
219                     case 'limit_maxbytes':
220                         $res['limit_maxbytes']+=$row;
221                         break;
222                     case 'threads':
223                         $res['rusage_system'][$server]=$row;
224                         break;
225                 }
226             }
227         }
228         return $res;
229     }
230     return $resp;
231 }
232 
233 //////////////////////////////////////////////////////
234 
235 //
236 // don't cache this page
237 //
238 header("Cache-Control: no-store, no-cache, must-revalidate");  // HTTP/1.1
239 header("Cache-Control: post-check=0, pre-check=0", false);
240 header("Pragma: no-cache");                                    // HTTP/1.0
241 
242 function duration($ts) {
243     global $time;
244     $years = (int)((($time - $ts)/(7*86400))/52.177457);
245     $rem = (int)(($time-$ts)-($years * 52.177457 * 7 * 86400));
246     $weeks = (int)(($rem)/(7*86400));
247     $days = (int)(($rem)/86400) - $weeks*7;
248     $hours = (int)(($rem)/3600) - $days*24 - $weeks*7*24;
249     $mins = (int)(($rem)/60) - $hours*60 - $days*24*60 - $weeks*7*24*60;
250     $str = '';
251     if($years==1) $str .= "$years year, ";
252     if($years>1) $str .= "$years years, ";
253     if($weeks==1) $str .= "$weeks week, ";
254     if($weeks>1) $str .= "$weeks weeks, ";
255     if($days==1) $str .= "$days day,";
256     if($days>1) $str .= "$days days,";
257     if($hours == 1) $str .= " $hours hour and";
258     if($hours>1) $str .= " $hours hours and";
259     if($mins == 1) $str .= " 1 minute";
260     else $str .= " $mins minutes";
261     return $str;
262 }
263 
264 // create graphics
265 //
266 function graphics_avail() {
267     return extension_loaded('gd');
268 }
269 
270 function bsize($s) {
271     foreach (array('','K','M','G') as $i => $k) {
272         if ($s < 1024) break;
273         $s/=1024;
274     }
275     return sprintf("%5.1f %sBytes",$s,$k);
276 }
277 
278 // create menu entry
279 function menu_entry($ob,$title) {
280     global $PHP_SELF;
281     if ($ob==$_GET['op']){
282         return "<li><a class=\"child_active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
283     }
284     return "<li><a class=\"active\" href=\"$PHP_SELF&op=$ob\">$title</a></li>";
285 }
286 
287 function getHeader(){
288     $header = <<<EOB
289 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
290 <html>
291 <head><title>MEMCACHE INFO</title>
292 <style type="text/css"><!--
293 body { background:white; font-size:100.01%; margin:0; padding:0; }
294 body,p,td,th,input,submit { font-size:0.8em;font-family:arial,helvetica,sans-serif; }
295 * html body   {font-size:0.8em}
296 * html p      {font-size:0.8em}
297 * html td     {font-size:0.8em}
298 * html th     {font-size:0.8em}
299 * html input  {font-size:0.8em}
300 * html submit {font-size:0.8em}
301 td { vertical-align:top }
302 a { color:black; font-weight:none; text-decoration:none; }
303 a:hover { text-decoration:underline; }
304 div.content { padding:1em 1em 1em 1em; position:absolute; width:97%; z-index:100; }
305 
306 h1.memcache { background:rgb(153,153,204); margin:0; padding:0.5em 1em 0.5em 1em; }
307 * html h1.memcache { margin-bottom:-7px; }
308 h1.memcache a:hover { text-decoration:none; color:rgb(90,90,90); }
309 h1.memcache span.logo {
310     background:rgb(119,123,180);
311     color:black;
312     border-right: solid black 1px;
313     border-bottom: solid black 1px;
314     font-style:italic;
315     font-size:1em;
316     padding-left:1.2em;
317     padding-right:1.2em;
318     text-align:right;
319     display:block;
320     width:130px;
321     }
322 h1.memcache span.logo span.name { color:white; font-size:0.7em; padding:0 0.8em 0 2em; }
323 h1.memcache span.nameinfo { color:white; display:inline; font-size:0.4em; margin-left: 3em; }
324 h1.memcache div.copy { color:black; font-size:0.4em; position:absolute; right:1em; }
325 hr.memcache {
326     background:white;
327     border-bottom:solid rgb(102,102,153) 1px;
328     border-style:none;
329     border-top:solid rgb(102,102,153) 10px;
330     height:12px;
331     margin:0;
332     margin-top:1px;
333     padding:0;
334 }
335 
336 ol,menu { margin:1em 0 0 0; padding:0.2em; margin-left:1em;}
337 ol.menu li { display:inline; margin-right:0.7em; list-style:none; font-size:85%}
338 ol.menu a {
339     background:rgb(153,153,204);
340     border:solid rgb(102,102,153) 2px;
341     color:white;
342     font-weight:bold;
343     margin-right:0em;
344     padding:0.1em 0.5em 0.1em 0.5em;
345     text-decoration:none;
346     margin-left: 5px;
347     }
348 ol.menu a.child_active {
349     background:rgb(153,153,204);
350     border:solid rgb(102,102,153) 2px;
351     color:white;
352     font-weight:bold;
353     margin-right:0em;
354     padding:0.1em 0.5em 0.1em 0.5em;
355     text-decoration:none;
356     border-left: solid black 5px;
357     margin-left: 0px;
358     }
359 ol.menu span.active {
360     background:rgb(153,153,204);
361     border:solid rgb(102,102,153) 2px;
362     color:black;
363     font-weight:bold;
364     margin-right:0em;
365     padding:0.1em 0.5em 0.1em 0.5em;
366     text-decoration:none;
367     border-left: solid black 5px;
368     }
369 ol.menu span.inactive {
370     background:rgb(193,193,244);
371     border:solid rgb(182,182,233) 2px;
372     color:white;
373     font-weight:bold;
374     margin-right:0em;
375     padding:0.1em 0.5em 0.1em 0.5em;
376     text-decoration:none;
377     margin-left: 5px;
378     }
379 ol.menu a:hover {
380     background:rgb(193,193,244);
381     text-decoration:none;
382     }
383 
384 
385 div.info {
386     background:rgb(204,204,204);
387     border:solid rgb(204,204,204) 1px;
388     margin-bottom:1em;
389     }
390 div.info h2 {
391     background:rgb(204,204,204);
392     color:black;
393     font-size:1em;
394     margin:0;
395     padding:0.1em 1em 0.1em 1em;
396     }
397 div.info table {
398     border:solid rgb(204,204,204) 1px;
399     border-spacing:0;
400     width:100%;
401     }
402 div.info table th {
403     background:rgb(204,204,204);
404     color:white;
405     margin:0;
406     padding:0.1em 1em 0.1em 1em;
407     }
408 div.info table th a.sortable { color:black; }
409 div.info table tr.tr-0 { background:rgb(238,238,238); }
410 div.info table tr.tr-1 { background:rgb(221,221,221); }
411 div.info table td { padding:0.3em 1em 0.3em 1em; }
412 div.info table td.td-0 { border-right:solid rgb(102,102,153) 1px; white-space:nowrap; }
413 div.info table td.td-n { border-right:solid rgb(102,102,153) 1px; }
414 div.info table td h3 {
415     color:black;
416     font-size:1.1em;
417     margin-left:-0.3em;
418     }
419 .td-0 a , .td-n a, .tr-0 a , tr-1 a {
420     text-decoration:underline;
421 }
422 div.graph { margin-bottom:1em }
423 div.graph h2 { background:rgb(204,204,204);; color:black; font-size:1em; margin:0; padding:0.1em 1em 0.1em 1em; }
424 div.graph table { border:solid rgb(204,204,204) 1px; color:black; font-weight:normal; width:100%; }
425 div.graph table td.td-0 { background:rgb(238,238,238); }
426 div.graph table td.td-1 { background:rgb(221,221,221); }
427 div.graph table td { padding:0.2em 1em 0.4em 1em; }
428 
429 div.div1,div.div2 { margin-bottom:1em; width:35em; }
430 div.div3 { position:absolute; left:40em; top:1em; width:580px; }
431 //div.div3 { position:absolute; left:37em; top:1em; right:1em; }
432 
433 div.sorting { margin:1.5em 0em 1.5em 2em }
434 .center { text-align:center }
435 .aright { position:absolute;right:1em }
436 .right { text-align:right }
437 .ok { color:rgb(0,200,0); font-weight:bold}
438 .failed { color:rgb(200,0,0); font-weight:bold}
439 
440 span.box {
441     border: black solid 1px;
442     border-right:solid black 2px;
443     border-bottom:solid black 2px;
444     padding:0 0.5em 0 0.5em;
445     margin-right:1em;
446 }
447 span.green { background:#60F060; padding:0 0.5em 0 0.5em}
448 span.red { background:#D06030; padding:0 0.5em 0 0.5em }
449 
450 div.authneeded {
451     background:rgb(238,238,238);
452     border:solid rgb(204,204,204) 1px;
453     color:rgb(200,0,0);
454     font-size:1.2em;
455     font-weight:bold;
456     padding:2em;
457     text-align:center;
458     }
459 
460 input {
461     background:rgb(153,153,204);
462     border:solid rgb(102,102,153) 2px;
463     color:white;
464     font-weight:bold;
465     margin-right:1em;
466     padding:0.1em 0.5em 0.1em 0.5em;
467     }
468 //-->
469 </style>
470 </head>
471 <body>
472 <div class="head">
473     <h1 class="memcache">
474         <span class="logo"><a href="http://pecl.php.net/package/memcache">memcache</a></span>
475         <span class="nameinfo">memcache.php by <a href="http://livebookmark.net">Harun Yayli</a></span>
476     </h1>
477     <hr class="memcache">
478 </div>
479 <div class=content>
480 EOB;
481 
482     return $header;
483 }
484 function getFooter(){
485     global $VERSION;
486     $footer = '</div><!-- Based on apc.php '.$VERSION.'--></body>
487 </html>
488 ';
489 
490     return $footer;
491 
492 }
493 function getMenu(){
494     global $PHP_SELF;
495 echo "<ol class=menu>";
496 if ($_GET['op']!=4){
497 echo <<<EOB
498     <li><a href="$PHP_SELF&op={$_GET['op']}">Refresh Data</a></li>
499 EOB;
500 }
501 else {
502 echo <<<EOB
503     <li><a href="$PHP_SELF&op=2}">Back</a></li>
504 EOB;
505 }
506 echo
507     menu_entry(1,'View Host Stats'),
508     menu_entry(2,'Variables');
509 
510 echo <<<EOB
511     </ol>
512     <br/>
513 EOB;
514 }
515 
516 // TODO, AUTH
517 
518 $_GET['op'] = !isset($_GET['op'])? '1':$_GET['op'];
519 $PHP_SELF= isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'],'')) : '';
520 
521 $PHP_SELF=$PHP_SELF.'?';
522 $time = time();
523 // sanitize _GET
524 
525 foreach($_GET as $key=>$g){
526     $_GET[$key]=htmlentities($g);
527 }
528 
529 
530 // singleout
531 // when singleout is set, it only gives details for that server.
532 if (isset($_GET['singleout']) && $_GET['singleout']>=0 && $_GET['singleout'] <count($MEMCACHE_SERVERS)){
533     $MEMCACHE_SERVERS = array($MEMCACHE_SERVERS[$_GET['singleout']]);
534 }
535 
536 // display images
537 if (isset($_GET['IMG'])){
538     $memcacheStats = getMemcacheStats();
539     $memcacheStatsSingle = getMemcacheStats(false);
540 
541     if (!graphics_avail()) {
542         exit(0);
543     }
544 
545     function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') {
546         global $col_black;
547         $x1=$x+$w-1;
548         $y1=$y+$h-1;
549 
550         imagerectangle($im, $x, $y1, $x1+1, $y+1, $col_black);
551         if($y1>$y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
552         else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
553         imagerectangle($im, $x, $y1, $x1, $y, $color1);
554         if ($text) {
555             if ($placeindex>0) {
556 
557                 if ($placeindex<16)
558                 {
559                     $px=5;
560                     $py=$placeindex*12+6;
561                     imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2);
562                     imageline($im,$x,$y+$h/2,$px+90,$py,$color2);
563                     imagestring($im,2,$px,$py-6,$text,$color1);
564 
565                 } else {
566                     if ($placeindex<31) {
567                         $px=$x+40*2;
568                         $py=($placeindex-15)*12+6;
569                     } else {
570                         $px=$x+40*2+100*intval(($placeindex-15)/15);
571                         $py=($placeindex%15)*12+6;
572                     }
573                     imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2);
574                     imageline($im,$x+$w,$y+$h/2,$px,$py,$color2);
575                     imagestring($im,2,$px+2,$py-6,$text,$color1);
576                 }
577             } else {
578                 imagestring($im,4,$x+5,$y1-16,$text,$color1);
579             }
580         }
581     }
582 
583 
584     function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$color2,$text='',$placeindex=0) {
585         $r=$diameter/2;
586         $w=deg2rad((360+$start+($end-$start)/2)%360);
587 
588 
589         if (function_exists("imagefilledarc")) {
590             // exists only if GD 2.0.1 is avaliable
591             imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
592             imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
593             imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL|IMG_ARC_EDGED);
594         } else {
595             imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
596             imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
597             imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start+1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
598             imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end-1))   * $r, $centerY + sin(deg2rad($end))   * $r, $color2);
599             imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end))   * $r, $centerY + sin(deg2rad($end))   * $r, $color2);
600             imagefill($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2, $color2);
601         }
602         if ($text) {
603             if ($placeindex>0) {
604                 imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1);
605                 imagestring($im,4,$diameter, $placeindex*12,$text,$color1);
606 
607             } else {
608                 imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1);
609             }
610         }
611     }
612     $size = GRAPH_SIZE; // image size
613     $image = imagecreate($size+50, $size+10);
614 
615     $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
616     $col_red   = imagecolorallocate($image, 0xD0, 0x60,  0x30);
617     $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
618     $col_black = imagecolorallocate($image,   0,   0,   0);
619 
620     imagecolortransparent($image,$col_white);
621 
622     switch ($_GET['IMG']){
623         case 1: // pie chart
624             $tsize=$memcacheStats['limit_maxbytes'];
625             $avail=$tsize-$memcacheStats['bytes'];
626             $x=$y=$size/2;
627             $angle_from = 0;
628             $fuzz = 0.000001;
629 
630             foreach($memcacheStatsSingle as $serv=>$mcs) {
631                 $free = $mcs['STAT']['limit_maxbytes']-$mcs['STAT']['bytes'];
632                 $used = $mcs['STAT']['bytes'];
633 
634 
635                 if ($free>0){
636                 // draw free
637                     $angle_to = ($free*360)/$tsize;
638                     $perc =sprintf("%.2f%%", ($free *100) / $tsize) ;
639 
640                     fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_green,$perc);
641                     $angle_from = $angle_from + $angle_to ;
642                 }
643                 if ($used>0){
644                 // draw used
645                     $angle_to = ($used*360)/$tsize;
646                     $perc =sprintf("%.2f%%", ($used *100) / $tsize) ;
647                     fill_arc($image,$x,$y,$size,$angle_from,$angle_from + $angle_to ,$col_black,$col_red, '('.$perc.')' );
648                     $angle_from = $angle_from+ $angle_to ;
649                 }
650                 }
651 
652         break;
653 
654         case 2: // hit miss
655 
656             $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
657             $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
658             $total = $hits + $misses ;
659 
660                fill_box($image, 30,$size,50,-$hits*($size-21)/$total,$col_black,$col_green,sprintf("%.1f%%",$hits*100/$total));
661             fill_box($image,130,$size,50,-max(4,($total-$hits)*($size-21)/$total),$col_black,$col_red,sprintf("%.1f%%",$misses*100/$total));
662         break;
663         
664     }
665     header("Content-type: image/png");
666     imagepng($image);
667     exit;
668 }
669 
670 echo getHeader();
671 echo getMenu();
672 
673 switch ($_GET['op']) {
674 
675     case 1: // host stats
676         $phpversion = phpversion();
677         $memcacheStats = getMemcacheStats();
678         $memcacheStatsSingle = getMemcacheStats(false);
679 
680         $mem_size = $memcacheStats['limit_maxbytes'];
681         $mem_used = $memcacheStats['bytes'];
682         $mem_avail= $mem_size-$mem_used;
683         $startTime = time()-array_sum($memcacheStats['uptime']);
684 
685         $curr_items = $memcacheStats['curr_items'];
686         $total_items = $memcacheStats['total_items'];
687         $hits = ($memcacheStats['get_hits']==0) ? 1:$memcacheStats['get_hits'];
688         $misses = ($memcacheStats['get_misses']==0) ? 1:$memcacheStats['get_misses'];
689         $sets = $memcacheStats['cmd_set'];
690 
691            $req_rate = sprintf("%.2f",($hits+$misses)/($time-$startTime));
692         $hit_rate = sprintf("%.2f",($hits)/($time-$startTime));
693         $miss_rate = sprintf("%.2f",($misses)/($time-$startTime));
694         $set_rate = sprintf("%.2f",($sets)/($time-$startTime));
695 
696         echo <<< EOB
697         <div class="info div1"><h2>General Cache Information</h2>
698         <table cellspacing=0><tbody>
699         <tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
700 EOB;
701         echo "<tr class=tr-0><td class=td-0>Memcached Host". ((count($MEMCACHE_SERVERS)>1) ? 's':'')."</td><td>";
702         $i=0;
703         if (!isset($_GET['singleout']) && count($MEMCACHE_SERVERS)>1){
704             foreach($MEMCACHE_SERVERS as $server){
705                   echo ($i+1).'. <a href="'.$PHP_SELF.'&singleout='.$i++.'">'.$server.'</a><br/>';
706             }
707         }
708         else{
709             echo '1.'.$MEMCACHE_SERVERS[0];
710         }
711         if (isset($_GET['singleout'])){
712               echo '<a href="'.$PHP_SELF.'">(all servers)</a><br/>';
713         }
714         echo "</td></tr>\n";
715         echo "<tr class=tr-1><td class=td-0>Total Memcache Cache</td><td>".bsize($memcacheStats['limit_maxbytes'])."</td></tr>\n";
716 
717     echo <<<EOB
718         </tbody></table>
719         </div>
720 
721         <div class="info div1"><h2>Memcache Server Information</h2>
722 EOB;
723         foreach($MEMCACHE_SERVERS as $server){
724             echo '<table cellspacing=0><tbody>';
725             echo '<tr class=tr-1><td class=td-1>'.$server.'</td><td><a href="'.$PHP_SELF.'&server='.array_search($server,$MEMCACHE_SERVERS).'&op=6">[<b>Flush this server</b>]</a></td></tr>';
726             echo '<tr class=tr-0><td class=td-0>Start Time</td><td>',date(DATE_FORMAT,$memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
727             echo '<tr class=tr-1><td class=td-0>Uptime</td><td>',duration($memcacheStatsSingle[$server]['STAT']['time']-$memcacheStatsSingle[$server]['STAT']['uptime']),'</td></tr>';
728             echo '<tr class=tr-0><td class=td-0>Memcached Server Version</td><td>'.$memcacheStatsSingle[$server]['STAT']['version'].'</td></tr>';
729             echo '<tr class=tr-1><td class=td-0>Used Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['bytes']),'</td></tr>';
730             echo '<tr class=tr-0><td class=td-0>Total Cache Size</td><td>',bsize($memcacheStatsSingle[$server]['STAT']['limit_maxbytes']),'</td></tr>';
731             echo '</tbody></table>';
732        }
733     echo <<<EOB
734 
735         </div>
736         <div class="graph div3"><h2>Host Status Diagrams</h2>
737         <table cellspacing=0><tbody>
738 EOB;
739 
740     $size='width='.(GRAPH_SIZE+50).' height='.(GRAPH_SIZE+10);
741     echo <<<EOB
742         <tr>
743         <td class=td-0>Cache Usage</td>
744         <td class=td-1>Hits &amp; Misses</td>
745         </tr>
746 EOB;
747 
748     echo
749         graphics_avail() ?
750               '<tr>'.
751               "<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF&IMG=1&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td>".
752               "<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF&IMG=2&".(isset($_GET['singleout'])? 'singleout='.$_GET['singleout'].'&':'')."$time\"></td></tr>\n"
753             : "",
754         '<tr>',
755         '<td class=td-0><span class="green box">&nbsp;</span>Free: ',bsize($mem_avail).sprintf(" (%.1f%%)",$mem_avail*100/$mem_size),"</td>\n",
756         '<td class=td-1><span class="green box">&nbsp;</span>Hits: ',$hits.sprintf(" (%.1f%%)",$hits*100/($hits+$misses)),"</td>\n",
757         '</tr>',
758         '<tr>',
759         '<td class=td-0><span class="red box">&nbsp;</span>Used: ',bsize($mem_used ).sprintf(" (%.1f%%)",$mem_used *100/$mem_size),"</td>\n",
760         '<td class=td-1><span class="red box">&nbsp;</span>Misses: ',$misses.sprintf(" (%.1f%%)",$misses*100/($hits+$misses)),"</td>\n";
761         echo <<< EOB
762     </tr>
763     </tbody></table>
764 <br/>
765     <div class="info"><h2>Cache Information</h2>
766         <table cellspacing=0><tbody>
767         <tr class=tr-0><td class=td-0>Current Items(total)</td><td>$curr_items ($total_items)</td></tr>
768         <tr class=tr-1><td class=td-0>Hits</td><td>{$hits}</td></tr>
769         <tr class=tr-0><td class=td-0>Misses</td><td>{$misses}</td></tr>
770         <tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate cache requests/second</td></tr>
771         <tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate cache requests/second</td></tr>
772         <tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate cache requests/second</td></tr>
773         <tr class=tr-0><td class=td-0>Set Rate</td><td>$set_rate cache requests/second</td></tr>
774         </tbody></table>
775         </div>
776 
777 EOB;
778 
779     break;
780 
781     case 2: // variables
782 
783         $m=0;
784         $cacheItems= getCacheItems();
785         $items = $cacheItems['items'];
786         $totals = $cacheItems['counts'];
787         $maxDump = MAX_ITEM_DUMP;
788         foreach($items as $server => $entries) {
789 
790         echo <<< EOB
791 
792             <div class="info"><table cellspacing=0><tbody>
793             <tr><th colspan="2">$server</th></tr>
794             <tr><th>Slab Id</th><th>Info</th></tr>
795 EOB;
796 
797             foreach($entries as $slabId => $slab) {
798                 $dumpUrl = $PHP_SELF.'&op=2&server='.(array_search($server,$MEMCACHE_SERVERS)).'&dumpslab='.$slabId;
799                 echo
800                     "<tr class=tr-$m>",
801                     "<td class=td-0><center>",'<a href="',$dumpUrl,'">',$slabId,'</a>',"</center></td>",
802                     "<td class=td-last><b>Item count:</b> ",$slab['number'],'<br/><b>Age:</b>',duration($time-$slab['age']),'<br/> <b>Evicted:</b>',((isset($slab['evicted']) && $slab['evicted']==1)? 'Yes':'No');
803                     if ((isset($_GET['dumpslab']) && $_GET['dumpslab']==$slabId) &&  (isset($_GET['server']) && $_GET['server']==array_search($server,$MEMCACHE_SERVERS))){
804                         echo "<br/><b>Items: item</b><br/>";
805                         $items = dumpCacheSlab($server,$slabId,$slab['number']);
806                         // maybe someone likes to do a pagination here :)
807                         $i=1;
808                         foreach($items['ITEM'] as $itemKey=>$itemInfo){
809                             $itemInfo = trim($itemInfo,'[ ]');
810 
811 
812                             echo '<a href="',$PHP_SELF,'&op=4&server=',(array_search($server,$MEMCACHE_SERVERS)),'&key=',base64_encode($itemKey).'">',$itemKey,'</a>';
813                             if ($i++ % 10 == 0) {
814                                 echo '<br/>';
815                             }
816                             elseif ($i!=$slab['number']+1){
817                                 echo ',';
818                             }
819                         }
820                     }
821 
822                     echo "</td></tr>";
823                 $m=1-$m;
824             }
825         echo <<<EOB
826             </tbody></table>
827             </div><hr/>
828 EOB;
829 }
830         break;
831 
832     break;
833 
834     case 4: //item dump
835         if (!isset($_GET['key']) || !isset($_GET['server'])){
836             echo "No key set!";
837             break;
838         }
839         // I'm not doing anything to check the validity of the key string.
840         // probably an exploit can be written to delete all the files in key=base64_encode("\n\r delete all").
841         // somebody has to do a fix to this.
842         $theKey = htmlentities(base64_decode($_GET['key']));
843 
844         $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
845         list($h,$p) = explode(':',$theserver);
846         $r = sendMemcacheCommand($h,$p,'get '.$theKey);
847         echo <<<EOB
848         <div class="info"><table cellspacing=0><tbody>
849             <tr><th>Server<th>Key</th><th>Value</th><th>Delete</th></tr>
850 EOB;
851         echo "<tr><td class=td-0>",$theserver,"</td><td class=td-0>",$theKey,
852              " <br/>flag:",$r['VALUE'][$theKey]['stat']['flag'],
853              " <br/>Size:",bsize($r['VALUE'][$theKey]['stat']['size']),
854              "</td><td>",chunk_split($r['VALUE'][$theKey]['value'],40),"</td>",
855              '<td><a href="',$PHP_SELF,'&op=5&server=',(int)$_GET['server'],'&key=',base64_encode($theKey),"\">Delete</a></td>","</tr>";
856         echo <<<EOB
857             </tbody></table>
858             </div><hr/>
859 EOB;
860     break;
861     case 5: // item delete
862         if (!isset($_GET['key']) || !isset($_GET['server'])){
863             echo "No key set!";
864             break;
865         }
866         $theKey = htmlentities(base64_decode($_GET['key']));
867         $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
868         list($h,$p) = explode(':',$theserver);
869         $r = sendMemcacheCommand($h,$p,'delete '.$theKey);
870         echo 'Deleting '.$theKey.':'.$r;
871     break;
872     
873    case 6: // flush server
874         $theserver = $MEMCACHE_SERVERS[(int)$_GET['server']];
875         $r = flushServer($theserver);
876         echo 'Flush  '.$theserver.":".$r;
877    break;
878 }
879 echo getFooter();
880 
881 ?>

下载地址:memcache.php

posted @ 2013-02-04 15:35  daly2008  阅读(256)  评论(0编辑  收藏  举报