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