Browse Source

slide hits per second and hour

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@522 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 14 years ago
parent
commit
38643f8e5c
  1. 18
      Decompiler.class.php
  2. 6
      admin/common-zh-simplified-utf-8.lang.php
  3. 6
      admin/common-zh-traditional-utf-8.lang.php
  4. 3
      admin/help-en.lang.php
  5. 3
      admin/help-zh-simplified-utf-8.lang.php
  6. 4
      admin/xcache.css
  7. 99
      admin/xcache.php
  8. 15
      admin/xcache.tpl.php
  9. 6
      mkopcode_spec.awk
  10. 2
      phpdc.phpr
  11. 2
      run-xcachetest
  12. 2
      utils.h
  13. 71
      xcache.c
  14. 7
      xcache.h

18
Decompiler.class.php

@ -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 (' . '';
}

6
admin/common-zh-simplified-utf-8.lang.php

@ -27,6 +27,12 @@ $strings = array(
=> '%',
'Hits'
=> '命中',
'Hits 24H'
=> '24H 分布',
'Hits/H'
=> '命中/H',
'Hits/S'
=> '命中/S',
'Misses'
=> '错过',
'Clogs'

6
admin/common-zh-traditional-utf-8.lang.php

@ -27,6 +27,12 @@ $strings = array(
=> '%',
'Hits'
=> '命中',
'Hits 24H'
=> '24H 分布',
'Hits/H'
=> '命中/H',
'Hits/S'
=> '命中/S',
'Misses'
=> '錯過',
'Clogs'

3
admin/help-en.lang.php

@ -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>

3
admin/help-zh-simplified-utf-8.lang.php

@ -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>

4
admin/xcache.css

@ -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; }

99
admin/xcache.php

@ -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);
}
}

15
admin/xcache.tpl.php

@ -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>

6
mkopcode_spec.awk

@ -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
}
}

2
phpdc.phpr

@ -12,7 +12,7 @@ if (!isset($argv)) {
$argc = $_SERVER['argc'];
}
$dc = &new Decompiler();
$dc = new Decompiler();
if (isset($argv[1])) {
$dc->decompileFile($argv[1]);
}

2
run-xcachetest

@ -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

@ -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

@ -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

@ -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…
Cancel
Save