slide hits per second and hour
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@522 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
This commit is contained in:
parent
a148ea51f3
commit
38643f8e5c
|
@ -28,8 +28,8 @@ function str($src, $indent = '') // {{{
|
|||
|
||||
if (is_array($src)) {
|
||||
die_error('array str');
|
||||
$src = new Decompiler_Array($src);
|
||||
return $src->__toString($indent);
|
||||
$src = new Decompiler_Array($src, false, $indent);
|
||||
return $src->__toString();
|
||||
}
|
||||
|
||||
if (is_object($src)) {
|
||||
|
@ -164,9 +164,9 @@ class Decompiler_Box // {{{
|
|||
$this->obj = &$obj;
|
||||
}
|
||||
|
||||
function __toString($indent)
|
||||
function __toString()
|
||||
{
|
||||
return $this->obj->__toString($indent);
|
||||
return $this->obj->__toString();
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
@ -257,17 +257,19 @@ class Decompiler_ListBox extends Decompiler_Box // {{{
|
|||
class Decompiler_Array extends Decompiler_Value // {{{
|
||||
{
|
||||
var $needExport = false;
|
||||
var $indent = '';
|
||||
|
||||
function Decompiler_Array($value = array(), $needexport = false)
|
||||
function Decompiler_Array($value = array(), $needexport = false, $indent = '')
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->needExport = $needexport;
|
||||
$this->indent = $indent;
|
||||
}
|
||||
|
||||
function __toString($indent)
|
||||
function __toString()
|
||||
{
|
||||
$exp = "array(";
|
||||
$indent .= INDENT;
|
||||
$indent = $this->indent . INDENT;
|
||||
$assoclen = 0;
|
||||
$multiline = 0;
|
||||
$i = 0;
|
||||
|
@ -334,7 +336,7 @@ class Decompiler_ForeachBox extends Decompiler_Box // {{{
|
|||
{
|
||||
var $iskey;
|
||||
|
||||
function __toString($indent)
|
||||
function __toString()
|
||||
{
|
||||
return 'foreach (' . '';
|
||||
}
|
||||
|
|
|
@ -27,6 +27,12 @@ $strings = array(
|
|||
=> '%',
|
||||
'Hits'
|
||||
=> '命中',
|
||||
'Hits 24H'
|
||||
=> '24H 分布',
|
||||
'Hits/H'
|
||||
=> '命中/H',
|
||||
'Hits/S'
|
||||
=> '命中/S',
|
||||
'Misses'
|
||||
=> '错过',
|
||||
'Clogs'
|
||||
|
|
|
@ -27,6 +27,12 @@ $strings = array(
|
|||
=> '%',
|
||||
'Hits'
|
||||
=> '命中',
|
||||
'Hits 24H'
|
||||
=> '24H 分布',
|
||||
'Hits/H'
|
||||
=> '命中/H',
|
||||
'Hits/S'
|
||||
=> '命中/S',
|
||||
'Misses'
|
||||
=> '錯過',
|
||||
'Clogs'
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<dt><?php echo _T('Clear'); ?>: </dt><dd>Clear Button, Press the button to clean this cache</dd>
|
||||
<dt><?php echo _T('Compiling'); ?>: </dt><dd>Compiling flag, "yes" if the cache is busy compiling php script</dd>
|
||||
<dt><?php echo _T('Hits'); ?>: </dt><dd>Cache Hits, hit=a var/php is loaded from this cache</dd>
|
||||
<dt><?php echo _T('Hits/H'); ?>: </dt><dd>Average Hits per Hour. Only last 24 hours is logged</dd>
|
||||
<dt><?php echo _T('Hits 24H'); ?>: </dt><dd>Hits 24 Hours. Hits graph of last 24 hours</dd>
|
||||
<dt><?php echo _T('Hits/S'); ?>: </dt><dd>Average Hits per Second. Only last 5 seconds is logged</dd>
|
||||
<dt><?php echo _T('Misses'); ?>: </dt><dd>Cache Misses, miss=a var/php is requested but not in the cache</dd>
|
||||
<dt><?php echo _T('Clogs'); ?>: </dt><dd>Compiling Clogs, clog=compiling is needed but avoided to wait(be blocked) when the cache is busy compiling already</dd>
|
||||
<dt><?php echo _T('OOMs'); ?>: </dt><dd>Out Of Memory, how many times a new item should be stored but there isn't enough memory in the cache, think of increasing the xcache.size or xcache.var_size</dd>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<dt><?php echo _T('Clear'); ?>: </dt><dd>清除按钮, 点击按钮清除对应共享内存区的数据</dd>
|
||||
<dt><?php echo _T('Compiling'); ?>: </dt><dd>编译标记, 当共享内存区正在编译 php 脚本时标记为 "yes"</dd>
|
||||
<dt><?php echo _T('Hits'); ?>: </dt><dd>共享内存命中次数, 命中=从该共享内存载入php或者变量</dd>
|
||||
<dt><?php echo _T('Hits/H'); ?>: </dt><dd>每小时命中次数. 只统计最后 24 小时</dd>
|
||||
<dt><?php echo _T('Hits 24H'); ?>: </dt><dd>24 小时命中分布图. 图表现是最后 24 小时的命中次数</dd>
|
||||
<dt><?php echo _T('Hits/S'); ?>: </dt><dd>每秒命中次数. 只统计最后 5 秒</dd>
|
||||
<dt><?php echo _T('Misses'); ?>: </dt><dd>共享内存错过次数, 错过=请求的php或者变量并不在该共享内存内</dd>
|
||||
<dt><?php echo _T('Clogs'); ?>: </dt><dd>编译阻塞跳过, 阻塞=当需该共享内存区负责编译时, 其他进程/现成无法访问此共享内存. 跳过=XCache 自动判断阻塞的共享内存区自动跳过阻塞等待, 直接使用非共享内存方式继续处理请求</dd>
|
||||
<dt><?php echo _T('OOMs'); ?>: </dt><dd>内存不足次数, 显示需要存储新数据但是共享内存区内存不足的次数. 如果出现太频繁请考虑加大配置中的 xcache.size 或者 xcache.var_size</dd>
|
||||
|
|
|
@ -27,6 +27,10 @@ form {margin: 0; padding: 0}
|
|||
.freeblockgraph div { float: left; height: 3px; width: 4px; border: solid gray; border-width: 0 0px 1px 0; }
|
||||
.freeblockgraph { border: 1px solid gray; border-bottom: 0px; }
|
||||
|
||||
.hitsgraph { height: 20px; border: solid gray; border-width: 1px 0 1px 0; margin: auto; }
|
||||
.hitsgraph div { float: left; width: 2px; height: 100%; }
|
||||
.bitsgraph div div { float: none; width: 100%; }
|
||||
|
||||
.switcher, h1, h2 { text-align: center; display: block; }
|
||||
.switcher * { color: blue; }
|
||||
.switcher a.active { font-weight: bold; font-size: 130%; color: black; }
|
||||
|
|
|
@ -113,6 +113,72 @@ function freeblock_to_graph($freeblocks, $size)
|
|||
return implode('', $html);
|
||||
}
|
||||
|
||||
function calc_total(&$total, $data)
|
||||
{
|
||||
foreach ($data as $k => $v) {
|
||||
switch ($k) {
|
||||
case 'type':
|
||||
case 'cache_name':
|
||||
case 'cacheid':
|
||||
case 'free_blocks':
|
||||
continue 2;
|
||||
}
|
||||
if (!isset($total[$k])) {
|
||||
$total[$k] = $v;
|
||||
}
|
||||
else {
|
||||
switch ($k) {
|
||||
case 'his_by_hour':
|
||||
case 'his_by_second':
|
||||
foreach ($data[$k] as $kk => $vv) {
|
||||
$total[$k][$kk] += $vv;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$total[$k] += $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function array_avg($a)
|
||||
{
|
||||
if (count($a) == 0) {
|
||||
return '';
|
||||
}
|
||||
return array_sum($a) / count($a);
|
||||
}
|
||||
|
||||
function bar_percent($percent)
|
||||
{
|
||||
$r = 220 + (int) ($percent * 25);
|
||||
$g = $b = 220 - (int) ($percent * 220);
|
||||
$percent = (int) ($percent * 100);
|
||||
return '<div>'
|
||||
. '<div style="height: ' . (100 - $percent) . '%"></div>'
|
||||
. '<div style="background: rgb(' . "$r,$g,$b" . '); height: ' . $percent . '%"></div>'
|
||||
. '</div>';
|
||||
}
|
||||
|
||||
function hits_to_graph($hits)
|
||||
{
|
||||
$max = 0;
|
||||
foreach ($hits as $v) {
|
||||
if ($max < $v) {
|
||||
$max = $v;
|
||||
}
|
||||
}
|
||||
if (!$max) {
|
||||
return '';
|
||||
}
|
||||
$html = array();
|
||||
foreach ($hits as $v) {
|
||||
$html[] = bar_percent($v / $max);
|
||||
}
|
||||
return implode('', $html);
|
||||
}
|
||||
|
||||
function switcher($name, $options)
|
||||
{
|
||||
$n = isset($_GET[$name]) ? $_GET[$name] : null;
|
||||
|
@ -195,21 +261,7 @@ for ($i = 0; $i < $pcnt; $i ++) {
|
|||
$data['cacheid'] = $i;
|
||||
$cacheinfos[] = $data;
|
||||
if ($pcnt >= 2) {
|
||||
foreach ($data as $k => $v) {
|
||||
switch ($k) {
|
||||
case 'type':
|
||||
case 'cache_name':
|
||||
case 'cacheid':
|
||||
case 'free_blocks':
|
||||
continue 2;
|
||||
}
|
||||
if (!isset($total[$k])) {
|
||||
$total[$k] = $v;
|
||||
}
|
||||
else {
|
||||
$total[$k] += $v;
|
||||
}
|
||||
}
|
||||
calc_total($total, $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,22 +285,7 @@ for ($i = 0; $i < $vcnt; $i ++) {
|
|||
$data['cacheid'] = $i;
|
||||
$cacheinfos[] = $data;
|
||||
if ($pcnt >= 2) {
|
||||
foreach ($data as $k => $v) {
|
||||
switch ($k) {
|
||||
case 'type':
|
||||
case 'cache_name':
|
||||
case 'cacheid':
|
||||
case 'free_blocks':
|
||||
case 'gc':
|
||||
continue 2;
|
||||
}
|
||||
if (!isset($total[$k])) {
|
||||
$total[$k] = $v;
|
||||
}
|
||||
else {
|
||||
$total[$k] += $v;
|
||||
}
|
||||
}
|
||||
calc_total($total, $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@ $b = new Cycle('class="col1"', 'class="col2"');
|
|||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
|
@ -31,6 +34,9 @@ $b = new Cycle('class="col1"', 'class="col2"');
|
|||
<th><?php echo _T('Clear'); ?></th>
|
||||
<th><?php echo _T('Compiling'); ?></th>
|
||||
<th><?php echo _T('Hits'); ?></th>
|
||||
<th><?php echo _T('Hits/H'); ?></th>
|
||||
<th><?php echo _T('Hits 24H'); ?></th>
|
||||
<th><?php echo _T('Hits/S'); ?></th>
|
||||
<th><?php echo _T('Misses'); ?></th>
|
||||
<th><?php echo _T('Clogs'); ?></th>
|
||||
<th><?php echo _T('OOMs'); ?></th>
|
||||
|
@ -64,6 +70,12 @@ $b = new Cycle('class="col1"', 'class="col2"');
|
|||
$ci_size = size($ci['size']);
|
||||
$ci_avail = size($ci['avail']);
|
||||
$ci = number_formats($ci, $numkeys);
|
||||
|
||||
$hits_avg_h = number_format(array_avg($ci['hits_by_hour']), 2);
|
||||
$hits_avg_s = number_format(array_avg($ci['hits_by_second']), 2);
|
||||
$hits_graph_h = hits_to_graph($ci['hits_by_hour']);
|
||||
$hits_graph_h_w = count($ci['hits_by_hour']) * 2;
|
||||
|
||||
if (!empty($ci['istotal'])) {
|
||||
$ci['compiling'] = '-';
|
||||
$ci['can_readonly'] = '-';
|
||||
|
@ -94,6 +106,9 @@ $b = new Cycle('class="col1"', 'class="col2"');
|
|||
></td>
|
||||
<td>{$ci['compiling']}</td>
|
||||
<td>{$ci['hits']}</td>
|
||||
<td>{$hits_avg_h}</td>
|
||||
<td><div class="hitsgraph" style="width: {$hits_graph_h_w}px">{$hits_graph_h}</div></td>
|
||||
<td>{$hits_avg_s}</td>
|
||||
<td>{$ci['misses']}</td>
|
||||
<td>{$ci['clogs']}</td>
|
||||
<td>{$ci['ooms']}</td>
|
||||
|
|
|
@ -14,7 +14,11 @@ BEGIN {
|
|||
print "error" $0
|
||||
exit
|
||||
}
|
||||
printf "\tOPSPEC(%10s, %10s, %10s, %10s)\n", array[1], array[2], array[3], array[4]
|
||||
comment = "";
|
||||
if (match($0, /\/\* (\d+) \*\//, comments)) {
|
||||
comment = comments[1];
|
||||
}
|
||||
printf "\tOPSPEC(%10s, %10s, %10s, %10s)%s\n", array[1], array[2], array[3], array[4], comment;
|
||||
next
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ if (!isset($argv)) {
|
|||
$argc = $_SERVER['argc'];
|
||||
}
|
||||
|
||||
$dc = &new Decompiler();
|
||||
$dc = new Decompiler();
|
||||
if (isset($argv[1])) {
|
||||
$dc->decompileFile($argv[1]);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ fi
|
|||
test -z "$PHP_SRC" && PHP_SRC=./php-src
|
||||
if test -z "$TEST_PHP_USER" ; then
|
||||
TEST_PHP_USER="$PHP_SRC/tests"
|
||||
for i in Zend ZendEngine2 ext/standard/tests ext/reflection/tests ; do
|
||||
for i in Zend ZendEngine2 ext/standard/tests ext/reflection/tests ext/spl/tests; do
|
||||
if test -d "$PHP_SRC/$i" ; then
|
||||
TEST_PHP_USER="$TEST_PHP_USER,$PHP_SRC/$i"
|
||||
fi
|
||||
|
|
2
utils.h
2
utils.h
|
@ -99,7 +99,7 @@ typedef struct {
|
|||
|
||||
#ifdef E_STRICT
|
||||
int orig_user_error_handler_error_reporting;
|
||||
ZEND_API void (*orig_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
void (*orig_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
zend_uint compilererror_cnt;
|
||||
zend_uint compilererror_size;
|
||||
xc_compilererror_t *compilererrors;
|
||||
|
|
71
xcache.c
71
xcache.c
|
@ -312,6 +312,55 @@ static void xc_entry_hold_var_dmz(xc_entry_t *xce TSRMLS_DC) /* {{{ */
|
|||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
static inline zend_uint advance_wrapped(zend_uint val, zend_uint count) /* {{{ */
|
||||
{
|
||||
if (val + 1 >= count) {
|
||||
return 0;
|
||||
}
|
||||
return val + 1;
|
||||
}
|
||||
/* }}} */
|
||||
static void xc_counters_inc(time_t *curtime, zend_uint *curslot, time_t period, zend_ulong *counters, zend_uint count TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
time_t n = XG(request_time) / period;
|
||||
if (*curtime != n) {
|
||||
zend_uint target_slot = n % count;
|
||||
if (n - *curtime > period) {
|
||||
memset(counters, 0, sizeof(counters[0]) * count);
|
||||
}
|
||||
else {
|
||||
zend_uint slot;
|
||||
for (slot = advance_wrapped(*curslot, count);
|
||||
slot != target_slot;
|
||||
slot = advance_wrapped(slot, count)) {
|
||||
counters[slot] = 0;
|
||||
}
|
||||
counters[target_slot] = 0;
|
||||
}
|
||||
*curtime = n;
|
||||
*curslot = target_slot;
|
||||
}
|
||||
counters[*curslot] ++;
|
||||
}
|
||||
/* }}} */
|
||||
static void xc_cache_hit_dmz(xc_cache_t *cache TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
cache->hits ++;
|
||||
|
||||
xc_counters_inc(&cache->hits_by_hour_cur_time
|
||||
, &cache->hits_by_hour_cur_slot, 60 * 60
|
||||
, cache->hits_by_hour
|
||||
, sizeof(cache->hits_by_hour) / sizeof(cache->hits_by_hour[0])
|
||||
TSRMLS_CC);
|
||||
|
||||
xc_counters_inc(&cache->hits_by_second_cur_time
|
||||
, &cache->hits_by_second_cur_slot
|
||||
, 1
|
||||
, cache->hits_by_second
|
||||
, sizeof(cache->hits_by_second) / sizeof(cache->hits_by_second[0])
|
||||
TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* helper function that loop through each entry */
|
||||
#define XC_ENTRY_APPLY_FUNC(name) int name(xc_entry_t *entry TSRMLS_DC)
|
||||
|
@ -454,7 +503,8 @@ static void xc_gc_deletes(TSRMLS_D) /* {{{ */
|
|||
/* helper functions for user functions */
|
||||
static void xc_fillinfo_dmz(int cachetype, xc_cache_t *cache, zval *return_value TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *blocks;
|
||||
zval *blocks, *hits;
|
||||
int i;
|
||||
const xc_block_t *b;
|
||||
#ifndef NDEBUG
|
||||
xc_memsize_t avail = 0;
|
||||
|
@ -486,6 +536,19 @@ static void xc_fillinfo_dmz(int cachetype, xc_cache_t *cache, zval *return_value
|
|||
else {
|
||||
add_assoc_null_ex(return_value, ZEND_STRS("gc"));
|
||||
}
|
||||
MAKE_STD_ZVAL(hits);
|
||||
array_init(hits);
|
||||
for (i = 0; i < sizeof(cache->hits_by_hour) / sizeof(cache->hits_by_hour[0]); i ++) {
|
||||
add_next_index_long(hits, (long) cache->hits_by_hour[i]);
|
||||
}
|
||||
add_assoc_zval_ex(return_value, ZEND_STRS("hits_by_hour"), hits);
|
||||
|
||||
MAKE_STD_ZVAL(hits);
|
||||
array_init(hits);
|
||||
for (i = 0; i < sizeof(cache->hits_by_second) / sizeof(cache->hits_by_second[0]); i ++) {
|
||||
add_next_index_long(hits, (long) cache->hits_by_second[i]);
|
||||
}
|
||||
add_assoc_zval_ex(return_value, ZEND_STRS("hits_by_second"), hits);
|
||||
|
||||
MAKE_STD_ZVAL(blocks);
|
||||
array_init(blocks);
|
||||
|
@ -1256,7 +1319,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /
|
|||
ENTER_LOCK_EX(cache) {
|
||||
stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC);
|
||||
if (stored_xce) {
|
||||
cache->hits ++;
|
||||
xc_cache_hit_dmz(cache TSRMLS_CC);
|
||||
|
||||
TRACE("hit %s, holding", stored_xce->name.str.val);
|
||||
xc_entry_hold_php_dmz(stored_xce TSRMLS_CC);
|
||||
|
@ -2112,7 +2175,7 @@ PHP_FUNCTION(xcache_get)
|
|||
RETVAL_NULL();
|
||||
} LEAVE_LOCK(xce.cache);
|
||||
if (found) {
|
||||
xce.cache->hits ++;
|
||||
xc_cache_hit_dmz(xce.cache TSRMLS_CC);
|
||||
}
|
||||
else {
|
||||
xce.cache->misses ++;
|
||||
|
@ -2193,7 +2256,7 @@ PHP_FUNCTION(xcache_isset)
|
|||
RETVAL_FALSE;
|
||||
} LEAVE_LOCK(xce.cache);
|
||||
if (found) {
|
||||
xce.cache->hits ++;
|
||||
xc_cache_hit_dmz(xce.cache TSRMLS_CC);
|
||||
}
|
||||
else {
|
||||
xce.cache->misses ++;
|
||||
|
|
7
xcache.h
7
xcache.h
|
@ -223,6 +223,13 @@ typedef struct {
|
|||
|
||||
time_t last_gc_deletes;
|
||||
time_t last_gc_expires;
|
||||
|
||||
time_t hits_by_hour_cur_time;
|
||||
zend_uint hits_by_hour_cur_slot;
|
||||
zend_ulong hits_by_hour[24];
|
||||
time_t hits_by_second_cur_time;
|
||||
zend_uint hits_by_second_cur_slot;
|
||||
zend_ulong hits_by_second[5];
|
||||
} xc_cache_t;
|
||||
/* }}} */
|
||||
/* {{{ xc_classinfo_t */
|
||||
|
|
Loading…
Reference in New Issue