- added _Redis_ info panel to /setup page for basic monitoring, closed #686

- improved "system index" build procedure, #666
This commit is contained in:
Mark Friedrich
2018-09-15 19:38:13 +02:00
parent bffd22fc27
commit 712764294c
5 changed files with 172 additions and 47 deletions

View File

@@ -144,12 +144,22 @@ class Universe extends Controller {
* @var $system Model\Universe\SystemModel
*/
$system = Model\Universe\BasicUniverseModel::getNew('SystemModel');
$indexData = [];
foreach($systemIds as $systemId){
$system->getById($systemId);
$system->buildIndex();
$system->reset();
if($hashKeyId = $system->getHashKey()){
$indexData[$hashKeyId] = $system->getData();
}
// offset must increase otherwise we get a endless loop
// -> see /setup ajax build loop function
$offset++;
}
$this->getF3()->mset($indexData, '', $system::CACHE_INDEX_EXPIRE_KEY);
// ... add hashKeys for all table rows to tableIndex as well
$system::buildTableIndex($system, array_keys($indexData));
return ['countAll' => $systemsAll, 'countBuild' => count($systemIds), 'offset' => $offset];
}
@@ -179,15 +189,16 @@ class Universe extends Controller {
/**
* get complete system index (all systems)
* @param bool $all
* @return array
*/
public function getSystemsIndex() : array {
public function getSystemsIndex(bool $all = false) : array {
$index = [];
$cacheKeyTable = Model\Universe\BasicUniverseModel::generateHashKeyTable('system');
if($this->getF3()->exists($cacheKeyTable,$cacheKeys)){
foreach((array)$cacheKeys as $cacheKeyRow){
if(($data = $this->get($cacheKeyRow)) && is_object($data)){
$index[$data->id] = $data;
$index[] = $all ? $data : $data->id;
}
}
}

View File

@@ -166,13 +166,7 @@ class Setup extends Controller {
$f3->set('tplJsView', 'setup');
// set render functions (called within template)
$f3->set('cacheType', function(){
$cacheType = $this->getF3()->get('CACHE');
if( strpos($cacheType, 'redis') !== false ){
$cacheType = 'redis';
}
return $cacheType;
});
$f3->set('cacheType', $this->getCacheType($f3));
// simple counter (called within template)
$counter = 0;
@@ -188,6 +182,19 @@ class Setup extends Controller {
echo \Template::instance()->render( Config::getPathfinderData('view.index') );
}
/**
* get Cache backend type for F3
* @param \Base $f3
* @return string
*/
protected function getCacheType(\Base &$f3) : string {
$cacheType = $f3->get('CACHE');
if(strpos($cacheType, 'redis') !== false){
$cacheType = 'redis';
}
return $cacheType;
}
/**
* main setup route handler
* works as dispatcher for setup functions
@@ -255,6 +262,9 @@ class Setup extends Controller {
// set cache size
$f3->set('cacheSize', $this->getCacheData($f3));
// set Redis config check information
$f3->set('checkRedisConfig', $this->checkRedisConfig($f3));
}
/**
@@ -337,8 +347,8 @@ class Setup extends Controller {
'value' => $f3->get('PORT')
],
'protocol' => [
'label' => 'Protocol',
'value' => strtoupper( $f3->get('SCHEME') )
'label' => 'Protocol - scheme',
'value' => $f3->get('SERVER.SERVER_PROTOCOL') . ' - ' . $f3->get('SCHEME')
]
];
@@ -431,11 +441,8 @@ class Setup extends Controller {
'version' => (extension_loaded('curl') && function_exists('curl_version')) ? 'installed' : 'missing',
'check' => (extension_loaded('curl') && function_exists('curl_version'))
],
[
'label' => 'Redis Server [optional]'
],
'ext_redis' => [
'label' => 'Redis',
'label' => 'Redis [optional]',
'required' => $f3->get('REQUIREMENTS.PHP.REDIS'),
'version' => extension_loaded('redis') ? phpversion('redis') : 'missing',
'check' => version_compare( phpversion('redis'), $f3->get('REQUIREMENTS.PHP.REDIS'), '>='),
@@ -593,6 +600,81 @@ class Setup extends Controller {
return $phpConfig;
}
/**
* check Redis (cache) config
* -> only visible if Redis is used as Cache backend
* @param \Base $f3
* @return array
*/
protected function checkRedisConfig(\Base $f3): array {
$redisConfig = [];
if($this->getCacheType($f3) === 'redis'){
// we need to access the "protected" member $ref from F3´s Cache class
// to get access to the underlying Redis() class
$ref = new \ReflectionObject($cache = \Cache::instance());
$prop = $ref->getProperty('ref');
$prop->setAccessible(true);
/**
* @var $redis \Redis
*/
$redis = $prop->getValue($cache);
$redisServerInfo = (array)$redis->info('SERVER');
$redisMemoryInfo = (array)$redis->info('MEMORY');
$redisStatsInfo = (array)$redis->info('STATS');
$redisConfig = [
'redisVersion' => [
'label' => 'redis_version',
'required' => number_format((float)$f3->get('REQUIREMENTS.REDIS.VERSION'), 1, '.', ''),
'version' => $redisServerInfo['redis_version'],
'check' => version_compare( $redisServerInfo['redis_version'], $f3->get('REQUIREMENTS.REDIS.VERSION'), '>='),
'tooltip' => 'Redis server version'
],
'maxMemory' => [
'label' => 'maxmemory',
'required' => $this->convertBytes($f3->get('REQUIREMENTS.REDIS.MAX_MEMORY')),
'version' => $this->convertBytes($redisMemoryInfo['maxmemory']),
'check' => $redisMemoryInfo['maxmemory'] >= $f3->get('REQUIREMENTS.REDIS.MAX_MEMORY'),
'tooltip' => 'Max memory limit for Redis'
],
'usedMemory' => [
'label' => 'used_memory',
'version' => $this->convertBytes($redisMemoryInfo['used_memory']),
'check' => $redisMemoryInfo['used_memory'] < $redisMemoryInfo['maxmemory'],
'tooltip' => 'Current memory used by Redis'
],
'usedMemoryPeak' => [
'label' => 'used_memory_peak',
'version' => $this->convertBytes($redisMemoryInfo['used_memory_peak']),
'check' => $redisMemoryInfo['used_memory_peak'] <= $redisMemoryInfo['maxmemory'],
'tooltip' => 'Peak memory used by Redis'
],
'maxmemoryPolicy' => [
'label' => 'maxmemory_policy',
'required' => $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
'version' => $redisMemoryInfo['maxmemory_policy'],
'check' => $redisMemoryInfo['maxmemory_policy'] == $f3->get('REQUIREMENTS.REDIS.MAXMEMORY_POLICY'),
'tooltip' => 'How Redis behaves if \'maxmemory\' limit reached'
],
'evictedKeys' => [
'label' => 'evicted_keys',
'version' => $redisStatsInfo['evicted_keys'],
'check' => !(bool)$redisStatsInfo['evicted_keys'],
'tooltip' => 'Number of evicted keys due to maxmemory limit'
],
'dbSize' . $redis->getDbNum() => [
'label' => 'Size DB (' . $redis->getDbNum() . ')',
'version' => $redis->dbSize(),
'check' => $redis->dbSize() > 0,
'tooltip' => 'Keys found in DB (' . $redis->getDbNum() . ') [Cache DB]'
]
];
}
return $redisConfig;
}
/**
* check system environment vars
* -> mostly relevant for development/build/deployment
@@ -1419,8 +1501,8 @@ class Setup extends Controller {
$result = '0';
if($bytes){
$base = log($bytes, 1024);
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
$result = round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)];
$suffixes = array('', 'KB', 'M', 'GB', 'TB');
$result = round(pow(1024, $base - floor($base)), $precision) .''. $suffixes[floor($base)];
}
return $result;
}

View File

@@ -100,28 +100,32 @@ abstract class BasicUniverseModel extends BasicModel {
*/
public function buildIndex(){
$data = null;
if($hashKeyId = $this->getHashKey()){
$hashKeyTable = self::generateHashKeyTable($this->getTable());
if( !self::existsCacheValue($hashKeyTable, $cachedData) ){
$cachedData = [];
}
if( !in_array($hashKeyId, $cachedData) ){
$cachedData[] = $hashKeyId;
}
$data = $this->getData();
$this->getF3()->set($hashKeyId, $data, self::CACHE_INDEX_EXPIRE_KEY);
// straight into cache (no $f->set() ), no sync with hive here -> save ram
self::setCacheValue($hashKeyId, $data, self::CACHE_INDEX_EXPIRE_KEY);
self::setCacheValue($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
// ... add hashKey for this rows to tableIndex as well
self::buildTableIndex($this, [$hashKeyId]);
}
return $data;
}
/**
* add $rowKeys (hashKeys) to a search index that holds all rowKeys of a table
* @param BasicUniverseModel $model
* @param array $rowKeys
*/
public static function buildTableIndex(BasicUniverseModel $model, array $rowKeys = []){
$hashKeyTable = self::generateHashKeyTable($model->getTable());
if( !self::getF3()->exists($hashKeyTable, $cachedData) ){
$cachedData = [];
}
$cachedData = array_unique(array_merge($cachedData, $rowKeys));
self::getF3()->set($hashKeyTable, $cachedData, self::CACHE_INDEX_EXPIRE_KEY);
}
/**
* get data from "search" index for this model
* -> if data not found -> try to build up index for this model

View File

@@ -9,7 +9,6 @@ APACHE.VERSION = 2.5
NGINX.VERSION = 1.9
[REQUIREMENTS.PHP]
; recommended is >= 5.6
VERSION = 7.0
; 64-bit version of PHP (4 = 32-bit, 8 = 64-bit)
@@ -50,7 +49,6 @@ MAX_INPUT_VARS = 3000
HTML_ERRORS = 0
[REQUIREMENTS.LIBS]
ZMQ = 4.1.3
[REQUIREMENTS.MYSQL]
@@ -72,6 +70,14 @@ COLLATION_DATABASE = utf8_general_ci
COLLATION_CONNECTION = utf8_general_ci
FOREIGN_KEY_CHECKS = ON
[REQUIREMENTS.REDIS]
VERSION = 3.0
; max memory limit (Bytes) "binary" (default: 128M)
MAX_MEMORY = 134217728
; how Redis behaves if "maxmemory" limit reached
; https://redis.io/topics/lru-cache
MAXMEMORY_POLICY = allkeys-lru
[REQUIREMENTS.PATH]
NODE = 6.0
NPM = 3.10.0

View File

@@ -142,10 +142,8 @@
</div>
<div class="col-xs-12 col-md-6 pf-landing-pricing-panel">
{* Server *}
<div class="panel panel-default pricing-big">
<div class="panel-heading text-left">
<h3 class="panel-title">Server</h3>
</div>
@@ -166,6 +164,30 @@
</div>
</div>
{* System Env requirements *}
<check if="{{ @checkSystemConfig }}">
<set requirementsData="{{ @checkSystemConfig }}" />
<div class="panel panel-default pricing-big">
<div class="panel-heading text-left">
<h3 class="panel-title">Environment variables [optional]</h3>
</div>
<div class="panel-body no-padding text-align-center">
<include href="templates/modules/requirements_table.html"/>
</div>
<div class="panel-footer text-align-center">
<check if="{{ !@tplCounter('get') }}">
<true>
<h3 class="panel-title txt-color txt-color-success">OK</h3>
</true>
<false>
<h3 class="panel-title txt-color txt-color-warning">{{ @tplCounter('get') }} Warnings</h3>
</false>
</check>
</div>
</div>
{{ @tplCounter('reset') }}
</check>
</div>
</div>
@@ -204,7 +226,7 @@
<div class="panel panel-default pricing-big">
<div class="panel-heading text-left">
<h3 class="panel-title">PHP configuration</h3>
<h3 class="panel-title">PHP config (php.ini)</h3>
</div>
<div class="panel-body no-padding text-align-center">
<include href="templates/modules/requirements_table.html"/>
@@ -222,13 +244,13 @@
</div>
{{ @tplCounter('reset') }}
{* System Env requirements *}
<check if="{{ @checkSystemConfig }}">
<set requirementsData="{{ @checkSystemConfig }}" />
{* Redis requirements *}
<check if="{{ @checkRedisConfig }}">
<set requirementsData="{{ @checkRedisConfig }}" />
<div class="panel panel-default pricing-big">
<div class="panel-heading text-left">
<h3 class="panel-title">Environment variables [optional]</h3>
<h3 class="panel-title">Redis configuration [optional]</h3>
</div>
<div class="panel-body no-padding text-align-center">
<include href="templates/modules/requirements_table.html"/>
@@ -970,10 +992,10 @@
<kbd class="pull-right">
<check if="{{ @cacheSize.all }}">
<true>
{{ @cacheSize.all }}&nbsp;
{{ @cacheSize.all }}
</true>
<false>
0 KB&nbsp;
0KB
</false>
</check>
</kbd>
@@ -981,7 +1003,7 @@
</div>
<div class="panel-body no-padding">
<check if="{{ @cacheType() == 'redis' }}">
<check if="{{ @cacheType === 'redis' }}">
<div class="btn-group btn-group-justified">
<span class="btn btn-default disabled btn-fake">
Redis cache
@@ -1001,7 +1023,7 @@
{{ @cacheSize.data }}
</true>
<false>
0 KB
0KB
</false>
</check>
</kbd>
@@ -1020,7 +1042,7 @@
{{ @cacheSize.template }}
</true>
<false>
0 KB
0KB
</false>
</check>
</kbd>