Commit 8ecbc348 authored by Ghislain Loas's avatar Ghislain Loas
Browse files

hotline #142649 add memcached status

parent 864f9cf9
Pipeline #15087 passed with stage
in 29 minutes and 8 seconds
- ticket #142649 : Magasin de thèmes : Amélioration des performances du rendu de liste à interactions.
Administration : Ajout d'un écran d'état de l'utilisation de Memcached.
\ No newline at end of file
......@@ -19,8 +19,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Admin_SystemeController extends Zend_Controller_Action {
use Trait_Translator, Trait_StaticFileSystem;
class Admin_SystemeController extends ZendAfi_Controller_Action {
use
Trait_StaticFileSystem,
Trait_TimeSource;
public function webservicesAction() {
$this->view->titre = $this->_('Test des Web Services');
......@@ -274,5 +278,9 @@ class Admin_SystemeController extends Zend_Controller_Action {
public function statusAction() {
$this->view->titre = $this->_('Etat du système');
}
}
?>
\ No newline at end of file
public function memcachedStatusAction() {
$this->view->titre = $this->_('État de la configuration et de l\'utilisation de Memcached à %s', static::getCurrentDateTime());
}
}
\ No newline at end of file
......@@ -158,6 +158,7 @@ class ZendAfi_View_Helper_Admin_ContentNav extends ZendAfi_View_Helper_BaseHelpe
['sendmail_tests', $this->_('Test envoi mails'), '/admin/systeme/mailtest', [], $is_super_admin],
['php', $this->_('Informations système'), '/admin/systeme/phpinfo', [], $is_super_admin],
['memcached', $this->_('Informations Memcached'), '/admin/systeme/memcached-status', [], $is_super_admin],
['image_cache', $this->_('Cache des images'), '/admin/systeme/cacheimages', [], $is_admin],
['migrate_comments', $this->_('Import avis opac2'), '/admin/systeme/importavisopac2',
......
<?php
/**
* Copyright (c) 2012-2021, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
* the Free Software Foundation.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
* along with BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class ZendAfi_View_Helper_Admin_MemcachedStatus extends ZendAfi_View_Helper_BaseHelper {
protected static
$_port,
$_host,
$_memcached;
public function Admin_MemcachedStatus() {
$this->_tag('h1', $this->view->titre);
if ( ! $cache = Storm_Cache::getDefaultZendCache() )
return $this->_tagWarning($this->_('Memcached n\'est pas utilisé.'));
if ( $cache instanceof Storm_Cache_Null)
return $this->_tagWarning($this->_('Memcached n\'est pas utilisé.'));
if ( ! $backend = $cache->getBackend())
return $this->_tagWarning($this->_('Memcached n\'est pas utilisé.'));
if ( (! $backend instanceof Zend_Cache_Backend_Memcached) && (! isset(static::$_memcached)))
return $this->_tagWarning($this->_('Memcached n\'est pas utilisé.'));
$memcached = $this->getMemcached();
$memcached->addServer($this->getHost(), $this->getPort());
$html = [$this->_renderStats($memcached),
$this->_renderSessions($memcached),
$this->_renderLocalStats($memcached)];
return $this->_tag('div', implode($html));
}
protected function _renderStats($memcached) {
$stats = $memcached->getStats();
return
$this->_div(['class' => 'memcached_status_stats'],
$this->_tag('h2',
$this->_('Statistiques globales du server Memcached'))
. $this->_tag('pre', json_encode($stats, JSON_PRETTY_PRINT)));
}
protected function _renderSessions($memcached) {
$keys = $memcached->getAllKeys();
$session_keys =
array_filter($keys,
function($key)
{
return 0 === strpos($key, 'memc.sess.key');
});
$count = count($session_keys);
$locked_sessions =
array_filter($session_keys,
function($key)
{
return false !== strpos($key, '.lock');
});
$count_locked = count($locked_sessions);
return
$this->_div(['class' => 'memcached_status_sessions'],
$this->_tag('h2',
$this->_('Toutes les sessions sur le serveur Memcached'))
. $this->_tagNotice($this->_('Nombre de sessions : %s', $count))
. $this->_tagNotice($this->_('Nombre de sessions bloquée (locked) : %s', $count_locked)));
}
protected function _renderLocalStats($memcached) {
$seed = Bokeh_Engine::getInstance()->getCacheSeed();
$keys = $memcached->getAllKeys();
$local_keys =
array_filter($keys,
function($key) use ($seed)
{
return false !== strpos($key, $seed);
});
$local_keys = array_values($local_keys);
$html = [];
$total = 0;
foreach ($local_keys as $key){
$cache_content = $memcached->get($key);
if ( ! $cache_content) {
$html [] = $this->_tagError($this->_('Memcached::get(%s) a retourné le message suivant : %s',
$key,
$memcached->getResultMessage()));
continue;
}
$cache_content = array_shift($cache_content);
$size = mb_strlen($cache_content);
$cache_content = substr($cache_content, 0, 100);
$html [] =
$this->_tagNotice($this->_('Informations sur la cle %s : ',
$key))
. $this->_tagNotice($this->_('Taille de la valeur : %s ko',
number_format(($size / 1024), 2, ',', ' ')))
. $this->_tag('pre',
$this->_('Les 100 premiers caractères de la valeur: %s',
htmlspecialchars($cache_content)));
$total += $size;
}
return
$this->_div(['class' => 'memcached_status_local'],
$this->_tag('h2',
$this->_('Données de ce site dans le Memcached'))
. $this->_tagNotice($this->_('Clé du site : %s',
Bokeh_Engine::getInstance()->getCacheSeed()))
. $this->_tagNotice($this->_('Clé du site pour le memcached : %s',
(new Storm_Cache)->getRealSeed()))
. $this->_tagNotice($this->_('Taille totale des valeurs en cache: %s ko',
(number_format(($total / 1024), 2, ',', ' '))))
. $this->_tag('h3',
$this->_('Liste des clés pour ce site'))
. $this->_tag('pre',
json_encode($local_keys, JSON_PRETTY_PRINT))
. $this->_tag('h3',
$this->_('Liste des valeurs pour ce site'))
. implode($html)
);
}
public function getMemcached() {
return static::$_memcached
? static::$_memcached
: new \Memcached;
}
public function getHost() {
return static::$_host
? static::$_host
: MEMCACHED_HOST;
}
public function getPort() {
return static::$_port
? static::$_port
: MEMCACHED_PORT;
}
public static function setMemcached($memcached) {
static::$_memcached = $memcached;
}
public static function setHost($host) {
static::$_host = $host;
}
public static function setPort($port) {
static::$_port = $port;
}
}
......@@ -42,6 +42,7 @@ class Bokeh_Engine {
protected
$_cache_seed,
$_warm_up_cache = false,
$_config,
$_front_controller;
......@@ -223,7 +224,19 @@ class Bokeh_Engine {
$backendOptions);
Storm_Cache::setDefaultZendCache($cache);
Storm_Cache::setSeed($this->_config->sgbd->config->dbname.md5(BASE_URL));
$this->setCacheSeed(md5($this->_config->sgbd->config->dbname . BASE_URL));
Storm_Cache::setSeed($this->getCacheSeed());
return $this;
}
public function getCacheSeed() {
return $this->_cache_seed;;
}
public function setCacheSeed($seed) {
$this->_cache_seed = $seed;
return $this;
}
......
Subproject commit 5631ff8b7df25e16b711be08ba4d3ccb25e03bbd
Subproject commit 01c8ba7e46869ea4a85f0ce4ab37d45aea125e1e
......@@ -58,6 +58,7 @@
"thesaurus_init": "../../images/picto/generation_16.png",
"thesaurus_edit": "../../images/picto/generation_16.png",
"testmyopac": "icons/menu/link_24.png",
"memcached": "icons/menu/collections_24.png",
"home": "../../images/picto/icon_home.gif",
"back_to_front": "../../images/picto/profils_16.png",
......
......@@ -61,7 +61,7 @@
"pnb": "../../images/picto/pnb_16.png",
"php": "../../images/picto/php.png",
"memcached": "icons/menu/collections_24.png",
"home": "icons/menu/home_24.png",
"back_to_front": "icons/menu/site_24.png",
......
......@@ -61,6 +61,7 @@
"pnb": "../../images/picto/pnb_16.png",
"php": "../../images/picto/php.png",
"memcached": "icons/menu/collections_24.png",
"home": "icons/menu/home_24.png",
"back_to_front": "icons/menu/site_24.png",
......
......@@ -61,6 +61,7 @@
"pnb": "../../images/picto/pnb_16.png",
"php": "../../images/picto/php.png",
"memcached": "icons/menu/collections_24.png",
"home": "icons/menu/home_24.png",
"back_to_front": "icons/menu/site_24.png",
......
......@@ -88,6 +88,12 @@ class AdminIndexControllerIndexActionTest extends AdminIndexControllerTestCase {
public function menuGaucheShouldContainsTestMyOpac() {
$this->assertXPathContentContains('//li//a', 'Test de mon OPAC');
}
/** @test */
public function menuGaucheShouldContainsInformationsMemcached() {
$this->assertXPathContentContains('//li//a[contains(@href, "/admin/systeme/memcached-status")]', 'Informations Memcached');
}
}
......
......@@ -407,3 +407,153 @@ class Admin_SystemControllerStatusWithErrorDeterminingPublicIpTest extends Admin
$this->assertXPathContentContains('//dt[text()="IP publique"]/following-sibling::dd', 'Unable to connect');
}
}
class Admin_SystemControllerNoMemchaedStatusTest extends Admin_AbstractControllerTestCase {
protected $_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
$this->dispatch('/admin/systeme/memcached-status');
}
/** @test */
public function shouldDisplayTitleMemcachedStatus() {
$this->assertXPathContentContains('//h1', 'État de la configuration et de l\'utilisation de Memcached');
}
/** @test */
public function shouldDisplayMemcachedIsNotEnabled() {
$this->assertXPathContentContains('//p', 'Memcached n\'est pas utilisé.');
}
}
class Admin_SystemControllerMemchaedStatusTest extends Admin_AbstractControllerTestCase {
protected $_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
$memcached = $this
->mock()
->whenCalled('addServer')->with('localhost', 11211)
->answers(true)
->whenCalled('getStats')
->answers([[]])
->whenCalled('getAllKeys')
->answers(['memc.sess.key1',
'memc.sess.key2',
'12345789237OU8787897',
'123457123982987P89É7',
'1234578UIEUIESRT3242'])
->whenCalled('get')->with('12345789237OU8787897')
->answers(['A1924 A211 A8 M1860 Lfre G3 T1 B19 S1 Y19 V19 B20 E33 Y20 V20 B44 Y44 V44 B23 Y23 V23 S2 HNRNR000',
787893724789234])
->whenCalled('get')->with('123457123982987P89É7')
->answers(['a:13:{i:0;a:2:{i:0;i:6;i:1;s:45:"A8 M18435 Lfre G3 T1 B1 S1 E5 Y1 V1 HNRNR0002";}i',
1231312312313])
->whenCalled('get')->with('1234578UIEUIESRT3242')
->answers(false)
->whenCalled('getResultMessage')
->answers('NOT STORED')
->beStrict();
Bokeh_Engine::getInstance()->setCacheSeed('12345');
Storm_Cache::setSeed('12345');
ZendAfi_View_Helper_Admin_MemcachedStatus::setHost('localhost');
ZendAfi_View_Helper_Admin_MemcachedStatus::setPort(11211);
ZendAfi_View_Helper_Admin_MemcachedStatus::setMemcached($memcached);
$factory = $this
->mock()
->whenCalled('getBackend')
->answers($memcached)
->whenCalled('load')->with('12345')
->answers('12345')
->beStrict();
Storm_Cache::setDefaultZendCache($factory);
$this->dispatch('/admin/systeme/memcached-status');
}
public function tearDown() {
Storm_Cache::setDefaultZendCache(null);
}
/** @test */
public function shouldDisplayTitleMemcachedStatus() {
$this->assertXPathContentContains('//h1', 'État de la configuration et de l\'utilisation de Memcached');
}
/** @test */
public function shouldNotDisplayMemcachedIsNotEnabled() {
$this->assertNotXPathContentContains('//p', 'Memcached n\'est pas utilisé.');
}
/** @test */
public function shouldDisplayNumberOfSessions2() {
$this->assertXPathContentContains('//p', 'Nombre de sessions : 2');
}
/** @test */
public function shouldDisplayOthers() {
$this->assertXPathContentContains('//pre', '"12345789237OU8787897"');
}
/** @test */
public function shouldDisplaySeed() {
$this->assertXPathContentContains('//p', 'Clé du site : 12345');
}
/** @test */
public function shouldDisplayRealSeed() {
$this->assertXPathContentContains('//p', 'Clé du site pour le memcached : 12345');
}
/** @test */
public function shouldDisplayTotalSize() {
$this->assertXPathContentContains('//p', 'Taille totale des valeurs en cache: 0,17 ko');
}
/** @test */
public function shouldDisplayValueSize() {
$this->assertXPathContentContains('//p', 'Taille de la valeur : 0,09 ko');
}
/** @test */
public function memcachedGetShouldReturnAnError() {
$this->assertXPathContentContains('//p[@class="error"]', 'Memcached::get(1234578UIEUIESRT3242) a retourné le message suivant : NOT STORED');
}
}
\ No newline at end of file
......@@ -544,7 +544,7 @@ class CatalogueTestOAISpec extends ModelTestCase {
class CatalogueGetNoticesByPreferencesNotRandomTest extends ModelTestCase {
protected $_cache_key = '25d43b0fa219225c79624883f5f7fd99';
protected $_cache_key = 'fixed_seed_ddc31b220940c90625375ed2f381bc8c';
public function setUp() {
parent::setUp();
......
......@@ -254,7 +254,7 @@ class SitoViewHelperCachedTest extends SitoViewHelperTestCase {
/** @test */
public function cacheShouldBeUse() {
$value = (new Storm_Cache())->getCache()->load('2834982d0d27025a7755ea93669e9537');
$value = (new Storm_Cache())->getCache()->load('real_seed_6421da151f69b65d9601ce3c3eb18656');
$this->assertNotEquals(false, $value);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment