| * | Rasmus Lerdorf | * | Ilia Alshanetsky | * +----------------------------------------------------------------------+ * * All other licensing and usage conditions are those of the PHP Group. * * Based on https://github.com/krakjoe/apcu/blob/master/apc.php * Implemented into Froxlor: Janos Muzsi * */ define('AREA', 'admin'); require './lib/init.php'; $horizontal_bar_size = 950; // 1280px window width if ($action == 'delete' && function_exists('apcu_clear_cache') && $userinfo['change_serversettings'] == '1') { apcu_clear_cache(); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "cleared APCu cache"); header('Location: ' . $linker->getLink(array( 'section' => 'apcuinfo', 'page' => 'showinfo' ))); exit(); } if (! function_exists('apcu_cache_info') || ! function_exists('apcu_sma_info')) { \Froxlor\UI\Response::standard_error($lng['error']['no_apcuinfo']); } if ($page == 'showinfo') { $cache = apcu_cache_info(); $mem = apcu_sma_info(); $time = time(); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_apcuinfo"); $passtime = $time - $cache['start_time'] > 0 ? $time - $cache['start_time'] : 1; // zero division $mem_size = $mem['num_seg'] * $mem['seg_size']; $mem_avail = $mem['avail_mem']; $mem_used = $mem_size - $mem_avail; $seg_size = bsize($mem['seg_size']); $sharedmem = sprintf($lng['apcuinfo']['sharedmemval'], $mem['num_seg'], $seg_size, $cache['memory_type']); $req_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits'] + $cache['num_misses']) / $passtime) : 0); $hit_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits']) / $passtime) : 0); $miss_rate_user = sprintf("%.2f", $cache['num_misses'] ? (($cache['num_misses']) / $passtime) : 0); $insert_rate_user = sprintf("%.2f", $cache['num_inserts'] ? (($cache['num_inserts']) / $passtime) : 0); $apcversion = phpversion('apcu'); $phpversion = phpversion(); $number_vars = $cache['num_entries']; $starttime = date('Y-m-d H:i:s', $cache['start_time']); $uptime_duration = duration($cache['start_time']); $size_vars = bsize($cache['mem_size']); $num_hits_and_misses = $cache['num_hits'] + $cache['num_misses']; $num_hits_and_misses = 0 >= $num_hits_and_misses ? 1 : $num_hits_and_misses; // check for possible empty values that are used in the templates if (! isset($cache['file_upload_progress'])) { $cache['file_upload_progress'] = $lng['logger']['unknown']; } if (! isset($cache['num_expunges'])) { $cache['num_expunges'] = $lng['logger']['unknown']; } $runtimelines = ''; foreach (ini_get_all('apcu') as $name => $v) { $value = $v['local_value']; eval("\$runtimelines.=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/runtime_line") . "\";"); } $freemem = bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size); $usedmem = bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 100 / $mem_size); $hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / $num_hits_and_misses); $misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / $num_hits_and_misses); // Fragmentation: (freeseg - 1) / total_seg $nseg = $freeseg = $fragsize = $freetotal = 0; for ($i = 0; $i < $mem['num_seg']; $i ++) { $ptr = 0; foreach ($mem['block_lists'][$i] as $block) { if ($block['offset'] != $ptr) { ++ $nseg; } $ptr = $block['offset'] + $block['size']; /* Only consider blocks <5M for the fragmentation % */ if ($block['size'] < (5 * 1024 * 1024)) $fragsize += $block['size']; $freetotal += $block['size']; } $freeseg += count($mem['block_lists'][$i]); } if ($freeseg > 1) { $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize / $freetotal) * 100, bsize($fragsize), bsize($freetotal), $freeseg); } else { $frag = "0%"; } foreach (ini_get_all('apcu') as $name => $v) { $value = $v['local_value']; } $img_src1 = ''; $img_src2 = ''; $img_src3 = ''; if (graphics_avail()) { $img_src = $linker->getLink(array( 'section' => 'apcuinfo', 'page' => 'img1', 'action' => mt_rand(0, 1000000) )); eval("\$img_src1=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); $img_src = $linker->getLink(array( 'section' => 'apcuinfo', 'page' => 'img2', 'action' => mt_rand(0, 1000000) )); eval("\$img_src2=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); $img_src = $linker->getLink(array( 'section' => 'apcuinfo', 'page' => 'img3', 'action' => mt_rand(0, 1000000) )); eval("\$img_src3=\"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/img_line") . "\";"); } eval("echo \"" . \Froxlor\UI\Template::getTemplate("settings/apcuinfo/showinfo") . "\";"); } elseif ($page == 'img1') { $mem = apcu_sma_info(); $size = 460; $image = imagecreate($size + 5, $size + 5); $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); $col_black = imagecolorallocate($image, 0, 0, 0); imagecolortransparent($image, $col_white); $s = $mem['num_seg'] * $mem['seg_size']; $a = $mem['avail_mem']; $x = $y = $size / 2; $fuzz = 0.000001; // This block of code creates the pie chart. It is a lot more complex than you // would expect because we try to visualize any memory fragmentation as well. $angle_from = 0; $string_placement = array(); for ($i = 0; $i < $mem['num_seg']; $i ++) { $ptr = 0; $free = $mem['block_lists'][$i]; uasort($free, 'block_sort'); foreach ($free as $block) { if ($block['offset'] != $ptr) { // Used block $angle_to = $angle_from + ($block['offset'] - $ptr) / $s; if (($angle_to + $fuzz) > 1) $angle_to = 1; if (($angle_to * 360) - ($angle_from * 360) >= 1) { fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); if (($angle_to - $angle_from) > 0.05) { array_push($string_placement, array( $angle_from, $angle_to )); } } $angle_from = $angle_to; } $angle_to = $angle_from + ($block['size']) / $s; if (($angle_to + $fuzz) > 1) $angle_to = 1; if (($angle_to * 360) - ($angle_from * 360) >= 1) { fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_green); if (($angle_to - $angle_from) > 0.05) { array_push($string_placement, array( $angle_from, $angle_to )); } } $angle_from = $angle_to; $ptr = $block['offset'] + $block['size']; } if ($ptr < $mem['seg_size']) { // memory at the end $angle_to = $angle_from + ($mem['seg_size'] - $ptr) / $s; if (($angle_to + $fuzz) > 1) $angle_to = 1; fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red); if (($angle_to - $angle_from) > 0.05) { array_push($string_placement, array( $angle_from, $angle_to )); } } } foreach ($string_placement as $angle) { text_arc($image, $x, $y, $size, $angle[0] * 360, $angle[1] * 360, $col_black, bsize($s * ($angle[1] - $angle[0]))); } header("Content-type: image/png"); imagepng($image); exit(); } elseif ($page == 'img2') { $cache = apcu_cache_info(); $size = $horizontal_bar_size; $image = imagecreate($size + 5, 140); $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); $col_black = imagecolorallocate($image, 0, 0, 0); imagecolortransparent($image, $col_white); $s = $cache['num_hits'] + $cache['num_misses']; $a = $cache['num_hits']; fill_box($image, 1, 10, $s ? ($a * ($size - 21) / $s) : $size, 50, $col_black, $col_green /* , sprintf("%.1f%%", $s ? $cache['num_hits'] * 100 / $s : 0) */ ); fill_box($image, 1, 80, $s ? max(4, ($s - $a) * ($size - 21) / $s) : $size, 50, $col_black, $col_red /* , sprintf("%.1f%%", $s ? $cache['num_misses'] * 100 / $s : 0) */ ); header("Content-type: image/png"); imagepng($image); exit(); } elseif ($page == 'img3') { $mem = apcu_sma_info(); $size = $horizontal_bar_size; $image = imagecreate($size, 70); $col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); $col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30); $col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60); $col_black = imagecolorallocate($image, 0, 0, 0); imagecolortransparent($image, $col_white); $s = $mem['num_seg'] * $mem['seg_size']; $a = $mem['avail_mem']; $x = 10; $y = 0; // This block of code creates the bar chart. It is a lot more complex than you // would expect because we try to visualize any memory fragmentation as well. for ($i = 0; $i < $mem['num_seg']; $i ++) { $ptr = 0; $free = $mem['block_lists'][$i]; uasort($free, 'block_sort'); foreach ($free as $block) { if ($block['offset'] != $ptr) { // Used block $h = ($size - 5) * ($block['offset'] - $ptr) / $s; if ($h > 0) { fill_box($image, $y, $x, $h, 50, $col_black, $col_red); } $y += $h; } $h = ($size - 5) * ($block['size']) / $s; if ($h > 0) { fill_box($image, $y, $x, $h, 50, $col_black, $col_green); } $y += $h; $ptr = $block['offset'] + $block['size']; } if ($ptr < $mem['seg_size']) { // memory at the end $h = ($size - 5) * ($mem['seg_size'] - $ptr) / $s; if ($h > 0) { fill_box($image, $y, $x, $h, 50, $col_black, $col_red, bsize($mem['seg_size'] - $ptr), $j ++); } } } header("Content-type: image/png"); imagepng($image); exit(); } function graphics_avail() { return extension_loaded('gd'); } // pretty printer for byte values // function bsize($s) { foreach (array( '', 'K', 'M', 'G' ) as $i => $k) { if ($s < 1024) break; $s /= 1024; } return sprintf("%5.1f %sBytes", $s, $k); } function duration($ts) { global $time; $years = (int) ((($time - $ts) / (7 * 86400)) / 52.177457); $rem = (int) (($time - $ts) - ($years * 52.177457 * 7 * 86400)); $weeks = (int) (($rem) / (7 * 86400)); $days = (int) (($rem) / 86400) - $weeks * 7; $hours = (int) (($rem) / 3600) - $days * 24 - $weeks * 7 * 24; $mins = (int) (($rem) / 60) - $hours * 60 - $days * 24 * 60 - $weeks * 7 * 24 * 60; $str = ''; if ($years == 1) $str .= "$years year, "; if ($years > 1) $str .= "$years years, "; if ($weeks == 1) $str .= "$weeks week, "; if ($weeks > 1) $str .= "$weeks weeks, "; if ($days == 1) $str .= "$days day,"; if ($days > 1) $str .= "$days days,"; if ($hours == 1) $str .= " $hours hour and"; if ($hours > 1) $str .= " $hours hours and"; if ($mins == 1) $str .= " 1 minute"; else $str .= " $mins minutes"; return $str; } function block_sort($array1, $array2) { if ($array1['offset'] > $array2['offset']) { return 1; } else { return - 1; } } function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $color2, $text = '', $placeindex = 0) { $r = $diameter / 2; $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); if (function_exists("imagefilledarc")) { // exists only if GD 2.0.1 is available imagefilledarc($im, $centerX + 1, $centerY + 1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE); imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL | IMG_ARC_EDGED); } else { imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2); imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start + 1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2); imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end - 1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2); imagefill($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $color2); } if ($text) { if ($placeindex > 0) { imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); } else { imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); } } } function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $text, $placeindex = 0) { $r = $diameter / 2; $w = deg2rad((360 + $start + ($end - $start) / 2) % 360); if ($placeindex > 0) { imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1); imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1); } else { imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1); } } function fill_box($im, $x, $y, $w, $h, $color1, $color2, $text = '', $placeindex = '') { global $col_black; $x1 = $x + $w - 1; $y1 = $y + $h - 1; imagerectangle($im, $x, $y1, $x1 + 1, $y + 1, $col_black); if ($y1 > $y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2); else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2); imagerectangle($im, $x, $y1, $x1, $y, $color1); if ($text) { if ($placeindex > 0) { if ($placeindex < 16) { $px = 5; $py = $placeindex * 12 + 6; imagefilledrectangle($im, $px + 90, $py + 3, $px + 90 - 4, $py - 3, $color2); imageline($im, $x, $y + $h / 2, $px + 90, $py, $color2); imagestring($im, 2, $px, $py - 6, $text, $color1); } else { if ($placeindex < 31) { $px = $x + 40 * 2; $py = ($placeindex - 15) * 12 + 6; } else { $px = $x + 40 * 2 + 100 * intval(($placeindex - 15) / 15); $py = ($placeindex % 15) * 12 + 6; } imagefilledrectangle($im, $px, $py + 3, $px - 4, $py - 3, $color2); imageline($im, $x + $w, $y + $h / 2, $px, $py, $color2); imagestring($im, 2, $px + 2, $py - 6, $text, $color1); } } else { imagestring($im, 4, $x + 5, $y1 - 16, $text, $color1); } } }