r353
Долгожданный новый дизайн от Nightmare git-svn-id: https://torrentpier2.googlecode.com/svn/trunk@353 a8ac35ab-4ca4-ca47-4c2d-a49a94f06293
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
return array (
|
|
||||||
'stats_api' => 'Server',
|
|
||||||
'slabs_api' => 'Server',
|
|
||||||
'items_api' => 'Server',
|
|
||||||
'get_api' => 'Server',
|
|
||||||
'set_api' => 'Server',
|
|
||||||
'delete_api' => 'Server',
|
|
||||||
'flush_all_api' => 'Server',
|
|
||||||
'connection_timeout' => '1',
|
|
||||||
'max_item_dump' => '100',
|
|
||||||
'refresh_rate' => 5,
|
|
||||||
'memory_alert' => '80',
|
|
||||||
'hit_rate_alert' => '90',
|
|
||||||
'eviction_alert' => '0',
|
|
||||||
'file_path' => 'Temp/',
|
|
||||||
'servers' =>
|
|
||||||
array (
|
|
||||||
'Default' =>
|
|
||||||
array (
|
|
||||||
'127.0.0.1:11211' =>
|
|
||||||
array (
|
|
||||||
'hostname' => '127.0.0.1',
|
|
||||||
'port' => '11211',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
|
@ -1,332 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Analysis of memcached command response
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
class Library_Analysis
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Merge two arrays of stats from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
*
|
|
||||||
* @param $array Statistic from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
* @param $stats Statistic from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public static function merge($array, $stats)
|
|
||||||
{
|
|
||||||
# Checking input
|
|
||||||
if(!is_array($array))
|
|
||||||
{
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
elseif(!is_array($stats))
|
|
||||||
{
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Merging Stats
|
|
||||||
foreach($stats as $key => $value)
|
|
||||||
{
|
|
||||||
if(isset($array[$key]) && ($key != 'version') && ($key != 'uptime'))
|
|
||||||
{
|
|
||||||
$array[$key] += $value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$array[$key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Diff two arrays of stats from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
*
|
|
||||||
* @param Array $array Statistic from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
* @param Array $stats Statistic from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public static function diff($array, $stats)
|
|
||||||
{
|
|
||||||
# Checking input
|
|
||||||
if(!is_array($array))
|
|
||||||
{
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
elseif(!is_array($stats))
|
|
||||||
{
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Diff for each key
|
|
||||||
foreach($stats as $key => $value)
|
|
||||||
{
|
|
||||||
if(isset($array[$key]))
|
|
||||||
{
|
|
||||||
$stats[$key] = $value - $array[$key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyse and return memcache stats command
|
|
||||||
*
|
|
||||||
* @param Array $stats Statistic from MemCacheAdmin_ServerCommands::stats()
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public static function stats($stats)
|
|
||||||
{
|
|
||||||
if(!is_array($stats) || (count($stats) == 0))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Command set()
|
|
||||||
$stats['set_rate'] = ($stats['cmd_set'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_set'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Command get()
|
|
||||||
$stats['get_hits_percent'] = ($stats['cmd_get'] == 0) ? ' - ' : sprintf('%.1f', $stats['get_hits'] / $stats['cmd_get'] * 100, 1);
|
|
||||||
$stats['get_misses_percent'] = ($stats['cmd_get'] == 0) ? ' - ' : sprintf('%.1f', $stats['get_misses'] / $stats['cmd_get'] * 100, 1);
|
|
||||||
$stats['get_rate'] = ($stats['cmd_get'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_get'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Command delete(), version > 1.2.X
|
|
||||||
if(isset($stats['delete_hits'], $stats['delete_misses']))
|
|
||||||
{
|
|
||||||
$stats['cmd_delete'] = $stats['delete_hits'] + $stats['delete_misses'];
|
|
||||||
$stats['delete_hits_percent'] = ($stats['cmd_delete'] == 0) ? ' - ' : sprintf('%.1f', $stats['delete_hits'] / $stats['cmd_delete'] * 100, 1);
|
|
||||||
$stats['delete_misses_percent'] = ($stats['cmd_delete'] == 0) ? ' - ' : sprintf('%.1f', $stats['delete_misses'] / $stats['cmd_delete'] * 100, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stats['cmd_delete'] = 0;
|
|
||||||
$stats['delete_hits_percent'] = ' - ';
|
|
||||||
$stats['delete_misses_percent'] = ' - ';
|
|
||||||
}
|
|
||||||
$stats['delete_rate'] = ($stats['cmd_delete'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_delete'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Command cas(), version > 1.2.X
|
|
||||||
if(isset($stats['cas_hits'], $stats['cas_misses'], $stats['cas_badval']))
|
|
||||||
{
|
|
||||||
$stats['cmd_cas'] = $stats['cas_hits'] + $stats['cas_misses'] + $stats['cas_badval'];
|
|
||||||
$stats['cas_hits_percent'] = ($stats['cmd_cas'] == 0) ? ' - ' : sprintf('%.1f', $stats['cas_hits'] / $stats['cmd_cas'] * 100, 1);
|
|
||||||
$stats['cas_misses_percent'] = ($stats['cmd_cas'] == 0) ? ' - ' : sprintf('%.1f', $stats['cas_misses'] / $stats['cmd_cas'] * 100, 1);
|
|
||||||
$stats['cas_badval_percent'] = ($stats['cmd_cas'] == 0) ? ' - ' : sprintf('%.1f', $stats['cas_badval'] / $stats['cmd_cas'] * 100, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stats['cmd_cas'] = 0;
|
|
||||||
$stats['cas_hits_percent'] = ' - ';
|
|
||||||
$stats['cas_misses_percent'] = ' - ';
|
|
||||||
$stats['cas_badval_percent'] = ' - ';
|
|
||||||
}
|
|
||||||
$stats['cas_rate'] = ($stats['cmd_cas'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_cas'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Command increment(), version > 1.2.X
|
|
||||||
if(isset($stats['incr_hits'], $stats['incr_misses']))
|
|
||||||
{
|
|
||||||
$stats['cmd_incr'] = $stats['incr_hits'] + $stats['incr_misses'];
|
|
||||||
$stats['incr_hits_percent'] = ($stats['cmd_incr'] == 0) ? ' - ' : sprintf('%.1f', $stats['incr_hits'] / $stats['cmd_incr'] * 100, 1);
|
|
||||||
$stats['incr_misses_percent'] = ($stats['cmd_incr'] == 0) ? ' - ' : sprintf('%.1f', $stats['incr_misses'] / $stats['cmd_incr'] * 100, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stats['cmd_incr'] = 0;
|
|
||||||
$stats['incr_hits_percent'] = ' - ';
|
|
||||||
$stats['incr_misses_percent'] = ' - ';
|
|
||||||
|
|
||||||
}
|
|
||||||
$stats['incr_rate'] = ($stats['cmd_incr'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_incr'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Command decrement(), version > 1.2.X
|
|
||||||
if(isset($stats['decr_hits'], $stats['decr_misses']))
|
|
||||||
{
|
|
||||||
$stats['cmd_decr'] = $stats['decr_hits'] + $stats['decr_misses'];
|
|
||||||
$stats['decr_hits_percent'] = ($stats['cmd_decr'] == 0) ? ' - ' : sprintf('%.1f', $stats['decr_hits'] / $stats['cmd_decr'] * 100, 1);
|
|
||||||
$stats['decr_misses_percent'] = ($stats['cmd_decr'] == 0) ? ' - ' : sprintf('%.1f', $stats['decr_misses'] / $stats['cmd_decr'] * 100, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stats['cmd_decr'] = 0;
|
|
||||||
$stats['decr_hits_percent'] = ' - ';
|
|
||||||
$stats['decr_misses_percent'] = ' - ';
|
|
||||||
}
|
|
||||||
$stats['decr_rate'] = ($stats['cmd_decr'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_decr'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Total hit & miss
|
|
||||||
#$stats['cmd_total'] = $stats['cmd_get'] + $stats['cmd_set'] + $stats['cmd_delete'] + $stats['cmd_cas'] + $stats['cmd_incr'] + $stats['cmd_decr'];
|
|
||||||
#$stats['hit_percent'] = ($stats['cmd_get'] == 0) ? '0.0' : sprintf('%.1f', ($stats['get_hits']) / ($stats['get_hits'] + $stats['get_misses']) * 100, 1);
|
|
||||||
#$stats['miss_percent'] = ($stats['cmd_get'] == 0) ? '0.0' : sprintf('%.1f', ($stats['get_misses']) / ($stats['get_hits'] + $stats['get_misses']) * 100, 1);
|
|
||||||
|
|
||||||
# Command flush_all
|
|
||||||
if(isset($stats['cmd_flush']))
|
|
||||||
{
|
|
||||||
$stats['flush_rate'] = ($stats['cmd_flush'] == 0) ? '0.0' : sprintf('%.1f', $stats['cmd_flush'] / $stats['uptime'], 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$stats['flush_rate'] = '0.0';
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cache size
|
|
||||||
$stats['bytes_percent'] = ($stats['limit_maxbytes'] == 0) ? '0.0' : sprintf('%.1f', $stats['bytes'] / $stats['limit_maxbytes'] * 100, 1);
|
|
||||||
|
|
||||||
# Request rate
|
|
||||||
$stats['request_rate'] = sprintf('%.1f', ($stats['cmd_get'] + $stats['cmd_set'] + $stats['cmd_delete'] + $stats['cmd_cas'] + $stats['cmd_incr'] + $stats['cmd_decr']) / $stats['uptime'], 1);
|
|
||||||
$stats['hit_rate'] = sprintf('%.1f', ($stats['get_hits']) / $stats['uptime'], 1);
|
|
||||||
$stats['miss_rate'] = sprintf('%.1f', ($stats['get_misses']) / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
# Eviction & reclaimed rate
|
|
||||||
$stats['eviction_rate'] = ($stats['evictions'] == 0) ? '0.0' : sprintf('%.1f', $stats['evictions'] / $stats['uptime'], 1);
|
|
||||||
$stats['reclaimed_rate'] = (!isset($stats['reclaimed']) || ($stats['reclaimed'] == 0)) ? '0.0' : sprintf('%.1f', $stats['reclaimed'] / $stats['uptime'], 1);
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyse and return memcache slabs command
|
|
||||||
*
|
|
||||||
* @param Array $slabs Statistic from MemCacheAdmin_ServerCommands::slabs()
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public static function slabs($slabs)
|
|
||||||
{
|
|
||||||
# Initializing Used Slabs
|
|
||||||
$slabs['used_slabs'] = 0;
|
|
||||||
$slabs['total_wasted'] = 0;
|
|
||||||
# Request Rate par Slabs
|
|
||||||
foreach($slabs as $id => $slab)
|
|
||||||
{
|
|
||||||
# Check if it's a Slab
|
|
||||||
if(is_numeric($id))
|
|
||||||
{
|
|
||||||
# Check if Slab is used
|
|
||||||
if($slab['used_chunks'] > 0)
|
|
||||||
{
|
|
||||||
$slabs['used_slabs']++;
|
|
||||||
}
|
|
||||||
$slabs[$id]['request_rate'] = sprintf('%.1f', ($slab['get_hits'] + $slab['cmd_set'] + $slab['delete_hits'] + $slab['cas_hits'] + $slab['cas_badval'] + $slab['incr_hits'] + $slab['decr_hits']) / $slabs['uptime'], 1);
|
|
||||||
$slabs[$id]['mem_wasted'] = (($slab['total_chunks'] * $slab['chunk_size']) < $slab['mem_requested']) ?(($slab['total_chunks'] - $slab['used_chunks']) * $slab['chunk_size']):(($slab['total_chunks'] * $slab['chunk_size']) - $slab['mem_requested']);
|
|
||||||
$slabs['total_wasted'] += $slabs[$id]['mem_wasted'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $slabs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate Uptime
|
|
||||||
*
|
|
||||||
* @param Integer $uptime Uptime timestamp
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static function uptime($uptime)
|
|
||||||
{
|
|
||||||
if($uptime > 0)
|
|
||||||
{
|
|
||||||
$days = floor($uptime/60/60/24);
|
|
||||||
$hours = $uptime/60/60%24;
|
|
||||||
$mins = $uptime/60%60;
|
|
||||||
if(($days + $hours + $mins) == 0)
|
|
||||||
{
|
|
||||||
return ' less than 1 min';
|
|
||||||
}
|
|
||||||
return $days . ' days ' . $hours . ' hrs ' . $mins . ' min';
|
|
||||||
}
|
|
||||||
return ' - ';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize a byte value
|
|
||||||
*
|
|
||||||
* @param Integer $value Value to resize
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static function byteResize($value)
|
|
||||||
{
|
|
||||||
# Unit list
|
|
||||||
$units = array('', 'K', 'M', 'G', 'T');
|
|
||||||
|
|
||||||
# Resizing
|
|
||||||
foreach($units as $unit)
|
|
||||||
{
|
|
||||||
if($value < 1024)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$value /= 1024;
|
|
||||||
}
|
|
||||||
return sprintf('%.1f %s', $value, $unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize a value
|
|
||||||
*
|
|
||||||
* @param Integer $value Value to resize
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static function valueResize($value)
|
|
||||||
{
|
|
||||||
# Unit list
|
|
||||||
$units = array('', 'K', 'M', 'G', 'T');
|
|
||||||
|
|
||||||
# Resizing
|
|
||||||
foreach($units as $unit)
|
|
||||||
{
|
|
||||||
if($value < 1000)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$value /= 1000;
|
|
||||||
}
|
|
||||||
return sprintf('%.1f%s', $value, $unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resize a hit value
|
|
||||||
*
|
|
||||||
* @param Integer $value Hit value to resize
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static function hitResize($value)
|
|
||||||
{
|
|
||||||
# Unit list
|
|
||||||
$units = array('', 'K', 'M', 'G', 'T');
|
|
||||||
|
|
||||||
# Resizing
|
|
||||||
foreach($units as $unit)
|
|
||||||
{
|
|
||||||
if($value < 10000000)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$value /= 1000;
|
|
||||||
}
|
|
||||||
return sprintf('%.0f%s', $value, $unit);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Factory for communication with Memcache Server
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 30/03/2010
|
|
||||||
*/
|
|
||||||
class Library_Command_Factory
|
|
||||||
{
|
|
||||||
private static $_object = array();
|
|
||||||
|
|
||||||
# No explicit call of constructor
|
|
||||||
private function __construct() {}
|
|
||||||
|
|
||||||
# No explicit call of clone()
|
|
||||||
private function __clone() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor to command class instance by command type
|
|
||||||
*
|
|
||||||
* @param String $command Type of command
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function instance($command)
|
|
||||||
{
|
|
||||||
# Importing configuration
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Instance does not exists
|
|
||||||
if(!isset(self::$_object[$_ini->get($command)]) || ($_ini->get($command) != 'Server'))
|
|
||||||
{
|
|
||||||
# Switching by API
|
|
||||||
switch($_ini->get($command))
|
|
||||||
{
|
|
||||||
case 'Memcache':
|
|
||||||
# PECL Memcache API
|
|
||||||
require_once 'Memcache.php';
|
|
||||||
self::$_object['Memcache'] = new Library_Command_Memcache();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Memcached':
|
|
||||||
# PECL Memcached API
|
|
||||||
require_once 'Memcached.php';
|
|
||||||
self::$_object['Memcached'] = new Library_Command_Memcached();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Server':
|
|
||||||
default:
|
|
||||||
# Server API (eg communicating directly with the memcache server)
|
|
||||||
require_once 'Server.php';
|
|
||||||
self::$_object['Server'] = new Library_Command_Server();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self::$_object[$_ini->get($command)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor to command class instance by type
|
|
||||||
*
|
|
||||||
* @param String $command Type of command
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function api($api)
|
|
||||||
{
|
|
||||||
# Instance does not exists
|
|
||||||
if(!isset(self::$_object[$api]) || ($api != 'Server'))
|
|
||||||
{
|
|
||||||
# Switching by API
|
|
||||||
switch($api)
|
|
||||||
{
|
|
||||||
case 'Memcache':
|
|
||||||
# PECL Memcache API
|
|
||||||
require_once 'Memcache.php';
|
|
||||||
self::$_object['Memcache'] = new Library_Command_Memcache();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Memcached':
|
|
||||||
# PECL Memcached API
|
|
||||||
require_once 'Memcached.php';
|
|
||||||
self::$_object['Memcached'] = new Library_Command_Memcached();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Server':
|
|
||||||
default:
|
|
||||||
# Server API (eg communicating directly with the memcache server)
|
|
||||||
require_once 'Server.php';
|
|
||||||
self::$_object['Server'] = new Library_Command_Server();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self::$_object[$api];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Interface of communication to MemCache Server
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
interface Library_Command_Interface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function __construct();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats command to server
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
function stats($server, $port);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve slabs stats
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
function slabs($server, $port);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve items from a slabs
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Integer $slab Slab ID
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
function items($server, $port, $slab);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send get command to server to retrieve an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to retrieve
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function get($server, $port, $key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to store
|
|
||||||
* @param Mixed $data Data to store
|
|
||||||
* @param Integer $duration Duration
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function set($server, $port, $key, $data, $duration);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to delete
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function delete($server, $port, $key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all items on a server after delay
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Integer $delay Delay before flushing server
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function flush_all($server, $port, $delay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for item
|
|
||||||
* Return all the items matching parameters if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to search
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function search($server, $port, $search);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a telnet command on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $command Command to execute
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function telnet($server, $port, $command);
|
|
||||||
}
|
|
|
@ -1,257 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Sending command to memcache server via PECL memcache API http://pecl.php.net/package/memcache
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
class Library_Command_Memcache implements Library_Command_Interface
|
|
||||||
{
|
|
||||||
private static $_ini;
|
|
||||||
private static $_memcache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param Array $ini Array from ini_parse
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
# Importing configuration
|
|
||||||
self::$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing
|
|
||||||
self::$_memcache = new Memcache();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats command to server
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function stats($server, $port)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command
|
|
||||||
if(($return = self::$_memcache->getExtendedStats()))
|
|
||||||
{
|
|
||||||
# Delete server key based
|
|
||||||
$stats = $return[$server.':'.$port];
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats items command to server to retrieve slabs stats
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function slabs($server, $port)
|
|
||||||
{
|
|
||||||
# Initializing
|
|
||||||
$slabs = array();
|
|
||||||
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : slabs
|
|
||||||
if(($slabs = self::$_memcache->getStats('slabs')))
|
|
||||||
{
|
|
||||||
# Finding uptime
|
|
||||||
$stats = $this->stats($server, $port);
|
|
||||||
$slabs['uptime'] = $stats['uptime'];
|
|
||||||
unset($stats);
|
|
||||||
|
|
||||||
# Executing command : items
|
|
||||||
if(($result = self::$_memcache->getStats('items')))
|
|
||||||
{
|
|
||||||
# Indexing by slabs
|
|
||||||
foreach($result['items'] as $id => $items)
|
|
||||||
{
|
|
||||||
foreach($items as $key => $value)
|
|
||||||
{
|
|
||||||
$slabs[$id]['items:' . $key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $slabs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats cachedump command to server to retrieve slabs items
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Interger $slab Slab ID
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function items($server, $port, $slab)
|
|
||||||
{
|
|
||||||
# Initializing
|
|
||||||
$items = false;
|
|
||||||
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : slabs stats
|
|
||||||
if(($items = self::$_memcache->getStats('cachedump', $slab, self::$_ini->get('max_item_dump'))))
|
|
||||||
{
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send get command to server to retrieve an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to retrieve
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function get($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : get
|
|
||||||
if($item = self::$_memcache->get($key))
|
|
||||||
{
|
|
||||||
return print_r($item, true);
|
|
||||||
}
|
|
||||||
return 'NOT_FOUND';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to store
|
|
||||||
* @param Mixed $data Data to store
|
|
||||||
* @param Integer $duration Duration
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function set($server, $port, $key, $data, $duration)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : set
|
|
||||||
if(self::$_memcache->set($key, $data, 0, $duration))
|
|
||||||
{
|
|
||||||
return 'STORED';
|
|
||||||
}
|
|
||||||
return 'ERROR';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to delete
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function delete($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : delete
|
|
||||||
if(self::$_memcache->delete($key))
|
|
||||||
{
|
|
||||||
return 'DELETED';
|
|
||||||
}
|
|
||||||
return 'NOT_FOUND';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all items on a server
|
|
||||||
* Warning, delay won't work with Memcache API
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Integer $delay Delay before flushing server
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function flush_all($server, $port, $delay)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : flush_all
|
|
||||||
self::$_memcache->flush();
|
|
||||||
return 'OK';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for item
|
|
||||||
* Return all the items matching parameters if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to search
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function search($server, $port, $search)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcache does not support search function, use Server instead');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a telnet command on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $command Command to execute
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function telnet($server, $port, $command)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcache does not support telnet, use Server instead');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,226 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Sending command to memcache server via PECL memcache API http://pecl.php.net/package/memcache
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
class Library_Command_Memcached implements Library_Command_Interface
|
|
||||||
{
|
|
||||||
private static $_ini;
|
|
||||||
private static $_memcache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param Array $ini Array from ini_parse
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
# Importing configuration
|
|
||||||
self::$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing
|
|
||||||
self::$_memcache = new Memcached();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats command to server
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function stats($server, $port)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command
|
|
||||||
if(($return = self::$_memcache->getStats()))
|
|
||||||
{
|
|
||||||
# Delete server key based
|
|
||||||
$stats = $return[$server.':'.$port];
|
|
||||||
|
|
||||||
# Adding value that miss
|
|
||||||
$stats['delete_hits'] = '';
|
|
||||||
$stats['delete_misses'] = '';
|
|
||||||
$stats['incr_hits'] = '';
|
|
||||||
$stats['incr_misses'] = '';
|
|
||||||
$stats['decr_hits'] = '';
|
|
||||||
$stats['decr_misses'] = '';
|
|
||||||
$stats['cas_hits'] = '';
|
|
||||||
$stats['cas_misses'] = '';
|
|
||||||
$stats['cas_badval'] = '';
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats items command to server to retrieve slabs stats
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function slabs($server, $port)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcache does not support slabs stats, use Server or Memcache instead');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats cachedump command to server to retrieve slabs items
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Interger $slab Slab ID
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function items($server, $port, $slab)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcache does not support slabs items stats, use Server or Memcache instead');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send get command to server to retrieve an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to retrieve
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function get($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : get
|
|
||||||
if($item = self::$_memcache->get($key))
|
|
||||||
{
|
|
||||||
return print_r($item, true);
|
|
||||||
}
|
|
||||||
return self::$_memcache->getResultMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to store
|
|
||||||
* @param Mixed $data Data to store
|
|
||||||
* @param Integer $duration Duration
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function set($server, $port, $key, $data, $duration)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Checking duration
|
|
||||||
if($duration == '') { $duration = 0; }
|
|
||||||
|
|
||||||
# Executing command : set
|
|
||||||
self::$_memcache->set($key, $data, $duration);
|
|
||||||
return self::$_memcache->getResultMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to delete
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function delete($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : delete
|
|
||||||
self::$_memcache->delete($key);
|
|
||||||
return self::$_memcache->getResultMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all items on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Integer $delay Delay before flushing server
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function flush_all($server, $port, $delay)
|
|
||||||
{
|
|
||||||
# Adding server
|
|
||||||
self::$_memcache->addServer($server, $port);
|
|
||||||
|
|
||||||
# Executing command : delete
|
|
||||||
self::$_memcache->flush($delay);
|
|
||||||
return self::$_memcache->getResultMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for item
|
|
||||||
* Return all the items matching parameters if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to search
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function search($server, $port, $search)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcached does not support search function, use Server instead');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a telnet command on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $command Command to execute
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function telnet($server, $port, $command)
|
|
||||||
{
|
|
||||||
throw new Exception('PECL Memcached does not support telnet, use Server instead');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,443 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Sending command to memcache server
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
class Library_Command_Server implements Library_Command_Interface
|
|
||||||
{
|
|
||||||
private static $_ini;
|
|
||||||
private static $_log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param Array $ini Array from ini_parse
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
# Importing configuration
|
|
||||||
self::$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executing a Command on a MemCache Server
|
|
||||||
* With the help of http://github.com/memcached/memcached/blob/master/doc/protocol.txt
|
|
||||||
* Return the response, or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $command Command
|
|
||||||
* @param String $server Server Hostname
|
|
||||||
* @param Integer $port Server Port
|
|
||||||
*
|
|
||||||
* @return String|Boolean
|
|
||||||
*/
|
|
||||||
public function exec($command, $server, $port)
|
|
||||||
{
|
|
||||||
# Variables
|
|
||||||
$buffer = '';
|
|
||||||
$handle = null;
|
|
||||||
|
|
||||||
# Socket Opening
|
|
||||||
if(!($handle = @fsockopen($server, $port, $errno, $errstr, self::$_ini->get('connection_timeout'))))
|
|
||||||
{
|
|
||||||
# Adding error to log
|
|
||||||
self::$_log = utf8_encode($errstr);
|
|
||||||
Library_Data_Error::add(utf8_encode($errstr));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sending Command ...
|
|
||||||
fwrite($handle, $command . "\r\n");
|
|
||||||
|
|
||||||
# Getting first line
|
|
||||||
$buffer = fgets($handle);
|
|
||||||
|
|
||||||
# Checking if result is valid
|
|
||||||
if($this->end($buffer))
|
|
||||||
{
|
|
||||||
# Closing socket
|
|
||||||
fclose($handle);
|
|
||||||
|
|
||||||
# Adding error to log
|
|
||||||
self::$_log = $buffer;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Reading Results
|
|
||||||
while((!feof($handle)))
|
|
||||||
{
|
|
||||||
# Getting line
|
|
||||||
$line = fgets($handle);
|
|
||||||
$buffer .= $line;
|
|
||||||
|
|
||||||
# Checking for end of MemCache command
|
|
||||||
if($this->end($line))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Closing socket
|
|
||||||
fclose($handle);
|
|
||||||
|
|
||||||
return $buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if response is at the end from memcache server
|
|
||||||
* Return true if response end, true otherwise
|
|
||||||
*
|
|
||||||
* @param String $buffer Buffer received from memcache server
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
private function end($buffer)
|
|
||||||
{
|
|
||||||
# Checking command response end
|
|
||||||
if(preg_match('/(END|DELETED|OK|ERROR|SERVER_ERROR|CLIENT_ERROR|NOT_FOUND|STORED|RESET)\r\n$/', $buffer))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse result to make an array
|
|
||||||
*
|
|
||||||
* @param String $string String to parse
|
|
||||||
* @param Boolean $string (optionnal) Parsing stats ?
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public function parse($string, $stats = true)
|
|
||||||
{
|
|
||||||
# Variable
|
|
||||||
$return = array();
|
|
||||||
|
|
||||||
# Exploding by \r\n
|
|
||||||
$lines = preg_split('/\r\n/', $string);
|
|
||||||
|
|
||||||
# Stats
|
|
||||||
if($stats)
|
|
||||||
{
|
|
||||||
# Browsing each line
|
|
||||||
foreach($lines as $line)
|
|
||||||
{
|
|
||||||
$data = preg_split('/ /', $line);
|
|
||||||
if(isset($data[2]))
|
|
||||||
{
|
|
||||||
$return[$data[1]] = $data[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Items
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# Browsing each line
|
|
||||||
foreach($lines as $line)
|
|
||||||
{
|
|
||||||
$data = preg_split('/ /', $line);
|
|
||||||
if(isset($data[1]))
|
|
||||||
{
|
|
||||||
$return[$data[1]] = array(substr($data[2], 1), $data[4]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats command to server
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function stats($server, $port)
|
|
||||||
{
|
|
||||||
# Executing command
|
|
||||||
if(($return = $this->exec('stats', $server, $port)))
|
|
||||||
{
|
|
||||||
return $this->parse($return);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats settings command to server
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function settings($server, $port)
|
|
||||||
{
|
|
||||||
# Executing command
|
|
||||||
if(($return = $this->exec('stats settings', $server, $port)))
|
|
||||||
{
|
|
||||||
return $this->parse($return);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats items command to server to retrieve slabs stats
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function slabs($server, $port)
|
|
||||||
{
|
|
||||||
# Initializing
|
|
||||||
$slabs = array();
|
|
||||||
|
|
||||||
# Finding uptime
|
|
||||||
$stats = $this->stats($server, $port);
|
|
||||||
$slabs['uptime'] = $stats['uptime'];
|
|
||||||
unset($stats);
|
|
||||||
|
|
||||||
# Executing command : slabs stats
|
|
||||||
if(($result = $this->exec('stats slabs', $server, $port)))
|
|
||||||
{
|
|
||||||
# Parsing result
|
|
||||||
$result = $this->parse($result);
|
|
||||||
$slabs['active_slabs'] = $result['active_slabs'];
|
|
||||||
$slabs['total_malloced'] = $result['total_malloced'];
|
|
||||||
unset($result['active_slabs']);
|
|
||||||
unset($result['total_malloced']);
|
|
||||||
|
|
||||||
# Indexing by slabs
|
|
||||||
foreach($result as $key => $value)
|
|
||||||
{
|
|
||||||
$key = preg_split('/:/', $key);
|
|
||||||
$slabs[$key[0]][$key[1]] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Executing command : items stats
|
|
||||||
if(($result = $this->exec('stats items', $server, $port)))
|
|
||||||
{
|
|
||||||
# Parsing result
|
|
||||||
$result = $this->parse($result);
|
|
||||||
|
|
||||||
# Indexing by slabs
|
|
||||||
foreach($result as $key => $value)
|
|
||||||
{
|
|
||||||
$key = preg_split('/:/', $key);
|
|
||||||
$slabs[$key[1]]['items:' . $key[2]] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $slabs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send stats cachedump command to server to retrieve slabs items
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Interger $slab Slab ID
|
|
||||||
*
|
|
||||||
* @return Array|Boolean
|
|
||||||
*/
|
|
||||||
public function items($server, $port, $slab)
|
|
||||||
{
|
|
||||||
# Initializing
|
|
||||||
$items = false;
|
|
||||||
|
|
||||||
# Executing command : stats cachedump
|
|
||||||
if(($result = $this->exec('stats cachedump ' . $slab . ' ' . self::$_ini->get('max_item_dump'), $server, $port)))
|
|
||||||
{
|
|
||||||
# Parsing result
|
|
||||||
$items = $this->parse($result, false);
|
|
||||||
}
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send get command to server to retrieve an item
|
|
||||||
* Return the result if successful or false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to retrieve
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function get($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Executing command : get
|
|
||||||
if(($string = $this->exec('get ' . $key, $server, $port)))
|
|
||||||
{
|
|
||||||
return preg_replace('/^VALUE ' . preg_quote($key, '/') . '[0-9 ]*\r\n/', '', $string);
|
|
||||||
}
|
|
||||||
return self::$_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set an item
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to store
|
|
||||||
* @param Mixed $data Data to store
|
|
||||||
* @param Integer $duration Duration
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function set($server, $port, $key, $data, $duration)
|
|
||||||
{
|
|
||||||
# Formatting data
|
|
||||||
$data = preg_replace('/\r/', '', $data);
|
|
||||||
|
|
||||||
# Executing command : set
|
|
||||||
if(($result = $this->exec('set ' . $key . ' 0 ' . $duration . ' ' . strlen($data) . "\r\n" . $data, $server, $port)))
|
|
||||||
{
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
return self::$_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an item
|
|
||||||
* Return true if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to delete
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function delete($server, $port, $key)
|
|
||||||
{
|
|
||||||
# Executing command : delete
|
|
||||||
if(($result = $this->exec('delete ' . $key, $server, $port)))
|
|
||||||
{
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
return self::$_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all items on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param Integer $delay Delay before flushing server
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function flush_all($server, $port, $delay)
|
|
||||||
{
|
|
||||||
# Executing command : flush_all
|
|
||||||
if(($result = $this->exec('flush_all ' . $delay, $server, $port)))
|
|
||||||
{
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
return self::$_log;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for item
|
|
||||||
* Return all the items matching parameters if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $key Key to search
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function search($server, $port, $search)
|
|
||||||
{
|
|
||||||
$slabs = array();
|
|
||||||
$items = false;
|
|
||||||
|
|
||||||
# Executing command : slabs stats
|
|
||||||
if(($result = $this->exec('stats slabs', $server, $port)))
|
|
||||||
{
|
|
||||||
# Parsing result
|
|
||||||
$result = $this->parse($result);
|
|
||||||
unset($result['active_slabs']);
|
|
||||||
unset($result['total_malloced']);
|
|
||||||
# Indexing by slabs
|
|
||||||
foreach($result as $key => $value)
|
|
||||||
{
|
|
||||||
$key = preg_split('/:/', $key);
|
|
||||||
$slabs[$key[0]] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exploring each slabs
|
|
||||||
foreach($slabs as $slab => $unused)
|
|
||||||
{
|
|
||||||
# Executing command : stats cachedump
|
|
||||||
if(($result = $this->exec('stats cachedump ' . $slab . ' 0', $server, $port)))
|
|
||||||
{
|
|
||||||
# Parsing result
|
|
||||||
preg_match_all('/^ITEM ((?:.*)' . preg_quote($search, '/') . '(?:.*)) \[(?:.*)\]\r\n/mU', $result, $matchs, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
foreach($matchs as $item)
|
|
||||||
{
|
|
||||||
$items[] = $item[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($slabs[$slab]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_array($items))
|
|
||||||
{
|
|
||||||
sort($items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a telnet command on a server
|
|
||||||
* Return the result
|
|
||||||
*
|
|
||||||
* @param String $server Hostname
|
|
||||||
* @param Integer $port Hostname Port
|
|
||||||
* @param String $command Command to execute
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
function telnet($server, $port, $command)
|
|
||||||
{
|
|
||||||
# Executing command
|
|
||||||
if(($result = $this->exec($command, $server, $port)))
|
|
||||||
{
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
return self::$_log;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,187 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Configuration class for editing, saving, ...
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 19/05/2010
|
|
||||||
*/
|
|
||||||
class Library_Configuration_Loader
|
|
||||||
{
|
|
||||||
# Singleton
|
|
||||||
protected static $_instance = null;
|
|
||||||
|
|
||||||
# Configuration file
|
|
||||||
protected static $_iniPath = './Config/Memcache.php';
|
|
||||||
|
|
||||||
# Configuration needed keys
|
|
||||||
protected static $_iniKeys = array('stats_api',
|
|
||||||
'slabs_api',
|
|
||||||
'items_api',
|
|
||||||
'get_api',
|
|
||||||
'set_api',
|
|
||||||
'delete_api',
|
|
||||||
'flush_all_api',
|
|
||||||
'connection_timeout',
|
|
||||||
'max_item_dump',
|
|
||||||
'refresh_rate',
|
|
||||||
'memory_alert',
|
|
||||||
'hit_rate_alert',
|
|
||||||
'eviction_alert',
|
|
||||||
'file_path',
|
|
||||||
'servers');
|
|
||||||
|
|
||||||
# Storage
|
|
||||||
protected static $_ini = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor, load configuration file and parse server list
|
|
||||||
*
|
|
||||||
* @return Void
|
|
||||||
*/
|
|
||||||
protected function __construct()
|
|
||||||
{
|
|
||||||
# Opening ini file
|
|
||||||
self::$_ini = require self::$_iniPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Library_Configuration_Loader singleton
|
|
||||||
*
|
|
||||||
* @return Library_Configuration_Loader
|
|
||||||
*/
|
|
||||||
public static function singleton()
|
|
||||||
{
|
|
||||||
if(!isset(self::$_instance))
|
|
||||||
{
|
|
||||||
self::$_instance = new self();
|
|
||||||
}
|
|
||||||
return self::$_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config key to retrieve
|
|
||||||
* Return the value, or false if does not exists
|
|
||||||
*
|
|
||||||
* @param String $key Key to get
|
|
||||||
*
|
|
||||||
* @return Mixed
|
|
||||||
*/
|
|
||||||
public function get($key)
|
|
||||||
{
|
|
||||||
if(isset(self::$_ini[$key]))
|
|
||||||
{
|
|
||||||
return self::$_ini[$key];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Servers to retrieve from cluster
|
|
||||||
* Return the value, or false if does not exists
|
|
||||||
*
|
|
||||||
* @param String $cluster Cluster to retreive
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public function cluster($cluster)
|
|
||||||
{
|
|
||||||
if(isset(self::$_ini['servers'][$cluster]))
|
|
||||||
{
|
|
||||||
return self::$_ini['servers'][$cluster];
|
|
||||||
}
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check and return server data
|
|
||||||
* Return the value, or false if does not exists
|
|
||||||
*
|
|
||||||
* @param String $server Server to retreive
|
|
||||||
*
|
|
||||||
* @return Array
|
|
||||||
*/
|
|
||||||
public function server($server)
|
|
||||||
{
|
|
||||||
foreach(self::$_ini['servers'] as $cluster => $servers)
|
|
||||||
{
|
|
||||||
if(isset(self::$_ini['servers'][$cluster][$server]))
|
|
||||||
{
|
|
||||||
return self::$_ini['servers'][$cluster][$server];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config key to set
|
|
||||||
*
|
|
||||||
* @param String $key Key to set
|
|
||||||
* @param Mixed $value Value to set
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
public function set($key, $value)
|
|
||||||
{
|
|
||||||
self::$_ini[$key] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return actual ini file path
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public function path()
|
|
||||||
{
|
|
||||||
return self::$_iniPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if every ini keys are set
|
|
||||||
* Return true if ini is correct, false otherwise
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
public function check()
|
|
||||||
{
|
|
||||||
# Checking configuration keys
|
|
||||||
foreach(self::$_iniKeys as $iniKey)
|
|
||||||
{
|
|
||||||
# Ini file key not set
|
|
||||||
if(!isset(self::$_ini[$iniKey]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write ini file
|
|
||||||
* Return true if written, false otherwise
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
public function write()
|
|
||||||
{
|
|
||||||
if($this->check())
|
|
||||||
{
|
|
||||||
return is_numeric(file_put_contents(self::$_iniPath, '<?php' . PHP_EOL . 'return ' . var_export(self::$_ini, true) . ';'));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Error container
|
|
||||||
*
|
|
||||||
* @author elijaa@free.fr
|
|
||||||
* @since 11/10/2010
|
|
||||||
*/
|
|
||||||
class Library_Data_Error
|
|
||||||
{
|
|
||||||
private static $_errors = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an error to the container
|
|
||||||
* Return true if successful, false otherwise
|
|
||||||
*
|
|
||||||
* @param String $error Error message
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
*/
|
|
||||||
public static function add($error)
|
|
||||||
{
|
|
||||||
return array_push(self::$_errors, $error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return last Error message
|
|
||||||
*
|
|
||||||
* @return Mixed
|
|
||||||
*/
|
|
||||||
public static function last()
|
|
||||||
{
|
|
||||||
return (isset(self::$_errors[count(self::$_errors) - 1])) ? self::$_errors[count(self::$_errors) - 1] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return errors count
|
|
||||||
*
|
|
||||||
* @return Integer
|
|
||||||
*/
|
|
||||||
public static function count()
|
|
||||||
{
|
|
||||||
return count(self::$_errors);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Manipulation of HTML
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 05/04/2010
|
|
||||||
*/
|
|
||||||
class Library_HTML_Components
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Dump server list in an HTML select
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function serverSelect($name, $selected = '', $class = '', $events = '')
|
|
||||||
{
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Select Name
|
|
||||||
$serverList = '<select id="' . $name . '" ';
|
|
||||||
|
|
||||||
# CSS Class
|
|
||||||
$serverList .= ($class != '') ? 'class="' . $class . '"' : '';
|
|
||||||
|
|
||||||
# Javascript Events
|
|
||||||
$serverList .= ' ' . $events .'>';
|
|
||||||
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Cluster
|
|
||||||
$serverList .= '<option value="' . $cluster . '" ';
|
|
||||||
$serverList .= ($selected == $cluster) ? 'selected="selected"' : '';
|
|
||||||
$serverList .= '>' . $cluster . ' cluster</option>';
|
|
||||||
|
|
||||||
# Cluster server
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
$serverList .= '<option value="' . $server['hostname'] . ':' . $server['port'] . '" ';
|
|
||||||
$serverList .= ($selected == $server['hostname'] . ':' . $server['port']) ? 'selected="selected"' : '';
|
|
||||||
$serverList .= '> - ' . $server['hostname'] . ':' . $server['port'] . '</option>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $serverList . '</select>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump cluster list in an HTML select
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function clusterSelect($name, $selected = '', $class = '', $events = '')
|
|
||||||
{
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Select Name
|
|
||||||
$clusterList = '<select id="' . $name . '" ';
|
|
||||||
|
|
||||||
# CSS Class
|
|
||||||
$clusterList .= ($class != '') ? 'class="' . $class . '"' : '';
|
|
||||||
|
|
||||||
# Javascript Events
|
|
||||||
$clusterList .= ' ' . $events .'>';
|
|
||||||
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Option value and selected case
|
|
||||||
$clusterList .= '<option value="' . $cluster . '" ';
|
|
||||||
$clusterList .= ($selected == $cluster) ? 'selected="selected"' : '';
|
|
||||||
$clusterList .= '>' . $cluster . ' cluster</option>';
|
|
||||||
}
|
|
||||||
return $clusterList . '</select>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump server response in proper formatting
|
|
||||||
*
|
|
||||||
* @param string $hostname Hostname
|
|
||||||
* @param string $port Port
|
|
||||||
* @param mixed $data Data (reponse)
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function serverResponse($hostname, $port, $data)
|
|
||||||
{
|
|
||||||
$header = '<span class="red">Server ' . $hostname . ':' . $port . "</span>\r\n";
|
|
||||||
$return = '';
|
|
||||||
if(is_array($data))
|
|
||||||
{
|
|
||||||
foreach($data as $string)
|
|
||||||
{
|
|
||||||
$return .= $string . "\r\n";
|
|
||||||
}
|
|
||||||
return $header . htmlentities($return, ENT_NOQUOTES | ENT_IGNORE, "UTF-8") . "\r\n";
|
|
||||||
}
|
|
||||||
return $header . $return . $data . "\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump api list un HTML select with select name
|
|
||||||
*
|
|
||||||
* @param String $iniAPI API Name from ini file
|
|
||||||
* @param String $id Select ID
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
public static function apiList($iniAPI = '', $id)
|
|
||||||
{
|
|
||||||
return '<select id="' . $id . '" name="' . $id . '">
|
|
||||||
<option value="Server" ' . self::selected('Server', $iniAPI) . '>Server API</option>
|
|
||||||
<option value="Memcache" ' . self::selected('Memcache', $iniAPI) . '>Memcache API</option>
|
|
||||||
<option value="Memcached" ' . self::selected('Memcached', $iniAPI) . '>Memcached API</option>
|
|
||||||
</select>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to see if an option is selected
|
|
||||||
*
|
|
||||||
* @param String $actual Actual value
|
|
||||||
* @param String $selected Selected value
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
private static function selected($actual, $selected)
|
|
||||||
{
|
|
||||||
if($actual == $selected)
|
|
||||||
{
|
|
||||||
return 'selected="selected"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
# Constants declaration
|
|
||||||
define('CURRENT_VERSION', '1.2.1');
|
|
||||||
|
|
||||||
# Autoloader
|
|
||||||
function __autoload($class)
|
|
||||||
{
|
|
||||||
require_once str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
|
|
||||||
}
|
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3 KiB |
|
@ -1,29 +0,0 @@
|
||||||
function changeServer(obj){if(obj.options[obj.selectedIndex].value!=''){window.location='index.php?server='+obj.options[obj.selectedIndex].value;}else{window.location='index.php';}}
|
|
||||||
function changeCluster(obj){if(obj.options[obj.selectedIndex].value!=''){window.location='stats.php?cluster='+obj.options[obj.selectedIndex].value;}else{window.location='stats.php';}}
|
|
||||||
function changeCommand(obj){document.getElementById('request_key').value='';document.getElementById('request_duration').value='';document.getElementById('request_data').value='';document.getElementById('request_delay').value='';var command=obj.options[obj.selectedIndex].value;var div_key=document.getElementById('div_key');var div_duration=document.getElementById('div_duration');var div_data=document.getElementById('div_data');var div_delay=document.getElementById('div_delay');if(command=='get'||command=='delete'){div_key.style.display='';div_duration.style.display='none';div_data.style.display='none';div_delay.style.display='none';}else if(command=='set'){div_key.style.display='';div_duration.style.display='';div_data.style.display='';div_delay.style.display='none';}else if(command=='flush_all'){div_key.style.display='none';div_duration.style.display='none';div_data.style.display='none';div_delay.style.display='';}else{div_key.style.display='none';div_duration.style.display='none';div_data.style.display='none';div_delay.style.display='none';}}
|
|
||||||
function executeClear(target)
|
|
||||||
{var object=document.getElementById(target);object.innerHTML='';}
|
|
||||||
function executeCommand(target){if(document.getElementById('request_command').value!='')
|
|
||||||
{var request_url='commands.php?request_command='+document.getElementById('request_command').value+'&request_key='+document.getElementById('request_key').value+'&request_duration='+document.getElementById('request_duration').value+'&request_data='+document.getElementById('request_data').value+'&request_delay='+document.getElementById('request_delay').value+'&request_server='+document.getElementById('request_server').value+'&request_api='+document.getElementById('request_api').value;execute(request_url,target,true);}}
|
|
||||||
function searchKey(target){if(document.getElementById('search_key').value!='')
|
|
||||||
{var request_url='commands.php?request_command=search'+'&request_key='+document.getElementById('search_key').value+'&request_server='+document.getElementById('search_server').value;execute(request_url,target,true);}}
|
|
||||||
function executeTelnet(target){if(document.getElementById('request_telnet').value!='')
|
|
||||||
{var request_url='commands.php?request_command=telnet'+'&request_telnet='+document.getElementById('request_telnet').value+'&request_server='+document.getElementById('request_telnet_server').value;execute(request_url,target,true);}}
|
|
||||||
function execute(url,target,append){if(window.XMLHttpRequest){req=new XMLHttpRequest();req.onreadystatechange=function(){onExecute(target,append);};req.open('GET',url,true);req.send(null);}else if(window.ActiveXObject){req=new ActiveXObject('Microsoft.XMLHTTP');if(req){req.onreadystatechange=function(){onExecute(target,append);};req.open('GET',url,true);req.send();}}}
|
|
||||||
function onExecute(target,append){if(req.readyState==1){document.getElementById('loading').style.visibility="visible";}
|
|
||||||
else if(req.readyState==4){document.getElementById('loading').style.visibility="hidden";if(req.status==200||req.status==304){if(append==true)
|
|
||||||
{var object=document.getElementById(target);object.innerHTML+=req.responseText;object.scrollTop=object.scrollHeight;}
|
|
||||||
else
|
|
||||||
{var object=document.getElementById(target);object.innerHTML=req.responseText;object.scrollTop=object.scrollHeight;}}}
|
|
||||||
else{document.getElementById('loading').style.visibility="hidden";}}
|
|
||||||
var server_id=1;var cluster_id=1;function addCluster(){var clusterDiv=document.createElement('div');cluster_id++;clusterDiv.innerHTML='<hr/><strong>Cluster '+'<input type="text" style="width:200px;" name="cluster['+cluster_id+']" value=""/></strong>'+'<div style="margin-left:40px;margin-top:6px;" id="cluster_'+cluster_id+'_commands"><a class="list button" href="javascript:addServer('+cluster_id+')">'+'Add New Server to Cluster</a> <a class="list" style="padding:1px 2px;-moz-border-radius:3px;-webkit-border-radius:3px;" '+'href="#" onclick="deleteServerOrCluster(\'cluster_'+cluster_id+'\')">Delete Cluster</a></div><br/>';clusterDiv.setAttribute('id','cluster_'+cluster_id);document.getElementById('server_form').appendChild(clusterDiv);}
|
|
||||||
function addServer(current_cluster_id){var serverDiv=document.createElement('div');server_id++;serverDiv.innerHTML='<div id="server_'+server_id+'"><div style="margin-left:40px;margin-top:3px;">'+'<input type="text" style="width:200px;" name="server['+current_cluster_id+']['+server_id+'][hostname]" value="hostname" onfocus="hostnameOnFocus(this)" onblur="hostnameOnBlur(this)"/> '+'<input type="text" style="width:50px;" name="server['+current_cluster_id+']['+server_id+'][port]" value="port" onfocus="portOnFocus(this)" onblur="portOnBlur(this)"/> '+'<a class="list button" style="padding:1px 2px;" href="#" onclick="deleteServerOrCluster(\'server_'+server_id+'\')">Delete</a>'+'</div></div>';serverDiv.setAttribute('id','server_'+server_id);document.getElementById('cluster_'+current_cluster_id).insertBefore(serverDiv,document.getElementById('cluster_'+current_cluster_id+'_commands'));}
|
|
||||||
function deleteServerOrCluster(divID){var div=document.getElementById(divID);div.parentNode.removeChild(div);}
|
|
||||||
function hostnameOnFocus(obj){if(obj.value=='hostname'){obj.value='';}}
|
|
||||||
function hostnameOnBlur(obj){if(obj.value==''){obj.value='hostname';}}
|
|
||||||
function portOnFocus(obj){if(obj.value=='port'){obj.value='';}}
|
|
||||||
function portOnBlur(obj){if(obj.value==''){obj.value='port';}}
|
|
||||||
function ajax(url,target){if(window.XMLHttpRequest){req=new XMLHttpRequest();req.onreadystatechange=function(){ajaxDone(target);};req.open("GET",url,true);req.send(null);}else if(window.ActiveXObject){req=new ActiveXObject('Microsoft.XMLHTTP');if(req){req.onreadystatechange=function(){ajaxDone(target);};req.open("GET",url,true);req.send();}}
|
|
||||||
setTimeout("ajax(page, 'stats')",timeout);}
|
|
||||||
function ajaxDone(target){if(req.readyState==4){if(req.status==200||req.status==304){results=req.responseText;document.getElementById(target).innerHTML=results;}else{document.getElementById(target).innerHTML="Loading stats error : "
|
|
||||||
+req.statusText;}}}
|
|
|
@ -1 +0,0 @@
|
||||||
body{background-color:#FEFEFE;font-family:Verdana,Tahoma,Segoe UI,Arial;font-size:0.8em;margin-top:10px}a{ color:#EEE; text-decoration:none}a:hover{ color:#A00}input,select,textarea{ -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; border:solid 1px #AAA; width:298px; font-family:tahoma; font-size:1em}textarea{ width:494px; resize:none}select{ width:300px}input:focus,textarea:focus{ border:solid 1px #EEE}input:hover{ color:#A00}img{ border:none}/** hr */hr{ height:0; border:none; border-bottom:solid 1px #eee}.menu{ border:solid 1px #a0312a; color:#eee; width:198px}.item{ font-family:Bitstream Vera Sans Mono}#loading{ text-decoration:blink; width:680px; visibility:hidden}.full-size{width:980px}.size-0{width:494px}.size-1{width:696px}.size-2{width:398px}.size-4{width:290px}.size-5{width:226px}.padding{padding:3px 7px 3px 7px}.corner{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}.header{border:1px solid #9c3c36;background:url("../Images/b5463f.png") repeat-x scroll 50% 50% #B5463F;font-weight:bold;color:#fff;clear:both}.sub-header{border:1px solid #514845;background:url("../Images/635855.png") repeat-x scroll 50% 50% #635855;font-weight:bold;color:#fff;clear:both;margin-top:10px}.container{border:1px solid #d0d0d0;background:#ebebeb;font-weight:none;color:#000;margin-top:1px;clear:both}.list{border:1px solid #9c3c36;background:#B5463F;font-weight:bold;color:#fff}.button{padding:1px 20px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}.live{font-family:Bitstream Vera Sans Mono,Lucida Sans Typewriter,DejaVu Sans Mono;font-size:12px;overflow:visible;white-space:pre-wrap}.line{min-height:18px;padding-top:3px;padding-bottom:2px;clear:both}.left{float:left;min-width:126px;font-weight:bold}.right{float:right}.setting{min-width:180px}.slabs{min-width:104px}.container hr{height:0;border:none;border-bottom:solid 1px #fff}.grey{ color:#EEE}.green{color:#40aaba}.red{background:#b5463f;color:#fff;font-weight:bold}
|
|
|
@ -1 +0,0 @@
|
||||||
a:1:{s:15:"127.0.0.1:11211";a:38:{s:3:"pid";s:4:"2049";s:6:"uptime";s:6:"779472";s:4:"time";s:10:"1326282322";s:7:"version";s:5:"1.4.5";s:12:"pointer_size";s:2:"32";s:11:"rusage_user";s:9:"20.137258";s:13:"rusage_system";s:9:"33.862116";s:16:"curr_connections";s:1:"6";s:17:"total_connections";s:5:"13230";s:21:"connection_structures";s:2:"17";s:7:"cmd_get";s:5:"25856";s:7:"cmd_set";s:5:"21025";s:9:"cmd_flush";s:1:"0";s:8:"get_hits";s:5:"22412";s:10:"get_misses";s:4:"3444";s:13:"delete_misses";s:1:"2";s:11:"delete_hits";s:2:"85";s:11:"incr_misses";s:1:"0";s:9:"incr_hits";s:1:"0";s:11:"decr_misses";s:1:"0";s:9:"decr_hits";s:1:"0";s:10:"cas_misses";s:1:"0";s:8:"cas_hits";s:1:"0";s:10:"cas_badval";s:1:"0";s:9:"auth_cmds";s:1:"0";s:11:"auth_errors";s:1:"0";s:10:"bytes_read";s:8:"34784259";s:13:"bytes_written";s:8:"61237342";s:14:"limit_maxbytes";s:8:"67108864";s:15:"accepting_conns";s:1:"1";s:19:"listen_disabled_num";s:1:"0";s:7:"threads";s:1:"4";s:11:"conn_yields";s:1:"0";s:5:"bytes";s:6:"175257";s:10:"curr_items";s:2:"45";s:11:"total_items";s:5:"21025";s:9:"evictions";s:1:"0";s:9:"reclaimed";s:4:"1746";}}
|
|
|
@ -1,162 +0,0 @@
|
||||||
<div style="float:left;">
|
|
||||||
<div class="sub-header corner full-size padding">Console</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<pre id="container" style="font-size:11px;overflow:auto;min-height:180px;max-height:500px;" class="full-size"></pre>
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding" style="text-align:right;">
|
|
||||||
<span style="float:left;">
|
|
||||||
<input class="header" type="submit" id="loading" value="Waiting for server response ..."/>
|
|
||||||
</span>
|
|
||||||
<input class="header" type="submit" onclick="javascript:executeClear('container')" value="Clear Console"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner full-size padding">Execute predefined <span class="green">Command</span></div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<table>
|
|
||||||
<tr valign="top">
|
|
||||||
<td class="size-0 padding" style="padding-right:14px;">
|
|
||||||
<form action="commands.php" onsubmit="return false">
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
Execute command on one or all memcached servers<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Command</span>
|
|
||||||
<span class="right">
|
|
||||||
<select id="request_command" onchange="javascript:changeCommand(this);">
|
|
||||||
<option value="">Choose a Command</option>
|
|
||||||
<option value="get">Get</option>
|
|
||||||
<option value="set">Set</option>
|
|
||||||
<option value="delete">Delete</option>
|
|
||||||
<option value="flush_all">Flush All</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="div_key" class="line" style="display:none;">
|
|
||||||
<span class="left">Key</span>
|
|
||||||
<span class="right">
|
|
||||||
<input id="request_key"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="div_duration" class="line" style="display:none;">
|
|
||||||
<span class="left">Duration</span>
|
|
||||||
<span class="right">
|
|
||||||
<input id="request_duration"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="div_data" class="line" style="display:none;">
|
|
||||||
<span class="left">Data</span>
|
|
||||||
<span class="right">
|
|
||||||
<textarea id="request_data" rows="2" cols="2"></textarea>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div id="div_delay" class="line" style="display:none;">
|
|
||||||
<span class="left">Delay</span>
|
|
||||||
<span class="right">
|
|
||||||
<input id="request_delay"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Server</span>
|
|
||||||
<span class="right">
|
|
||||||
<?php echo Library_HTML_Components::serverSelect('request_server'); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">API</span>
|
|
||||||
<span class="right">
|
|
||||||
<?php echo Library_HTML_Components::apiList($_ini->get('get_api'), 'request_api'); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="header" type="submit"
|
|
||||||
onclick="javascript:executeCommand('container');javascript:this.blur();" value="Execute Command"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td class="padding" style="border-left:1px solid #ffffff;padding-left:14px;">
|
|
||||||
|
|
||||||
<br/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner full-size padding">Execute Telnet <span class="green">Commands</span></div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<table>
|
|
||||||
<tr valign="top">
|
|
||||||
<td class="size-0 padding" style="padding-right:14px;">
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
Execute telnet command on one or all memcached servers<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<textarea id="request_telnet" rows="2" cols="2"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Server</span>
|
|
||||||
<span class="right">
|
|
||||||
<?php echo Library_HTML_Components::serverSelect('request_telnet_server'); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="header" type="submit"
|
|
||||||
onclick="javascript:executeTelnet('container');javascript:this.blur();" value="Execute Telnet Command"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="padding" style="border-left:1px solid #ffffff;padding-left:14px;">
|
|
||||||
You can use this thing to execute any telnet command to any memcached server
|
|
||||||
<br/>
|
|
||||||
It will connect to the server, execute the command and return it in the console
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
For more informations about memcached commands, see memcached protocol
|
|
||||||
<a href="http://github.com/memcached/memcached/blob/master/doc/protocol.txt" target="_blank"><span class="green">here</span></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner full-size padding">Search <span class="green">Key</span></div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<table>
|
|
||||||
<tr valign="top">
|
|
||||||
<td class="size-0 padding" style="padding-right:14px;">
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
Search for a key on one or all memcached servers<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Key</span>
|
|
||||||
<span class="right">
|
|
||||||
<input id="search_key" name="search_key"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Server</span>
|
|
||||||
<span class="right">
|
|
||||||
<?php echo Library_HTML_Components::serverSelect('search_server'); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="header" type="submit"
|
|
||||||
onclick="javascript:searchKey('container');javascript:this.blur();" value="Search Key"/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="padding" style="border-left:1px solid #ffffff;padding-left:14px;">
|
|
||||||
<span class="red">Warning !</span><br/>This thing is only for debuging issue, do not use it in a production environment as it can lock
|
|
||||||
or impact your memcached servers performances.
|
|
||||||
<br/>Also keep in mind that it does not list all keys. It lists keys up to a certain buffer size (1 or 2MB), and it list key that are expired.
|
|
||||||
<br/>
|
|
||||||
<br/>You can also use a PCRE regular expression
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,161 +0,0 @@
|
||||||
<div style="float:left;">
|
|
||||||
<div class="size-0" style="float:left;">
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Commands <span class="green">Configuration</span></div>
|
|
||||||
<div class="container corner padding" style="padding-right:14px;">
|
|
||||||
<form method="post" action="configure.php?request_write=commands">
|
|
||||||
<div class="line">
|
|
||||||
Memcached commands API used by phpMemCacheAdmin<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Stats</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('stats_api'), 'stats_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Slabs</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('slabs_api'), 'slabs_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Items</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('items_api'), 'items_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Get</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('get_api'), 'get_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Set</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('set_api'), 'set_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Delete</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('delete_api'), 'delete_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Flush All</span>
|
|
||||||
<span class="right"><?php echo Library_HTML_Components::apiList($_ini->get('flush_all_api'), 'flush_all_api'); ?></span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="list" type="submit" value="Save API Configuration"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Live Stats <span class="green">Configuration</span></div>
|
|
||||||
<div class="container corner padding" style="padding-right:14px;">
|
|
||||||
<form method="post" action="configure.php?request_write=live_stats">
|
|
||||||
<div class="line">
|
|
||||||
Alert & refresh rate for Live Stats<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Refresh Rate in sec</span>
|
|
||||||
<span class="right"><input type="text" name="refresh_rate" value="<?php echo $_ini->get('refresh_rate'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Memory Alert</span>
|
|
||||||
<span class="right"><input type="text" name="memory_alert" value="<?php echo $_ini->get('memory_alert'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hit Rate Alert</span>
|
|
||||||
<span class="right"><input type="text" name="hit_rate_alert" value="<?php echo $_ini->get('hit_rate_alert'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Eviction Alert</span>
|
|
||||||
<span class="right"><input type="text" name="eviction_alert" value="<?php echo $_ini->get('eviction_alert'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Temp Path</span>
|
|
||||||
<span class="right"><input type="text" name="file_path" value="<?php echo $_ini->get('file_path'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="list" type="submit" value="Save Live Configuration"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Miscellaneous <span class="green">Configuration</span></div>
|
|
||||||
<div class="container corner padding" style="padding-right:14px;">
|
|
||||||
<form method="post" action="configure.php?request_write=miscellaneous">
|
|
||||||
<div class="line">
|
|
||||||
Server connection timeout & miscellaneous<br/>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Timeout in sec</span>
|
|
||||||
<span class="right"><input type="text" name="connection_timeout" value="<?php echo $_ini->get('connection_timeout'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Max Items</span>
|
|
||||||
<span class="right"><input type="text" name="max_item_dump" value="<?php echo $_ini->get('max_item_dump'); ?>"/></span>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="text-align:center;">
|
|
||||||
<hr/>
|
|
||||||
<input class="list" type="submit" value="Save API Configuration"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="size-0" style="float:left;padding-left:9px;">
|
|
||||||
<div class="sub-header corner padding">Server <span class="green">List</span></div>
|
|
||||||
<div class="container corner padding" style="padding-right:14px;">
|
|
||||||
<form method="post" action="configure.php?request_write=servers">
|
|
||||||
<div class="line">
|
|
||||||
Servers list used by phpMemCacheAdmin<br/>
|
|
||||||
</div>
|
|
||||||
<div id="server_form">
|
|
||||||
<?php
|
|
||||||
# Initializing variables
|
|
||||||
$server_id = 0;
|
|
||||||
$cluster_id = 0;
|
|
||||||
|
|
||||||
# Looking into each cluster
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
$cluster_id++; ?>
|
|
||||||
<div id="cluster_<?php echo $cluster_id; ?>">
|
|
||||||
<hr/>
|
|
||||||
<strong>Cluster <input type="text" style="width:200px;" name="cluster[<?php echo $cluster_id; ?>]" value="<?php echo $cluster; ?>"/></strong>
|
|
||||||
<?php # Adding input for each server
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
$server_id++; ?>
|
|
||||||
<div id="server_<?php echo $server_id; ?>">
|
|
||||||
<div style="margin-left:40px;margin-top:3px;">
|
|
||||||
<input type="text" style="width:200px;" name="server[<?php echo $cluster_id; ?>][<?php echo $server_id; ?>][hostname]" value="<?php echo $server['hostname']; ?>" onfocus="hostnameOnFocus(this)" onblur="hostnameOnBlur(this)"/>
|
|
||||||
<input type="text" style="width:50px;" name="server[<?php echo $cluster_id; ?>][<?php echo $server_id; ?>][port]" value="<?php echo $server['port']; ?>" onfocus="portOnFocus(this)" onblur="portOnBlur(this)"/>
|
|
||||||
<a class="list button" style="padding:1px 2px;" href="#" onclick="deleteServerOrCluster('server_<?php echo $server_id; ?>')">Delete</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<div id="cluster_<?php echo $cluster_id; ?>_commands" style="margin-left:40px;margin-top:6px;">
|
|
||||||
<a class="list button" href="javascript:addServer(<?php echo $cluster_id; ?>)">Add New Server to Cluster</a> <a class="list" style="padding:1px 2px;-moz-border-radius:3px;-webkit-border-radius:3px;" href="#" onclick="deleteServerOrCluster('cluster_<?php echo $cluster_id; ?>')">Delete Cluster</a>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<hr/>
|
|
||||||
<a class="list button" href="javascript:addCluster()">Add New Cluster</a>
|
|
||||||
<input class="list" type="submit" value="Save Servers Configuration"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
server_id = <?php echo $server_id; ?>;
|
|
||||||
cluster_id = <?php echo $cluster_id; ?>;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="container corner padding" style="margin-top:10px;">
|
|
||||||
<div class="line">
|
|
||||||
For more information about configuring phpMemcachedAdmin, see installation guide
|
|
||||||
<a href="http://code.google.com/p/phpmemcacheadmin/wiki/InstallationGuide" target="_blank"><span class="green">here</span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<div class="sub-header corner full-size padding" style="float:left; text-align:center; margin-top:10px;">
|
|
||||||
<a href="http://code.google.com/p/phpmemcacheadmin/" target="_blank">phpMemcachedAdmin on GoogleCode</a>
|
|
||||||
- <a href="http://memcached.org/" target="_blank">Memcached.org</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,62 +0,0 @@
|
||||||
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<title>phpMemcachedAdmin <?php echo CURRENT_VERSION; ?></title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="Public/Styles/Style.css"/>
|
|
||||||
<script type="text/javascript" src="Public/Scripts/Script.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="margin:0pt auto; width:1000px; clear:both;">
|
|
||||||
<div style="font-weight:bold;font-size:1.2em;">phpMemcachedAdmin <sup><?php echo CURRENT_VERSION; ?></sup></div>
|
|
||||||
<div class="header corner full-size padding" style="text-align:center;margin-top:5px;">
|
|
||||||
<?php
|
|
||||||
# Live Stats view
|
|
||||||
if(basename($_SERVER['PHP_SELF']) == 'stats.php')
|
|
||||||
{ ?>
|
|
||||||
Live Stats |
|
|
||||||
<?php
|
|
||||||
} else { ?>
|
|
||||||
<a href="stats.php">See Live Stats </a> |
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
# Stats view
|
|
||||||
if(basename($_SERVER['PHP_SELF']) == 'index.php')
|
|
||||||
{ ?>
|
|
||||||
Actually seeing
|
|
||||||
<?php
|
|
||||||
} else { ?>
|
|
||||||
<a href="index.php">See Stats for </a>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
# Server HTML select
|
|
||||||
echo Library_HTML_Components::serverSelect('server_select', (isset($_GET['server'])) ? $_GET['server'] : '', 'list', 'onchange="changeServer(this)"'); ?>
|
|
||||||
|
|
|
||||||
<?php
|
|
||||||
# Commands view
|
|
||||||
if(basename($_SERVER['PHP_SELF']) == 'commands.php')
|
|
||||||
{ ?>
|
|
||||||
Executing Commands on Servers
|
|
||||||
<?php
|
|
||||||
} else { ?>
|
|
||||||
<a href="commands.php">Execute Commands on Servers</a>
|
|
||||||
<?php
|
|
||||||
}?>
|
|
||||||
|
|
|
||||||
<?php
|
|
||||||
# Configure view
|
|
||||||
if(basename($_SERVER['PHP_SELF']) == 'configure.php')
|
|
||||||
{ ?>
|
|
||||||
Editing Configuration
|
|
||||||
<?php
|
|
||||||
} else { ?>
|
|
||||||
<a href="configure.php">Edit Configuration</a>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--[if IE]>
|
|
||||||
<div class="header corner full-size padding" style="text-align:center;margin-top:10px;">
|
|
||||||
Support browsers that contribute to open source, try <a href="http://www.firefox.com" target="_blank">Firefox</a> or <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>.
|
|
||||||
</div>
|
|
||||||
<![endif]-->
|
|
|
@ -1,70 +0,0 @@
|
||||||
<script type="text/javascript">
|
|
||||||
var timeout = <?php echo $refresh_rate * 1000; ?>;
|
|
||||||
var page = 'stats.php?request_command=live_stats&cluster=<?php echo $cluster; ?>';
|
|
||||||
setTimeout("ajax(page,'stats')", <?php echo (5 + $refresh_rate - $_ini->get('refresh_rate')) * 1000; ?>);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div style="float:left;">
|
|
||||||
<div class="sub-header corner full-size padding">Live <span class="green">Stats</span></div>
|
|
||||||
<?php
|
|
||||||
# Refresh rate increased
|
|
||||||
if($refresh_rate > $_ini->get('refresh_rate'))
|
|
||||||
{ ?>
|
|
||||||
<div class="container corner" style="padding:9px;">
|
|
||||||
Connections errors were discovered, to prevent any problem, refresh rate was increased by
|
|
||||||
<?php echo sprintf('%.1f', $refresh_rate - $_ini->get('refresh_rate')); ?> seconds.
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
|
|
||||||
<div class="full-size padding">
|
|
||||||
<br/>
|
|
||||||
<span class="live">Actually looking at <?php echo Library_HTML_Components::clusterSelect('cluster_select', (isset($_GET['cluster'])) ? $_GET['cluster'] : '', 'live', 'onchange="changeCluster(this);"'); ?> stats</span>
|
|
||||||
<pre id="stats" class="live">
|
|
||||||
|
|
||||||
Loading live stats, please wait ~<?php echo sprintf('%.0f', 5 + $refresh_rate - $_ini->get('refresh_rate')); ?> seconds ...
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">SIZE</span>
|
|
||||||
Total cache size on this server
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">%MEM</span>
|
|
||||||
Percentage of total cache size used on this server
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">%HIT</span>
|
|
||||||
Global hit percent on this server : get_hits / (get_hits + get_misses)
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">TIME</span>
|
|
||||||
Time taken to connect to the server and proceed the request, high value can indicate a latency or server problem
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">REQ/s</span>
|
|
||||||
Total request per second (get, set, delete, incr, ...) issued to this server
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">CONN</span>
|
|
||||||
Current connections, monitor that this number doesn't come too close to the server max connection setting
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">GET/s, SET/s, DEL/s</span>
|
|
||||||
Get, set or delete commands per second issued to this server
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">EVI/s</span>
|
|
||||||
Number of times an item which had an explicit expire time set had to be evicted before it expired
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">READ/s</span>
|
|
||||||
Total number of bytes read by this server from network
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">WRITE/s</span>
|
|
||||||
Total number of bytes sent by this server to network
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,87 +0,0 @@
|
||||||
<?php
|
|
||||||
# CRLF/EOL
|
|
||||||
define('EOL', "\r\n");
|
|
||||||
|
|
||||||
# Header
|
|
||||||
echo 'Last update : ' . date('r', time()) . ' (refresh rate : ' . $_ini->get('refresh_rate') . ' sec)' . EOL . EOL;
|
|
||||||
|
|
||||||
# Table header
|
|
||||||
echo '<strong>' . sprintf('%-40s', 'SERVER:PORT') . sprintf('%10s', 'SIZE') . sprintf('%7s', '%MEM') . sprintf('%8s', 'TIME') .
|
|
||||||
sprintf('%6s', 'CONN') . sprintf('%7s', '%HIT') . sprintf('%8s', 'REQ/s') . sprintf('%8s', 'GET/s') . sprintf('%8s', 'SET/s') .
|
|
||||||
sprintf('%8s', 'DEL/s') . sprintf('%8s', 'EVI/s') . sprintf('%11s', 'READ/s') . sprintf('%10s', 'WRITE/s') . '</strong>' . EOL . '<hr>';
|
|
||||||
|
|
||||||
# Showing stats for every server
|
|
||||||
foreach($stats as $server => $data)
|
|
||||||
{
|
|
||||||
# Server name
|
|
||||||
echo sprintf('%-40.40s', $server);
|
|
||||||
|
|
||||||
# Checking for stats validity
|
|
||||||
if((isset($data['time'], $data['bytes_percent'], $data['get_hits_percent'], $data['query_time'], $data['request_rate'], $data['curr_connections'],
|
|
||||||
$data['get_rate'], $data['set_rate'], $data['delete_rate'], $data['eviction_rate'], $data['bytes_read'], $data['bytes_written'])) && ($data['time'] > 0))
|
|
||||||
{
|
|
||||||
# Total Memory
|
|
||||||
echo sprintf('%10s', Library_Analysis::byteResize($data['limit_maxbytes']) . 'b');
|
|
||||||
|
|
||||||
# Memory Occupation / Alert State
|
|
||||||
if($data['bytes_percent'] > $_ini->get('memory_alert'))
|
|
||||||
{
|
|
||||||
echo str_pad('', 7 - strlen($data['bytes_percent']), ' ') . '<span class="red">' . sprintf('%.1f', $data['bytes_percent']) . '</span>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo sprintf('%7.1f', $data['bytes_percent']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Query Time
|
|
||||||
echo sprintf('%5.0f', Library_Analysis::valueResize($data['query_time'])) . ' ms';
|
|
||||||
|
|
||||||
# Current connection
|
|
||||||
echo sprintf('%6s', $data['curr_connections']);
|
|
||||||
|
|
||||||
# Hit percent (get, delete, cas, incr & decr)
|
|
||||||
if($data['get_hits_percent'] < $_ini->get('hit_rate_alert'))
|
|
||||||
{
|
|
||||||
echo str_pad('', 7 - strlen($data['get_hits_percent']), ' ') . '<span class="red">' . sprintf('%.1f', $data['get_hits_percent']) . '</span>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo sprintf('%7.1f', $data['get_hits_percent']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Request rate
|
|
||||||
echo sprintf('%8s', Library_Analysis::valueResize($data['request_rate']));
|
|
||||||
|
|
||||||
# Get rate
|
|
||||||
echo sprintf('%8s', Library_Analysis::valueResize($data['get_rate']));
|
|
||||||
|
|
||||||
# Set rate
|
|
||||||
echo sprintf('%8s', Library_Analysis::valueResize($data['set_rate']));
|
|
||||||
|
|
||||||
# Delete rate
|
|
||||||
echo sprintf('%8s', Library_Analysis::valueResize($data['delete_rate']));
|
|
||||||
|
|
||||||
# Eviction rate
|
|
||||||
if($data['eviction_rate'] > $_ini->get('eviction_alert'))
|
|
||||||
{
|
|
||||||
echo str_pad('', 8 - strlen(Library_Analysis::valueResize($data['eviction_rate'])), ' ') . '<span class="red">' . Library_Analysis::valueResize($data['eviction_rate']) . '</span>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo sprintf('%8s', Library_Analysis::valueResize($data['eviction_rate']));
|
|
||||||
}
|
|
||||||
|
|
||||||
# Bytes read
|
|
||||||
echo sprintf('%11s', Library_Analysis::byteResize($data['bytes_read'] / $data['time']) . 'b');
|
|
||||||
|
|
||||||
# Bytes written
|
|
||||||
echo sprintf('%10s', Library_Analysis::byteResize($data['bytes_written'] / $data['time']) . 'b');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo str_pad('', 20, ' ') . '<span class="alert">An error has occured when retreiving or calculating stats</span>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# End of Line
|
|
||||||
echo EOL . '<hr>';
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
<?php
|
|
||||||
# Server seems down
|
|
||||||
if((isset($stats)) && (($stats === false) || ($stats == array())))
|
|
||||||
{ ?>
|
|
||||||
<div class="header corner full-size padding" style="margin-top:10px;text-align:center;">
|
|
||||||
<?php
|
|
||||||
# Asking server of cluster stats
|
|
||||||
if(isset($_GET['server']))
|
|
||||||
{
|
|
||||||
echo ($_ini->cluster($_GET['server'])) ? 'All servers from Cluster ' . $_GET['server'] : 'Server ' . $_GET['server'], ' did not respond !';
|
|
||||||
}
|
|
||||||
# All servers stats
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo 'Servers did not respond !';
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<span class="left">Error message</span>
|
|
||||||
<br/>
|
|
||||||
<?php echo Library_Data_Error::last(); ?>
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
Please check above error message, your <a href="configure.php" class="green">configuration</a> or your server status and retry
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
# No slabs used
|
|
||||||
elseif((isset($slabs)) && ($slabs === false))
|
|
||||||
{
|
|
||||||
?>
|
|
||||||
<div class="header corner full-size padding" style="margin-top:10px;text-align:center;">
|
|
||||||
No slabs used in this server !
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<span class="left">Error message</span>
|
|
||||||
<br/>
|
|
||||||
Maybe this server is not used, check your <a href="configure.php" class="green">configuration</a> or your server status and retry
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
# No Items in slab
|
|
||||||
elseif((isset($items)) && ($items === false))
|
|
||||||
{
|
|
||||||
?>
|
|
||||||
<div class="header corner full-size padding" style="margin-top:10px;text-align:center;">
|
|
||||||
No item in this slab !
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<span class="left">Error message</span>
|
|
||||||
<br/>
|
|
||||||
This slab is allocated, but is empty
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
Go back to <a href="?server=<?php echo $_GET['server']; ?>&show=slabs" class="green">Server Slabs</a>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
if((isset($response)) && ($response != array()))
|
|
||||||
{ ?>
|
|
||||||
<div class="sub-header corner full-size padding">Result</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<?php
|
|
||||||
foreach($response as $server => $result)
|
|
||||||
{ ?>
|
|
||||||
<pre style="font-size:12px;overflow:auto;" class="full-size"><?php echo htmlentities(trim($result), ENT_NOQUOTES, 'UTF-8'); ?></pre>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
<div class="sub-header corner full-size padding">
|
|
||||||
Items in Slab <?php echo $_GET['slab']; ?>, only showing first <?php echo $_ini->get('max_item_dump'); ?> items
|
|
||||||
<span style="float:right;"><a href="?server=<?php echo $_GET['server']; ?>&show=slabs">Back to Server Slabs</a></span>
|
|
||||||
</div>
|
|
||||||
<div class="container corner full-size padding">
|
|
||||||
<?php
|
|
||||||
$notFirst = false;
|
|
||||||
|
|
||||||
# Items
|
|
||||||
foreach($items as $key => $data)
|
|
||||||
{
|
|
||||||
# Checking if first item
|
|
||||||
if($notFirst) { echo '<hr/>'; }
|
|
||||||
?>
|
|
||||||
|
|
||||||
<a class="green item" href="index.php?server=<?php echo $_GET['server']; ?>&show=items&slab=<?php echo $_GET['slab']; ?>&request_key=<?php echo $key; ?>&request_api=<?php echo $_ini->get('get_api'); ?>&request_command=get"><?php echo ((strlen($key) > 70) ? substr($key, 0, 70) . '[..]' : $key); ?></a>
|
|
||||||
|
|
||||||
<span class="right" style="clear:right;">
|
|
||||||
<strong>Size</strong> : <?php echo Library_Analysis::byteResize($data[0]); ?>Bytes,
|
|
||||||
<strong>Expiration</strong> :
|
|
||||||
<?php
|
|
||||||
# Infinite expiration
|
|
||||||
if($data[1] == $infinite)
|
|
||||||
{
|
|
||||||
echo '∞';
|
|
||||||
}
|
|
||||||
# Timestamp expiration
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo Library_Analysis::uptime($data[1] - time());
|
|
||||||
} ?>
|
|
||||||
</span>
|
|
||||||
<?php
|
|
||||||
# First item done
|
|
||||||
$notFirst = true;
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
|
@ -1,126 +0,0 @@
|
||||||
<div class="size-4" style="float:left;">
|
|
||||||
<div class="sub-header corner padding">Slabs <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Slabs Used</span>
|
|
||||||
<?php echo $slabs['active_slabs']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Memory Used</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slabs['total_malloced']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Wasted</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slabs['total_wasted']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="size-2" style="float:left;padding-left:9px;margin-top:10px;">
|
|
||||||
<div class="header corner padding size-3cols" style="text-align:center;">
|
|
||||||
<a href="?server=<?php echo $_GET['server']; ?>">See this Server Stats</a>
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="size-1" style="float:left;padding-left:9px;">
|
|
||||||
<div class="container corner" style="padding:9px;">
|
|
||||||
For more informations about memcached slabs stats, see memcached protocol
|
|
||||||
<a href="http://github.com/memcached/memcached/blob/master/doc/protocol.txt#L470" target="_blank"><span class="green">here</span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="full-size" cellspacing="0" cellpadding="0">
|
|
||||||
<tr>
|
|
||||||
<?php
|
|
||||||
$actualSlab = 0;
|
|
||||||
|
|
||||||
# Slabs parsing
|
|
||||||
foreach($slabs as $id => $slab)
|
|
||||||
{
|
|
||||||
# If Slab is Used
|
|
||||||
if(is_numeric($id))
|
|
||||||
{
|
|
||||||
# Making a new line
|
|
||||||
if($actualSlab >= 4)
|
|
||||||
{
|
|
||||||
?>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<?php
|
|
||||||
$actualSlab = 0;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<td <?php if($actualSlab > 0) { echo 'style="padding-left:9px;"'; } ?> valign="top">
|
|
||||||
<div class="sub-header corner padding size-5">Slab <?php echo $id; ?> <span class="green">Stats</span>
|
|
||||||
<span style="float:right;"><a href="?server=<?php echo $_GET['server']; ?>&show=items&slab=<?php echo $id; ?>">See Slab Items</a></span>
|
|
||||||
</div>
|
|
||||||
<div class="container corner padding size-5">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Chunk Size</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slab['chunk_size']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Used Chunk</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($slab['used_chunks']); ?>
|
|
||||||
<span class="right">[<?php echo Library_Analysis::valueResize($slab['used_chunks'] / $slab['total_chunks'] * 100); ?> %]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Total Chunk</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($slab['total_chunks']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Total Page</span>
|
|
||||||
<?php echo $slab['total_pages']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Wasted</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slab['mem_wasted']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Hits</span>
|
|
||||||
<?php echo $slab['request_rate']; ?> Request/sec
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
if($slab['used_chunks'] > 0)
|
|
||||||
{ ?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Evicted</span>
|
|
||||||
<?php echo (isset($slab['items:evicted'])) ? $slab['items:evicted'] : 'N/A'; ?>
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Evicted Last</span>
|
|
||||||
<?php echo Library_Analysis::uptime($slab['items:evicted_time']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Out of Memory</span>
|
|
||||||
<?php echo $slab['items:outofmemory']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Tail Repairs</span>
|
|
||||||
<?php echo $slab['items:tailrepairs']; ?>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<?php }
|
|
||||||
else
|
|
||||||
{?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left slabs">Slab is allocated but empty</span>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<?php
|
|
||||||
$actualSlab++;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
for(true; $actualSlab < 4 ; $actualSlab++)
|
|
||||||
{
|
|
||||||
echo '<td style="width:100%;"></td>';
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
|
@ -1,356 +0,0 @@
|
||||||
<div class="size-4" style="float:left;">
|
|
||||||
<div class="sub-header corner padding">Get <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hits</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['get_hits']); ?>
|
|
||||||
<span class="right">[<?php echo $stats['get_hits_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Miss</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['get_misses']); ?>
|
|
||||||
<span class="right">[<?php echo $stats['get_misses_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo $stats['get_rate']; ?> Request/sec
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Set <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Total</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['cmd_set']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo $stats['set_rate']; ?> Request/sec
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Delete <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hits</span>
|
|
||||||
<?php echo (isset($stats['delete_hits'])) ? Library_Analysis::hitResize($stats['delete_hits']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['delete_hits_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Miss</span>
|
|
||||||
<?php echo (isset($stats['delete_misses'])) ? Library_Analysis::hitResize($stats['delete_misses']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['delete_misses_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo (isset($stats['delete_hits'])) ? $stats['delete_rate'] . ' Request/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Cas <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hits</span>
|
|
||||||
<?php echo (isset($stats['cas_hits'])) ? Library_Analysis::hitResize($stats['cas_hits']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['cas_hits_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Miss</span>
|
|
||||||
<?php echo (isset($stats['cas_misses'])) ? Library_Analysis::hitResize($stats['cas_misses']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['cas_misses_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Bad Value</span>
|
|
||||||
<?php echo (isset($stats['cas_badval'])) ? Library_Analysis::hitResize($stats['cas_badval']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['cas_badval_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo (isset($stats['cas_hits'])) ? $stats['cas_rate'] . ' Request/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Increment <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hits</span>
|
|
||||||
<?php echo (isset($stats['incr_hits'])) ? Library_Analysis::hitResize($stats['incr_hits']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['incr_hits_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Miss</span>
|
|
||||||
<?php echo (isset($stats['incr_misses'])) ? Library_Analysis::hitResize($stats['incr_misses']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['incr_misses_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo (isset($stats['incr_hits'])) ? $stats['incr_rate'] . ' Request/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Decrement <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Hits</span>
|
|
||||||
<?php echo (isset($stats['decr_hits'])) ? Library_Analysis::hitResize($stats['decr_hits']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['decr_hits_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Miss</span>
|
|
||||||
<?php echo (isset($stats['decr_misses'])) ? Library_Analysis::hitResize($stats['decr_misses']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
<span class="right">[<?php echo $stats['decr_misses_percent']; ?>%]</span>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo (isset($stats['decr_hits'])) ? $stats['decr_rate'] . ' Request/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Flush <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Total</span>
|
|
||||||
<?php echo (isset($stats['cmd_flush'])) ? Library_Analysis::hitResize($stats['cmd_flush']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Rate</span>
|
|
||||||
<?php echo (isset($stats['cmd_flush'])) ? $stats['flush_rate'] . ' Request/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="size-2" style="float:left;padding-left:9px;">
|
|
||||||
<?php
|
|
||||||
# Viewing a single server
|
|
||||||
if((isset($_GET['server'])) && ($_ini->server($_GET['server'])))
|
|
||||||
{ ?>
|
|
||||||
<div class="header corner padding size-3cols" style="text-align:center;margin-top:10px;">
|
|
||||||
<a href="?server=<?php echo $_GET['server']; ?>&show=slabs">See this Server Slabs Stats</a>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
<div class="sub-header corner padding"><?php echo (isset($_GET['server'])) && ($_ini->server($_GET['server'])) ? 'Server' : 'Cluster'; ?> <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding size-3cols">
|
|
||||||
<?php
|
|
||||||
# Viewing a single server
|
|
||||||
if((isset($_GET['server'])) && ($_ini->server($_GET['server'])))
|
|
||||||
{ ?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Uptime</span>
|
|
||||||
<?php echo Library_Analysis::uptime($stats['uptime']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="margin-bottom:4px;">
|
|
||||||
<span class="left setting">Memcached</span>
|
|
||||||
Version <?php echo $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Curr Connections</span>
|
|
||||||
<?php echo $stats['curr_connections']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Total Connections</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['total_connections']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Max Connections Errors</span>
|
|
||||||
<?php echo (isset($stats['listen_disabled_num'])) ? Library_Analysis::hitResize($stats['listen_disabled_num']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line" style="margin-top:4px;">
|
|
||||||
<span class="left setting">Current Items</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['curr_items']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Total Items</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['total_items']); ?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
# Viewing a single server
|
|
||||||
if((isset($_GET['server'])) && ($_ini->server($_GET['server'])))
|
|
||||||
{ ?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Oldest Item</span>
|
|
||||||
<?php echo (isset($settings['oldest'])) ? Library_Analysis::uptime($settings['oldest']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Eviction & Reclaimed <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Items Eviction</span>
|
|
||||||
<?php echo Library_Analysis::hitResize($stats['evictions']); ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Rate</span>
|
|
||||||
<?php echo $stats['eviction_rate']; ?> Eviction/sec
|
|
||||||
</div>
|
|
||||||
<div class="line" style="margin-top:4px;">
|
|
||||||
<span class="left setting">Reclaimed</span>
|
|
||||||
<?php echo (isset($stats['reclaimed'])) ? Library_Analysis::hitResize($stats['reclaimed']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting">Rate</span>
|
|
||||||
<?php echo (isset($stats['reclaimed'])) ? $stats['reclaimed_rate'] . ' Reclaimed/sec' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
# Viewing a server
|
|
||||||
if((isset($_GET['server'])) && ($_ini->server($_GET['server'])))
|
|
||||||
{ ?>
|
|
||||||
<div class="sub-header corner padding">Server <span class="green">Configuration</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : accepting_conns
Whether the server is accepting connection or not">Accepting Connections</span>
|
|
||||||
<?php
|
|
||||||
# Northscale/Membase server specific
|
|
||||||
if(isset($stats['accepting_conns']))
|
|
||||||
{
|
|
||||||
if($stats['accepting_conns']) { echo 'Yes'; } else { echo 'No'; }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo 'N/A on ' . $stats['version'];
|
|
||||||
}?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : maxbytes
Maximum number of bytes allowed in this cache">Max Bytes</span>
|
|
||||||
<?php echo (isset($settings['maxbytes'])) ? Library_Analysis::byteResize($settings['maxbytes']) . 'Bytes' : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : maxconns
Maximum number of clients allowed">Max Connection</span>
|
|
||||||
<?php echo (isset($settings['maxconns'])) ? $settings['maxconns'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : tcpport & udpport
TCP & UDP listen port">TCP/UDP Port</span>
|
|
||||||
<?php echo (isset($settings['tcpport'], $settings['udpport'])) ? 'TCP : ' . $settings['tcpport'] . ', UDP : ' . $settings['udpport'] : 'N/A on ' . $stats['version'] ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : inter
Listen interface">Listen Interface</span>
|
|
||||||
<?php echo (isset($settings['inter'])) ? $settings['inter'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : evictions
When Off, LRU evictions are disabled">Evictions</span>
|
|
||||||
<?php echo (isset($settings['evictions'])) ? ucfirst($settings['evictions']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : domain_socket
Path to the domain socket (if any)">Path to Domain Socket</span>
|
|
||||||
<?php echo (isset($settings['domain_socket'])) ? $settings['domain_socket'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : umask
Umask for the creation of the domain socket">Domain Socket Umask</span>
|
|
||||||
<?php echo (isset($settings['umask'])) ? $settings['umask'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : chunk_size
Minimum space allocated for key + value + flags">Chunk Size</span>
|
|
||||||
<?php echo (isset($settings['chunk_size'])) ? $settings['chunk_size'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : growth_factor
Chunk size growth factor">Chunk Growth Factor</span>
|
|
||||||
<?php echo (isset($settings['growth_factor'])) ? $settings['growth_factor'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : num_threads
Number of threads (including dispatch)">Max Threads</span>
|
|
||||||
<?php echo (isset($settings['num_threads'])) ? $settings['num_threads'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : detail_enabled
If yes, stats detail is enabled">Detail Enabled</span>
|
|
||||||
<?php echo (isset($settings['detail_enabled'])) ? ucfirst($settings['detail_enabled']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : reqs_per_event
Max num IO ops processed within an event">Max IO Ops/Event</span>
|
|
||||||
<?php echo (isset($settings['reqs_per_event'])) ? $settings['reqs_per_event'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : cas_enabled
When no, CAS is not enabled for this server">CAS Enabled</span>
|
|
||||||
<?php echo (isset($settings['cas_enabled'])) ? ucfirst($settings['cas_enabled']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : tcp_backlog
TCP listen backlog">TCP Listen Backlog</span>
|
|
||||||
<?php echo (isset($settings['tcp_backlog'])) ? $settings['tcp_backlog'] : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting" title="Internal name : auth_enabled_sasl
SASL auth requested and enabled">SASL Auth</span>
|
|
||||||
<?php echo (isset($settings['auth_enabled_sasl'])) ? ucfirst($settings['auth_enabled_sasl']) : 'N/A on ' . $stats['version']; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
# Viewing a cluster
|
|
||||||
elseif((isset($_GET['server'])) && ($cluster = $_ini->cluster($_GET['server'])))
|
|
||||||
{ ?>
|
|
||||||
<div class="sub-header corner padding">Cluster <?php echo $_GET['server']; ?> <span class="green">Servers List</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<?php
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{ ?>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left setting"><?php echo $server['hostname'] . ':' . $server['port']; ?></span>
|
|
||||||
<span class="right" style="font-weight:bold;"><a href="index.php?server=<?php echo $server['hostname'] . ':' . $server['port']; ?>" class="green">See Server Stats</a></span>
|
|
||||||
<div class="line" style="margin-left:5px;">
|
|
||||||
<?php echo ($status[$server['hostname'] . ':' . $server['port']] != '') ? 'Version ' . $status[$server['hostname'] . ':' . $server['port']] . ', Uptime : ' . Library_Analysis::uptime($uptime[$server['hostname'] . ':' . $server['port']]) : 'Server did not respond'; ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
} ?>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
# Making cache size stats
|
|
||||||
$wasted_percent = sprintf('%.0u', $slabs['total_wasted'] / $stats['limit_maxbytes'] * 100);
|
|
||||||
$used_percent = sprintf('%.0u', ($slabs['total_malloced'] - $slabs['total_wasted']) / $stats['limit_maxbytes'] * 100);
|
|
||||||
$free_percent = sprintf('%.0u', ($stats['limit_maxbytes'] - $slabs['total_malloced']) / $stats['limit_maxbytes'] * 100);
|
|
||||||
?>
|
|
||||||
<div class="size-4" style="float:left; padding-left:9px;clear:right;">
|
|
||||||
<div class="sub-header corner padding">Cache Size <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Used</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slabs['total_malloced']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Total</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($stats['limit_maxbytes']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Wasted</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($slabs['total_wasted']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Percent</span>
|
|
||||||
<?php echo sprintf('%.1f', $stats['bytes'] / $stats['limit_maxbytes'] * 100, 1); ?>%
|
|
||||||
</div>-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Cache Size <span class="green">Graphic</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<img src="http://chart.apis.google.com/chart?chf=bg,s,ebebeb&chs=280x225&cht=p&chco=b5463f|2a707b|ffffff&chd=t:<?php echo $wasted_percent; ?>,<?php echo $used_percent; ?>,<?php echo $free_percent; ?>&chdl=Wasted%20:%20<?php echo $wasted_percent; ?>%|Used%20:%20<?php echo $used_percent; ?>%|Free%20:%20<?php echo $free_percent; ?>%&chdlp=b" alt="Cache Size by GoogleCharts" width="280" height="225"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Hit & Miss Rate <span class="green">Graphic</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<img src="http://chart.apis.google.com/chart?cht=bvg&chd=t:<?php echo $stats['get_hits_percent']; ?>,<?php echo $stats['get_misses_percent']; ?>&chs=280x235&chl=Hit|Miss&chf=bg,s,ebebeb&chco=2a707b|b5463f&chxt=y&chbh=a&chm=N,000000,0,-1,11" alt="Cache Hit & Miss Rate by GoogleChart" width="280" height="235"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sub-header corner padding">Network <span class="green">Stats</span></div>
|
|
||||||
<div class="container corner padding">
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Bytes Read</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($stats['bytes_read']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
<div class="line">
|
|
||||||
<span class="left">Bytes Written</span>
|
|
||||||
<?php echo Library_Analysis::byteResize($stats['bytes_written']); ?>Bytes
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,276 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Executing commands
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 06/04/2010
|
|
||||||
*/
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
header('Content-type: text/html;');
|
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
|
||||||
|
|
||||||
# Require
|
|
||||||
require_once 'Library/Loader.php';
|
|
||||||
|
|
||||||
# Date timezone
|
|
||||||
date_default_timezone_set('Europe/Paris');
|
|
||||||
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing requests & response
|
|
||||||
$request = (isset($_GET['request_command'])) ? $_GET['request_command'] : null;
|
|
||||||
|
|
||||||
# Starting
|
|
||||||
ob_start();
|
|
||||||
|
|
||||||
# Display by request rype
|
|
||||||
switch($request)
|
|
||||||
{
|
|
||||||
# Memcache::get command
|
|
||||||
case 'get':
|
|
||||||
# Ask for get on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->get($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for get on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->get($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
# Ask for get on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->get($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Memcache::set command
|
|
||||||
case 'set':
|
|
||||||
# Ask for set on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->set($server['hostname'], $server['port'], $_GET['request_key'], $_GET['request_data'], $_GET['request_duration']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for set on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server set command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->set($server['hostname'], $server['port'], $_GET['request_key'], $_GET['request_data'], $_GET['request_duration']));
|
|
||||||
}
|
|
||||||
# Ask for set on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server set command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->set($server['hostname'], $server['port'], $_GET['request_key'], $_GET['request_data'], $_GET['request_duration']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Memcache::delete command
|
|
||||||
case 'delete':
|
|
||||||
# Ask for delete on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->delete($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for delete on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server delete command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->delete($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
# Ask for delete on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server delete command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->delete($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Memcache::flush_all command
|
|
||||||
case 'flush_all':
|
|
||||||
# Checking delay
|
|
||||||
if(!isset($_GET['request_delay']) || !is_numeric($_GET['request_delay']))
|
|
||||||
{
|
|
||||||
$_GET['request_delay'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ask for flush_all on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->flush_all($server['hostname'], $server['port'], $_GET['request_delay']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for flush_all on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server flush_all command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->flush_all($server['hostname'], $server['port'], $_GET['request_delay']));
|
|
||||||
}
|
|
||||||
# Ask for flush_all on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server flush_all command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api($_GET['request_api'])->flush_all($server['hostname'], $server['port'], $_GET['request_delay']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Memcache::search command
|
|
||||||
case 'search':
|
|
||||||
# Ask for flush_all on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server get command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->search($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for search on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server search command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->search($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
# Ask for search on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# Looking into each cluster
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server search command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->search($server['hostname'], $server['port'], $_GET['request_key']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Memcache::telnet command
|
|
||||||
case 'telnet':
|
|
||||||
# Ask for a telnet command on a cluster
|
|
||||||
if(isset($_GET['request_server']) && ($cluster = $_ini->cluster($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Dumping server telnet command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->telnet($server['hostname'], $server['port'], $_GET['request_telnet']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Ask for a telnet command on one server
|
|
||||||
elseif(isset($_GET['request_server']) && ($server = $_ini->server($_GET['request_server'])))
|
|
||||||
{
|
|
||||||
# Dumping server telnet command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->telnet($server['hostname'], $server['port'], $_GET['request_telnet']));
|
|
||||||
}
|
|
||||||
# Ask for a telnet command on all servers
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# Looking into each cluster
|
|
||||||
foreach($_ini->get('servers') as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Asking for each server stats
|
|
||||||
foreach($servers as $server)
|
|
||||||
{
|
|
||||||
# Dumping server telnet command response
|
|
||||||
echo Library_HTML_Components::serverResponse($server['hostname'], $server['port'],
|
|
||||||
Library_Command_Factory::api('Server')->telnet($server['hostname'], $server['port'], $_GET['request_telnet']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
# Default : No command
|
|
||||||
default :
|
|
||||||
# Showing header
|
|
||||||
include 'View/Header.tpl';
|
|
||||||
|
|
||||||
# Showing formulary
|
|
||||||
include 'View/Commands/Commands.tpl';
|
|
||||||
|
|
||||||
# Showing footer
|
|
||||||
include 'View/Footer.tpl';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ob_end_flush();
|
|
|
@ -1,127 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Configuration
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 06/04/2010
|
|
||||||
*/
|
|
||||||
# Headers
|
|
||||||
header('Content-type: text/html;');
|
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
|
||||||
|
|
||||||
# Require
|
|
||||||
require_once 'Library/Loader.php';
|
|
||||||
|
|
||||||
# Date timezone
|
|
||||||
date_default_timezone_set('Europe/Paris');
|
|
||||||
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing requests
|
|
||||||
$request = (isset($_GET['request_write'])) ? $_GET['request_write'] : null;
|
|
||||||
$write = null;
|
|
||||||
|
|
||||||
# Display by request rype
|
|
||||||
switch($request)
|
|
||||||
{
|
|
||||||
# Unlock configuration file & temp directory
|
|
||||||
case 'unlock':
|
|
||||||
# chmod 0755
|
|
||||||
chmod(Library_Configuration_Loader::path(), 0755);
|
|
||||||
chmod($_ini->get('file_path'), 0755);
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Live stats configuration save
|
|
||||||
case 'live_stats':
|
|
||||||
# Updating configuration
|
|
||||||
$_ini->set('refresh_rate', round(max(2, $_POST['refresh_rate'])));
|
|
||||||
$_ini->set('memory_alert', $_POST['memory_alert']);
|
|
||||||
$_ini->set('hit_rate_alert', $_POST['hit_rate_alert']);
|
|
||||||
$_ini->set('eviction_alert', $_POST['eviction_alert']);
|
|
||||||
$_ini->set('file_path', $_POST['file_path']);
|
|
||||||
|
|
||||||
# Writing configuration file
|
|
||||||
$write = Library_Configuration_Loader::singleton()->write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Commands configuration save
|
|
||||||
case 'commands':
|
|
||||||
# Updating configuration
|
|
||||||
$_ini->set('stats_api', $_POST['stats_api']);
|
|
||||||
$_ini->set('slabs_api', $_POST['slabs_api']);
|
|
||||||
$_ini->set('items_api', $_POST['items_api']);
|
|
||||||
$_ini->set('get_api', $_POST['get_api']);
|
|
||||||
$_ini->set('set_api', $_POST['set_api']);
|
|
||||||
$_ini->set('delete_api', $_POST['delete_api']);
|
|
||||||
$_ini->set('flush_all_api', $_POST['flush_all_api']);
|
|
||||||
|
|
||||||
# Writing configuration file
|
|
||||||
$write = Library_Configuration_Loader::singleton()->write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Server configuration save
|
|
||||||
case 'servers':
|
|
||||||
$array = array();
|
|
||||||
foreach($_POST['server'] as $cluster => $servers)
|
|
||||||
{
|
|
||||||
foreach($servers as $data)
|
|
||||||
{
|
|
||||||
$array[$_POST['cluster'][$cluster]][$data['hostname'] . ':' . $data['port']] = $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sorting clusters
|
|
||||||
ksort($array);
|
|
||||||
foreach($array as $cluster => $servers)
|
|
||||||
{
|
|
||||||
# Sorting servers
|
|
||||||
ksort($servers);
|
|
||||||
$array[$cluster] = $servers;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Updating configuration
|
|
||||||
$_ini->set('servers', $array);
|
|
||||||
|
|
||||||
# Writing configuration file
|
|
||||||
$write = Library_Configuration_Loader::singleton()->write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Miscellaneous configuration save
|
|
||||||
case 'miscellaneous':
|
|
||||||
# Updating configuration
|
|
||||||
$_ini->set('connection_timeout', $_POST['connection_timeout']);
|
|
||||||
$_ini->set('max_item_dump', $_POST['max_item_dump']);
|
|
||||||
|
|
||||||
# Writing configuration file
|
|
||||||
$write = Library_Configuration_Loader::singleton()->write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Default : No command
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Showing header
|
|
||||||
include 'View/Header.tpl';
|
|
||||||
|
|
||||||
# Showing formulary
|
|
||||||
include 'View/Configure/Configure.tpl';
|
|
||||||
|
|
||||||
# Showing footer
|
|
||||||
include 'View/Footer.tpl';
|
|
|
@ -1,176 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Stats viewing
|
|
||||||
*
|
|
||||||
* @author c.mahieux@of2m.fr
|
|
||||||
* @since 20/03/2010
|
|
||||||
*/
|
|
||||||
# Headers
|
|
||||||
header('Content-type: text/html; charset=UTF-8');
|
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
|
||||||
|
|
||||||
# Require
|
|
||||||
require_once 'Library/Loader.php';
|
|
||||||
|
|
||||||
# Date timezone
|
|
||||||
date_default_timezone_set('Europe/Paris');
|
|
||||||
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing requests
|
|
||||||
$request = (isset($_GET['show'])) ? $_GET['show'] : null;
|
|
||||||
|
|
||||||
# Getting default cluster
|
|
||||||
if(!isset($_GET['server']))
|
|
||||||
{
|
|
||||||
$clusters = array_keys($_ini->get('servers'));
|
|
||||||
$cluster = isset($clusters[0]) ? $clusters[0] : null;
|
|
||||||
$_GET['server'] = $cluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Showing header
|
|
||||||
include 'View/Header.tpl';
|
|
||||||
|
|
||||||
# Display by request type
|
|
||||||
switch($request)
|
|
||||||
{
|
|
||||||
# Items : Display of all items for a single slab for a single server
|
|
||||||
case 'items':
|
|
||||||
# Initializing items array
|
|
||||||
$server = null;
|
|
||||||
$items = false;
|
|
||||||
$response = array();
|
|
||||||
|
|
||||||
# Ask for one server and one slabs items
|
|
||||||
if(isset($_GET['server']) && ($server = $_ini->server($_GET['server'])))
|
|
||||||
{
|
|
||||||
$items = Library_Command_Factory::instance('items_api')->items($server['hostname'], $server['port'], $_GET['slab']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cheking if asking an item
|
|
||||||
if(isset($_GET['request_key']))
|
|
||||||
{
|
|
||||||
$response[$server['hostname'] . ':' . $server['port']] = Library_Command_Factory::instance('get_api')->get($server['hostname'], $server['port'], $_GET['request_key']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Getting stats to calculate server boot time
|
|
||||||
$stats = Library_Command_Factory::instance('stats_api')->stats($server['hostname'], $server['port']);
|
|
||||||
$infinite = (isset($stats['time'], $stats['uptime'])) ? ($stats['time'] - $stats['uptime']) : 0;
|
|
||||||
|
|
||||||
# Items are well formed
|
|
||||||
if($items !== false)
|
|
||||||
{
|
|
||||||
# Showing items
|
|
||||||
include 'View/Stats/Items.tpl';
|
|
||||||
}
|
|
||||||
# Items are not well formed
|
|
||||||
else
|
|
||||||
{
|
|
||||||
include 'View/Stats/Error.tpl';
|
|
||||||
}
|
|
||||||
unset($items);
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Slabs : Display of all slabs for a single server
|
|
||||||
case 'slabs':
|
|
||||||
# Initializing slabs array
|
|
||||||
$slabs = false;
|
|
||||||
|
|
||||||
# Ask for one server slabs
|
|
||||||
if(isset($_GET['server']) && ($server = $_ini->server($_GET['server'])))
|
|
||||||
{
|
|
||||||
# Spliting server in hostname:port
|
|
||||||
$slabs = Library_Command_Factory::instance('slabs_api')->slabs($server['hostname'], $server['port']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Slabs are well formed
|
|
||||||
if($slabs !== false)
|
|
||||||
{
|
|
||||||
# Analysis
|
|
||||||
$slabs = Library_Analysis::slabs($slabs);
|
|
||||||
include 'View/Stats/Slabs.tpl';
|
|
||||||
}
|
|
||||||
# Slabs are not well formed
|
|
||||||
else
|
|
||||||
{
|
|
||||||
include 'View/Stats/Error.tpl';
|
|
||||||
}
|
|
||||||
unset($slabs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Default : Stats for all or specific single server
|
|
||||||
default :
|
|
||||||
# Initializing stats & settings array
|
|
||||||
$stats = array();
|
|
||||||
$slabs = array();
|
|
||||||
$slabs['total_malloced'] = 0;
|
|
||||||
$slabs['total_wasted'] = 0;
|
|
||||||
$settings = array();
|
|
||||||
$status = array();
|
|
||||||
|
|
||||||
$cluster = null;
|
|
||||||
$server = null;
|
|
||||||
|
|
||||||
# Ask for a particular cluster stats
|
|
||||||
if(isset($_GET['server']) && ($cluster = $_ini->cluster($_GET['server'])))
|
|
||||||
{
|
|
||||||
foreach($cluster as $server)
|
|
||||||
{
|
|
||||||
# Getting Stats & Slabs stats
|
|
||||||
$data = array();
|
|
||||||
$data['stats'] = Library_Command_Factory::instance('stats_api')->stats($server['hostname'], $server['port']);
|
|
||||||
$data['slabs'] = Library_Analysis::slabs(Library_Command_Factory::instance('slabs_api')->slabs($server['hostname'], $server['port']));
|
|
||||||
$stats = Library_Analysis::merge($stats, $data['stats']);
|
|
||||||
|
|
||||||
# Computing stats
|
|
||||||
if(isset($data['slabs']['total_malloced'], $data['slabs']['total_wasted']))
|
|
||||||
{
|
|
||||||
$slabs['total_malloced'] += $data['slabs']['total_malloced'];
|
|
||||||
$slabs['total_wasted'] += $data['slabs']['total_wasted'];
|
|
||||||
}
|
|
||||||
$status[$server['hostname'] . ':' . $server['port']] = ($data['stats'] != array()) ? $data['stats']['version'] : '';
|
|
||||||
$uptime[$server['hostname'] . ':' . $server['port']] = ($data['stats'] != array()) ? $data['stats']['uptime'] : '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Asking for a server stats
|
|
||||||
elseif(isset($_GET['server']) && ($server = $_ini->server($_GET['server'])))
|
|
||||||
{
|
|
||||||
# Getting Stats & Slabs stats
|
|
||||||
$stats = Library_Command_Factory::instance('stats_api')->stats($server['hostname'], $server['port']);
|
|
||||||
$slabs = Library_Analysis::slabs(Library_Command_Factory::instance('slabs_api')->slabs($server['hostname'], $server['port']));
|
|
||||||
$settings = Library_Command_Factory::instance('stats_api')->settings($server['hostname'], $server['port']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Stats are well formed
|
|
||||||
if(($stats !== false) && ($stats != array()))
|
|
||||||
{
|
|
||||||
# Analysis
|
|
||||||
$stats = Library_Analysis::stats($stats);
|
|
||||||
include 'View/Stats/Stats.tpl';
|
|
||||||
}
|
|
||||||
# Stats are not well formed
|
|
||||||
else
|
|
||||||
{
|
|
||||||
include 'View/Stats/Error.tpl';
|
|
||||||
}
|
|
||||||
unset($stats);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
# Showing footer
|
|
||||||
include 'View/Footer.tpl';
|
|
|
@ -1,171 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright 2010 Cyrille Mahieux
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°> ><)))°>
|
|
||||||
*
|
|
||||||
* Live Stats top style
|
|
||||||
*
|
|
||||||
* @author Cyrille Mahieux : elijaa(at)free.fr
|
|
||||||
* @since 12/04/2010
|
|
||||||
*/
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
header('Content-type: text/html;');
|
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
|
||||||
|
|
||||||
# Require
|
|
||||||
require_once 'Library/Loader.php';
|
|
||||||
|
|
||||||
# Date timezone
|
|
||||||
date_default_timezone_set('Europe/Paris');
|
|
||||||
|
|
||||||
# Loading ini file
|
|
||||||
$_ini = Library_Configuration_Loader::singleton();
|
|
||||||
|
|
||||||
# Initializing requests
|
|
||||||
$request = (isset($_GET['request_command'])) ? $_GET['request_command'] : null;
|
|
||||||
|
|
||||||
# Stat of a particular cluster
|
|
||||||
if(isset($_GET['cluster']) && ($_GET['cluster'] != null))
|
|
||||||
{
|
|
||||||
$cluster = $_GET['cluster'];
|
|
||||||
}
|
|
||||||
# Getting default cluster
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$clusters = array_keys($_ini->get('servers'));
|
|
||||||
$cluster = isset($clusters[0]) ? $clusters[0] : null;
|
|
||||||
$_GET['cluster'] = $cluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Hashing cluster
|
|
||||||
$hash = md5($_GET['cluster']);
|
|
||||||
|
|
||||||
# Cookie @FIXME not a perfect method
|
|
||||||
if(!isset($_COOKIE['live_stats_id' . $hash]))
|
|
||||||
{
|
|
||||||
# Cleaning temporary directory
|
|
||||||
$files = glob($_ini->get('file_path') . '*', GLOB_NOSORT );
|
|
||||||
foreach($files as $path)
|
|
||||||
{
|
|
||||||
$stats = @stat($path);
|
|
||||||
if(isset($stats[9]) && ($stats[9] < (time() - 60*60*24)))
|
|
||||||
{
|
|
||||||
@unlink($path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generating unique id
|
|
||||||
$live_stats_id = rand() . $hash;
|
|
||||||
|
|
||||||
# Cookie
|
|
||||||
setcookie('live_stats_id' . $hash, $live_stats_id, time() + 60*60*24);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# Backup from a previous request
|
|
||||||
$live_stats_id = $_COOKIE['live_stats_id' . $hash];
|
|
||||||
}
|
|
||||||
|
|
||||||
# Live stats dump file
|
|
||||||
$file_path = rtrim($_ini->get('file_path'), '/') . DIRECTORY_SEPARATOR . 'live_stats.' . $live_stats_id;
|
|
||||||
|
|
||||||
# Display by request type
|
|
||||||
switch($request)
|
|
||||||
{
|
|
||||||
# Ajax ask : stats
|
|
||||||
case 'live_stats':
|
|
||||||
# Opening old stats dump
|
|
||||||
$previous = @unserialize(file_get_contents($file_path));
|
|
||||||
|
|
||||||
# Initializing variables
|
|
||||||
$actual = array();
|
|
||||||
$stats = array();
|
|
||||||
$time = 0;
|
|
||||||
|
|
||||||
# Requesting stats for each server
|
|
||||||
foreach($_ini->cluster($cluster) as $server)
|
|
||||||
{
|
|
||||||
# Start query time calculation
|
|
||||||
$time = microtime(true);
|
|
||||||
|
|
||||||
# Asking server for stats
|
|
||||||
$actual[$server['hostname'] . ':' . $server['port']] = Library_Command_Factory::instance('stats_api')->stats($server['hostname'], $server['port']);
|
|
||||||
|
|
||||||
# Calculating query time length
|
|
||||||
$actual[$server['hostname'] . ':' . $server['port']]['query_time'] = max((microtime(true) - $time) * 1000, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Analysing stats
|
|
||||||
foreach($_ini->cluster($cluster) as $server)
|
|
||||||
{
|
|
||||||
# Making an alias
|
|
||||||
$server = $server['hostname'] . ':' . $server['port'];
|
|
||||||
|
|
||||||
# Diff between old and new dump
|
|
||||||
$stats[$server] = Library_Analysis::diff($previous[$server], $actual[$server]);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Making stats for each server
|
|
||||||
foreach($stats as $server => $array)
|
|
||||||
{
|
|
||||||
# Analysing request
|
|
||||||
if((isset($stats[$server]['uptime'])) && ($stats[$server]['uptime'] > 0))
|
|
||||||
{
|
|
||||||
# Computing stats
|
|
||||||
$stats[$server] = Library_Analysis::stats($stats[$server]);
|
|
||||||
|
|
||||||
# Because we make a diff on every key, we must reasign some values
|
|
||||||
$stats[$server]['bytes_percent'] = sprintf('%.1f', $actual[$server]['bytes'] / $actual[$server]['limit_maxbytes'] * 100);
|
|
||||||
$stats[$server]['bytes'] = $actual[$server]['bytes'];
|
|
||||||
$stats[$server]['limit_maxbytes'] = $actual[$server]['limit_maxbytes'];
|
|
||||||
$stats[$server]['curr_connections'] = $actual[$server]['curr_connections'];
|
|
||||||
$stats[$server]['query_time'] = $actual[$server]['query_time'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Saving new stats dump
|
|
||||||
file_put_contents($file_path, serialize($actual));
|
|
||||||
|
|
||||||
# Showing stats
|
|
||||||
include 'View/LiveStats/Stats.tpl';
|
|
||||||
break;
|
|
||||||
|
|
||||||
# Default : No command
|
|
||||||
default :
|
|
||||||
# Initializing : making stats dump
|
|
||||||
$stats = array();
|
|
||||||
foreach($_ini->cluster($cluster) as $server)
|
|
||||||
{
|
|
||||||
$stats[$server['hostname'] . ':' . $server['port']] = Library_Command_Factory::instance('stats_api')->stats($server['hostname'], $server['port']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Saving first stats dump
|
|
||||||
file_put_contents($file_path, serialize($stats));
|
|
||||||
|
|
||||||
# Searching for connection error, adding some time to refresh rate to prevent error
|
|
||||||
$refresh_rate = max($_ini->get('refresh_rate'), count($_ini->cluster($cluster)) * 0.25 + (Library_Data_Error::count() * (0.5 + $_ini->get('connection_timeout'))));
|
|
||||||
|
|
||||||
# Showing header
|
|
||||||
include 'View/Header.tpl';
|
|
||||||
|
|
||||||
# Showing live stats frame
|
|
||||||
include 'View/LiveStats/Frame.tpl';
|
|
||||||
|
|
||||||
# Showing footer
|
|
||||||
include 'View/Footer.tpl';
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
phpRedisAdmin
|
|
||||||
=============
|
|
||||||
|
|
||||||
phpRedisAdmin is a simple web interface to manage [Redis](http://redis.io/) databases. It is released under the [Creative Commons Attribution 3.0 license](http://creativecommons.org/licenses/by/3.0/). This code is being developed and maintained by [Erik Dubbelboer](https://github.com/ErikDubbelboer/).
|
|
||||||
|
|
||||||
You can send comments, patches, questions [here on github](https://github.com/ErikDubbelboer/phpRedisAdmin/issues) or to erik@dubbelboer.com.
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
=======
|
|
||||||
|
|
||||||
You can find an example database at [http://dubbelboer.com/phpRedisAdmin/](http://dubbelboer.com/phpRedisAdmin/?view&key=example:hash)
|
|
||||||
|
|
||||||
|
|
||||||
Installing/Configuring
|
|
||||||
======================
|
|
||||||
|
|
||||||
You will need [phpredis](https://github.com/nicolasff/phpredis). See phpredis for install instructions.
|
|
||||||
|
|
||||||
You will need to edit config.inc.php with your redis information. You might also want to uncomment and change the login information in config.inc.php.
|
|
||||||
|
|
||||||
|
|
||||||
TODO
|
|
||||||
====
|
|
||||||
|
|
||||||
* Javascript sorting of tables
|
|
||||||
* Better error handling
|
|
||||||
* Move or Copy key to different server
|
|
||||||
* Importing JSON
|
|
||||||
* JSON export with seperate objects based on your seperator
|
|
||||||
|
|
||||||
|
|
||||||
Credits
|
|
||||||
=======
|
|
||||||
|
|
||||||
Icons by [http://p.yusukekamiyamane.com/](http://p.yusukekamiyamane.com/) ([https://github.com/yusukekamiyamane/fugue-icons/tree/master/icons-shadowless](https://github.com/yusukekamiyamane/fugue-icons/tree/master/icons-shadowless))
|
|
||||||
|
|
||||||
Favicon from [https://github.com/antirez/redis-io/blob/master/public/images/favicon.png](https://github.com/antirez/redis-io/blob/master/public/images/favicon.png)
|
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (!class_exists('Redis')) {
|
|
||||||
die('ERROR: phpredis is required. You can find phpredis at <a href="https://github.com/nicolasff/phpredis">https://github.com/nicolasff/phpredis</a>');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Undo magic quotes (both in keys and values)
|
|
||||||
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
|
|
||||||
$process = array(&$_GET, &$_POST);
|
|
||||||
|
|
||||||
while (list($key, $val) = each($process)) {
|
|
||||||
foreach ($val as $k => $v) {
|
|
||||||
unset($process[$key][$k]);
|
|
||||||
|
|
||||||
if (is_array($v)) {
|
|
||||||
$process[$key][stripslashes($k)] = $v;
|
|
||||||
$process[] = &$process[$key][stripslashes($k)];
|
|
||||||
} else {
|
|
||||||
$process[$key][stripslashes($k)] = stripslashes($v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($process);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// These includes are needed by each script.
|
|
||||||
require_once 'config.inc.php';
|
|
||||||
require_once 'functions.inc.php';
|
|
||||||
require_once 'page.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($config['login'])) {
|
|
||||||
require_once 'login.inc.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// phpredis types to string conversion array.
|
|
||||||
$redistypes = array(
|
|
||||||
Redis::REDIS_STRING => 'string',
|
|
||||||
Redis::REDIS_SET => 'set',
|
|
||||||
Redis::REDIS_LIST => 'list',
|
|
||||||
Redis::REDIS_ZSET => 'zset',
|
|
||||||
Redis::REDIS_HASH => 'hash',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($login['servers'])) {
|
|
||||||
$i = current($login['servers']);
|
|
||||||
} else {
|
|
||||||
$i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['s']) && is_numeric($_GET['s']) && ($_GET['s'] < count($config['servers']))) {
|
|
||||||
$i = $_GET['s'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$server = $config['servers'][$i];
|
|
||||||
$server['id'] = $i;
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($login, $login['servers'])) {
|
|
||||||
if (array_search($i, $login['servers']) === false) {
|
|
||||||
die('You are not allowed to access this database.');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($config['servers'] as $key => $ignore) {
|
|
||||||
if (array_search($key, $login['servers']) === false) {
|
|
||||||
unset($config['servers'][$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!isset($server['db'])) {
|
|
||||||
$server['db'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Setup a connection to Redis.
|
|
||||||
$redis = new Redis();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$redis->connect($server['host'], $server['port']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
die('ERROR: Could not connect to Redis ('.$server['host'].':'.$server['port'].')');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($server['auth'])) {
|
|
||||||
if (!$redis->auth($server['auth'])) {
|
|
||||||
die('ERROR: Authentication failed ('.$server['host'].':'.$server['port'].')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($server['db'] != 0) {
|
|
||||||
if (!$redis->select($server['db'])) {
|
|
||||||
die('ERROR: Selecting database failed ('.$server['host'].':'.$server['port'].','.$server['db'].')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
$config = array(
|
|
||||||
'servers' => array(
|
|
||||||
0 => array(
|
|
||||||
'name' => 'local server', // Optional name.
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => 6379,
|
|
||||||
|
|
||||||
// Optional Redis authentication.
|
|
||||||
//'auth' => 'redispasswordhere' // Warning: The password is sent in plain-text to the Redis server.
|
|
||||||
),
|
|
||||||
|
|
||||||
/*1 => array(
|
|
||||||
'host' => 'localhost',
|
|
||||||
'port' => 6380
|
|
||||||
),*/
|
|
||||||
|
|
||||||
/*2 => array(
|
|
||||||
'name' => 'local db 2',
|
|
||||||
'host' => 'localhost',
|
|
||||||
'port' => 6379,
|
|
||||||
'db' => 1 // Optional database number, see http://redis.io/commands/select
|
|
||||||
)*/
|
|
||||||
),
|
|
||||||
|
|
||||||
|
|
||||||
'seperator' => ':',
|
|
||||||
|
|
||||||
|
|
||||||
// Uncomment to show less information and make phpRedisAdmin fire less commands to the Redis server. Recommended for a really busy Redis server.
|
|
||||||
//'faster' => true,
|
|
||||||
|
|
||||||
|
|
||||||
// Uncomment to enable HTTP authentication
|
|
||||||
/*'login' => array(
|
|
||||||
// Username => Password
|
|
||||||
// Multiple combinations can be used
|
|
||||||
'admin' => array(
|
|
||||||
'password' => 'adminpassword',
|
|
||||||
),
|
|
||||||
'guest' => array(
|
|
||||||
'password' => '',
|
|
||||||
'servers' => array(1) // Optional list of servers this user can access.
|
|
||||||
)
|
|
||||||
),*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// You can ignore settings below this point.
|
|
||||||
|
|
||||||
'maxkeylen' => 100
|
|
||||||
);
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
html {
|
|
||||||
font-size: x-small; /* Wikipedia font-size scaling method */
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font: 116%/1.4em Verdana, sans-serif;
|
|
||||||
color: #000;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font: bold 190% "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font: bold 160% "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font: bold 130% "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr {
|
|
||||||
border-bottom: 1px dotted #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.clear {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.info {
|
|
||||||
color: #aaa;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.add {
|
|
||||||
padding: 3px 0 1px 20px;
|
|
||||||
background: url(../images/add.png) left center no-repeat;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
|
|
||||||
form {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
form p {
|
|
||||||
padding-left: 8em;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
form label {
|
|
||||||
float: left;
|
|
||||||
width: 7em;
|
|
||||||
margin-left: -8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
form .button {
|
|
||||||
margin-left: -7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#hkeyp, #indexp, #scorep {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-spacing: 0;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alt td {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
td div, th div {
|
|
||||||
padding: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.imgbut {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-top: -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.server {
|
|
||||||
float: left;
|
|
||||||
margin: 1em;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 24em;
|
|
||||||
height: 100%;
|
|
||||||
padding-left: 1em;
|
|
||||||
border-right: 1px solid #000;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar a, #sidebar a:visited {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#keys {
|
|
||||||
position: fixed;
|
|
||||||
top: 15.5em;
|
|
||||||
bottom: 0;
|
|
||||||
width: 24em;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys li {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys li.folder {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: .05em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys li.current a {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys li.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys .icon {
|
|
||||||
padding: 1px 0 1px 20px;
|
|
||||||
background: url(../images/folder-open.png) left center no-repeat;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys li.collapsed ul {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul {
|
|
||||||
margin-left: 6px;
|
|
||||||
background: url(../images/tree-vline.gif) repeat-y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li {
|
|
||||||
padding-left: 16px;
|
|
||||||
background: url(../images/tree-node.gif) no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li.folder {
|
|
||||||
background-image: url(../images/tree-folder-expanded.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li.folder.collapsed {
|
|
||||||
background-image: url(../images/tree-folder-collapsed.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li.last { /* Hard-coded substitute for :last-child */
|
|
||||||
margin-bottom: .3em;
|
|
||||||
background: #fff url(../images/tree-lastnode.gif) no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li.last.folder {
|
|
||||||
background-image: url(../images/tree-lastnode-expanded.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys ul ul li.last.folder.collapsed {
|
|
||||||
background-image: url(../images/tree-lastnode-collapsed.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys .deltree {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#keys .icon:hover .deltree {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#frame {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 25em;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#frame iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
if (!isset($_POST['post'])) {
|
|
||||||
die('Javascript needs to be enabled for you to delete keys.');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['key'])) {
|
|
||||||
// String
|
|
||||||
if (!isset($_GET['type']) || ($_GET['type'] == 'string')) {
|
|
||||||
// Delete the whole key.
|
|
||||||
$redis->delete($_GET['key']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if (($_GET['type'] == 'hash') && isset($_GET['hkey'])) {
|
|
||||||
// Delete only the field in the hash.
|
|
||||||
$redis->hDel($_GET['key'], $_GET['hkey']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if (($_GET['type'] == 'list') && isset($_GET['index'])) {
|
|
||||||
// Lists don't have simple delete operations.
|
|
||||||
// You can only remove something based on a value so we set the value at the index to some random value we hope doesn't occur elsewhere in the list.
|
|
||||||
$value = str_rand(69);
|
|
||||||
|
|
||||||
// This code assumes $value is not present in the list. To make sure of this we would need to check the whole list and place a Watch on it to make sure the list isn't modified in between.
|
|
||||||
$redis->lSet($_GET['key'], $_GET['index'], $value);
|
|
||||||
$redis->lRem($_GET['key'], $value, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
else if (($_GET['type'] == 'set') && isset($_GET['value'])) {
|
|
||||||
// Removing members from a set can only be done by supplying the member.
|
|
||||||
$redis->sRem($_GET['key'], $_GET['value']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZSet
|
|
||||||
else if (($_GET['type'] == 'zset') && isset($_GET['value'])) {
|
|
||||||
// Removing members from a zset can only be done by supplying the value.
|
|
||||||
$redis->zDelete($_GET['key'], $_GET['value']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
die('?view&s='.$server['id'].'&key='.urlencode($_GET['key']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['tree'])) {
|
|
||||||
$keys = $redis->keys($_GET['tree'].'*');
|
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
$redis->delete($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,186 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Are we editing or creating a new key?
|
|
||||||
$edit = false;
|
|
||||||
|
|
||||||
if (isset($_GET['key'], $_GET['type'])) {
|
|
||||||
if (($_GET['type'] == 'string') ||
|
|
||||||
(($_GET['type'] == 'hash') && isset($_GET['hkey'])) ||
|
|
||||||
(($_GET['type'] == 'list') && isset($_GET['index'])) ||
|
|
||||||
(($_GET['type'] == 'set' ) && isset($_GET['value'])) ||
|
|
||||||
(($_GET['type'] == 'zset') && isset($_GET['value']))) {
|
|
||||||
$edit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['type'], $_POST['key'], $_POST['value'])) {
|
|
||||||
// Don't allow keys that are to long (Redis supports keys that can be way to long to put in an url).
|
|
||||||
if (strlen($_POST['key']) > $config['maxkeylen']) {
|
|
||||||
die('ERROR: Your key is to long (max length is '.$config['maxkeylen'].')');
|
|
||||||
}
|
|
||||||
|
|
||||||
// String
|
|
||||||
if ($_POST['type'] == 'string') {
|
|
||||||
$redis->set($_POST['key'], $_POST['value']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if (($_POST['type'] == 'hash') && isset($_POST['hkey'])) {
|
|
||||||
if (strlen($_POST['hkey']) > $config['maxkeylen']) {
|
|
||||||
die('ERROR: Your hash key is to long (max length is '.$config['maxkeylen'].')');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($edit && !$redis->hExists($_POST['key'], $_POST['hkey'])) {
|
|
||||||
$redis->hDel($_POST['key'], $_GET['hkey']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$redis->hSet($_POST['key'], $_POST['hkey'], $_POST['value']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if (($_POST['type'] == 'list') && isset($_POST['index'])) {
|
|
||||||
$size = $redis->lSize($_POST['key']);
|
|
||||||
|
|
||||||
if (($_POST['index'] == '') ||
|
|
||||||
($_POST['index'] == $size) ||
|
|
||||||
($_POST['index'] == -1)) {
|
|
||||||
// Push it at the end
|
|
||||||
$redis->rPush($_POST['key'], $_POST['value']);
|
|
||||||
} else if (($_POST['index'] >= 0) &&
|
|
||||||
($_POST['index'] < $size)) {
|
|
||||||
// Overwrite an index
|
|
||||||
$redis->lSet($_POST['key'], $_POST['index'], $_POST['value']);
|
|
||||||
} else {
|
|
||||||
die('ERROR: Out of bounds index');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
else if ($_POST['type'] == 'set') {
|
|
||||||
if ($_POST['value'] != $_POST['oldvalue']) {
|
|
||||||
// The only way to edit a Set value is to add it and remove the old value.
|
|
||||||
$redis->sRem($_POST['key'], $_POST['oldvalue']);
|
|
||||||
$redis->sAdd($_POST['key'], $_POST['value']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZSet
|
|
||||||
else if (($_POST['type'] == 'zset') && isset($_POST['score'])) {
|
|
||||||
if ($_POST['value'] != $_POST['oldvalue']) {
|
|
||||||
// The only way to edit a ZSet value is to add it and remove the old value.
|
|
||||||
$redis->zDelete($_POST['key'], $_POST['oldvalue']);
|
|
||||||
$redis->zAdd($_POST['key'], $_POST['score'], $_POST['value']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Refresh the top so the key tree is updated.
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
top.location.href = top.location.pathname+'?view&s=<?php echo $server['id']?>&key=<?php echo urlencode($_POST['key'])?>';
|
|
||||||
</script>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get the current value.
|
|
||||||
$value = '';
|
|
||||||
|
|
||||||
if ($edit) {
|
|
||||||
// String
|
|
||||||
if ($_GET['type'] == 'string') {
|
|
||||||
$value = $redis->get($_GET['key']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if (($_GET['type'] == 'hash') && isset($_GET['hkey'])) {
|
|
||||||
$value = $redis->hGet($_GET['key'], $_GET['hkey']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if (($_GET['type'] == 'list') && isset($_GET['index'])) {
|
|
||||||
$value = $redis->lGet($_GET['key'], $_GET['index']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set, ZSet
|
|
||||||
else if ((($_GET['type'] == 'set') || ($_GET['type'] == 'zset')) && isset($_GET['value'])) {
|
|
||||||
$value = $_GET['value'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2><?php echo $edit ? 'Edit' : 'Add'?></h2>
|
|
||||||
<form action="<?php echo format_html($_SERVER['REQUEST_URI'])?>" method="post">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="type">Type:</label>
|
|
||||||
<select name="type" id="type">
|
|
||||||
<option value="string" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'string')) ? 'selected="selected"' : ''?>>String</option>
|
|
||||||
<option value="hash" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'hash' )) ? 'selected="selected"' : ''?>>Hash</option>
|
|
||||||
<option value="list" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'list' )) ? 'selected="selected"' : ''?>>List</option>
|
|
||||||
<option value="set" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'set' )) ? 'selected="selected"' : ''?>>Set</option>
|
|
||||||
<option value="zset" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'zset' )) ? 'selected="selected"' : ''?>>ZSet</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="key">Key:</label>
|
|
||||||
<input type="text" name="key" id="key" size="30" maxlength="30" <?php echo isset($_GET['key']) ? 'value="'.format_html($_GET['key']).'"' : ''?>>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="hkeyp">
|
|
||||||
<label for="khey">Hash key:</label>
|
|
||||||
<input type="text" name="hkey" id="hkey" size="30" maxlength="30" <?php echo isset($_GET['hkey']) ? 'value="'.format_html($_GET['hkey']).'"' : ''?>>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="indexp">
|
|
||||||
<label for="index">Index:</label>
|
|
||||||
<input type="text" name="index" id="index" size="30" <?php echo isset($_GET['index']) ? 'value="'.format_html($_GET['index']).'"' : ''?>> <span class="info">empty to append, -1 to prepend</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="scorep">
|
|
||||||
<label for="score">Score:</label>
|
|
||||||
<input type="text" name="score" id="score" size="30" <?php echo isset($_GET['score']) ? 'value="'.format_html($_GET['score']).'"' : ''?>>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="value">Value:</label>
|
|
||||||
<textarea name="value" id="value" cols="80" rows="20"><?php echo nl2br(format_html($value))?></textarea>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<input type="hidden" name="oldvalue" value="<?php echo format_html($value)?>">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="submit" class="button" value="<?php echo $edit ? 'Edit' : 'Add'?>">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,197 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Export to redis-cli commands
|
|
||||||
function export_redis($key) {
|
|
||||||
global $redistypes, $redis;
|
|
||||||
|
|
||||||
$type = $redis->type($key);
|
|
||||||
|
|
||||||
if (!isset($redistypes[$type])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $redistypes[$type];
|
|
||||||
|
|
||||||
|
|
||||||
// String
|
|
||||||
if ($type == 'string') {
|
|
||||||
echo 'SET "',addslashes($key),'" "',addslashes($redis->get($key)),'"',PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if ($type == 'hash') {
|
|
||||||
$values = $redis->hGetAll($key);
|
|
||||||
|
|
||||||
foreach ($values as $k => $v) {
|
|
||||||
echo 'HSET "',addslashes($key),'" "',addslashes($k),'" "',addslashes($v),'"',PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if ($type == 'list') {
|
|
||||||
$size = $redis->lSize($key);
|
|
||||||
|
|
||||||
for ($i = 0; $i < $size; ++$i) {
|
|
||||||
echo 'RPUSH "',addslashes($key),'" "',addslashes($redis->lGet($key, $i)),'"',PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
else if ($type == 'set') {
|
|
||||||
$values = $redis->sMembers($key);
|
|
||||||
|
|
||||||
foreach ($values as $v) {
|
|
||||||
echo 'SADD "',addslashes($key),'" "',addslashes($v),'"',PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZSet
|
|
||||||
else if ($type == 'zset') {
|
|
||||||
$values = $redis->zRange($key, 0, -1);
|
|
||||||
|
|
||||||
foreach ($values as $v) {
|
|
||||||
$s = $redis->zScore($key, $v);
|
|
||||||
|
|
||||||
echo 'ZADD "',addslashes($key),'" ',$s,' "',addslashes($v),'"',PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Return the JSON for this key
|
|
||||||
function export_json($key) {
|
|
||||||
global $redistypes, $redis;
|
|
||||||
|
|
||||||
$type = $redis->type($key);
|
|
||||||
|
|
||||||
if (!isset($redistypes[$type])) {
|
|
||||||
return 'undefined';
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $redistypes[$type];
|
|
||||||
|
|
||||||
|
|
||||||
// String
|
|
||||||
if ($type == 'string') {
|
|
||||||
$value = $redis->get($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if ($type == 'hash') {
|
|
||||||
$value = $redis->hGetAll($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if ($type == 'list') {
|
|
||||||
$size = $redis->lSize($key);
|
|
||||||
$value = array();
|
|
||||||
|
|
||||||
for ($i = 0; $i < $size; ++$i) {
|
|
||||||
$value[] = $redis->lGet($key, $i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
else if ($type == 'set') {
|
|
||||||
$value = $redis->sMembers($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ZSet
|
|
||||||
else if ($type == 'zset') {
|
|
||||||
$value = $redis->zRange($key, 0, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Export
|
|
||||||
if (isset($_POST['type'])) {
|
|
||||||
if ($_POST['type'] == 'json') {
|
|
||||||
$ext = 'js';
|
|
||||||
$ct = 'application/json';
|
|
||||||
} else {
|
|
||||||
$ext = 'redis';
|
|
||||||
$ct = 'text/plain';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
header('Content-type: '.$ct.'; charset=utf-8');
|
|
||||||
header('Content-Disposition: inline; filename="export.'.$ext.'"');
|
|
||||||
|
|
||||||
|
|
||||||
// JSON
|
|
||||||
if ($_POST['type'] == 'json') {
|
|
||||||
// Single key
|
|
||||||
if (isset($_GET['key'])) {
|
|
||||||
echo json_encode(export_json($_GET['key']));
|
|
||||||
} else { // All keys
|
|
||||||
$keys = $redis->keys('*');
|
|
||||||
$vals = array();
|
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
$vals[$key] = export_json($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode($vals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redis Commands
|
|
||||||
else {
|
|
||||||
// Single key
|
|
||||||
if (isset($_GET['key'])) {
|
|
||||||
export_redis($_GET['key']);
|
|
||||||
} else { // All keys
|
|
||||||
$keys = $redis->keys('*');
|
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
export_redis($key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Export <?php echo isset($_GET['key']) ? format_html($_GET['key']) : ''?></h2>
|
|
||||||
|
|
||||||
<form action="<?php echo format_html($_SERVER['REQUEST_URI'])?>" method="post">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="type">Type:</label>
|
|
||||||
<select name="type" id="type">
|
|
||||||
<option value="redis" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'redis')) ? 'selected="selected"' : ''?>>Redis</option>
|
|
||||||
<option value="json" <?php echo (isset($_GET['type']) && ($_GET['type'] == 'json' )) ? 'selected="selected"' : ''?>>JSON</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="submit" class="button" value="Export">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,3 +0,0 @@
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,66 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
function format_html($str) {
|
|
||||||
return htmlentities($str, ENT_COMPAT, 'UTF-8');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function format_ago($time, $ago = false) {
|
|
||||||
$minute = 60;
|
|
||||||
$hour = $minute * 60;
|
|
||||||
$day = $hour * 24;
|
|
||||||
|
|
||||||
$when = $time;
|
|
||||||
|
|
||||||
if ($when >= 0)
|
|
||||||
$suffix = 'ago';
|
|
||||||
else {
|
|
||||||
$when = -$when;
|
|
||||||
$suffix = 'in the future';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($when > $day) {
|
|
||||||
$when = round($when / $day);
|
|
||||||
$what = 'day';
|
|
||||||
} else if ($when > $hour) {
|
|
||||||
$when = round($when / $hour);
|
|
||||||
$what = 'hour';
|
|
||||||
} else if ($when > $minute) {
|
|
||||||
$when = round($when / $minute);
|
|
||||||
$what = 'minute';
|
|
||||||
} else {
|
|
||||||
$what = 'second';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($when != 1) $what .= 's';
|
|
||||||
|
|
||||||
if ($ago) {
|
|
||||||
return "$when $what $suffix";
|
|
||||||
} else {
|
|
||||||
return "$when $what";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function format_size($size) {
|
|
||||||
$sizes = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
|
||||||
|
|
||||||
if ($size == 0) {
|
|
||||||
return '0 B';
|
|
||||||
} else {
|
|
||||||
return round($size / pow(1024, ($i = floor(log($size, 1024)))), 1).' '.$sizes[$i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function str_rand($length) {
|
|
||||||
$r = '';
|
|
||||||
|
|
||||||
for (; $length > 0; --$length) {
|
|
||||||
$r .= chr(rand(32, 126)); // 32 - 126 is the printable ascii range
|
|
||||||
}
|
|
||||||
|
|
||||||
return $r;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
|
||||||
header('Cache-Control: private');
|
|
||||||
|
|
||||||
?><!DOCTYPE html>
|
|
||||||
<html lang=en>
|
|
||||||
<head>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
|
|
||||||
<?php if (is_ie()) {
|
|
||||||
// Always force latest IE rendering engine and chrome frame (also hides compatibility mode button)
|
|
||||||
?><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><?php
|
|
||||||
} ?>
|
|
||||||
|
|
||||||
<?php /* Disable phone number detection on apple devices. */?>
|
|
||||||
<meta name=format-detection content="telephone=no">
|
|
||||||
|
|
||||||
<?php /* I don't think we ever want this to be indexed*/ ?>
|
|
||||||
<meta name=robots content="noindex,nofollow,noarchive">
|
|
||||||
|
|
||||||
<meta name=author content="https://github.com/ErikDubbelboer/">
|
|
||||||
|
|
||||||
<title><?php echo format_html($server['host'])?> - phpRedisAdmin</title>
|
|
||||||
|
|
||||||
<?php foreach ($page['css'] as $css) { ?>
|
|
||||||
<link rel=stylesheet href="css/<?php echo $css; ?>.css?v1" media=all>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="images/favicon.png">
|
|
||||||
|
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js"></script>
|
|
||||||
|
|
||||||
<?php foreach ($page['js'] as $js) { ?>
|
|
||||||
<script src="js/<?php echo $js; ?>.js?v1"></script>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
Before Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 346 B |
Before Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 640 B |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 534 B |
Before Width: | Height: | Size: 692 B |
Before Width: | Height: | Size: 732 B |
Before Width: | Height: | Size: 657 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 465 B |
Before Width: | Height: | Size: 118 B |
Before Width: | Height: | Size: 114 B |
Before Width: | Height: | Size: 109 B |
Before Width: | Height: | Size: 105 B |
Before Width: | Height: | Size: 64 B |
Before Width: | Height: | Size: 74 B |
Before Width: | Height: | Size: 44 B |
|
@ -1,122 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This mess could need some cleanup!
|
|
||||||
if (isset($_POST['commands'])) {
|
|
||||||
// Append some spaces at the end to make sure we always have enough arguments for the last function.
|
|
||||||
$commands = str_getcsv(str_replace(array("\r", "\n"), array('', ' '), $_POST['commands']).' ', ' ');
|
|
||||||
|
|
||||||
foreach ($commands as &$command) {
|
|
||||||
$command = stripslashes($command);
|
|
||||||
}
|
|
||||||
unset($command);
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($commands); ++$i) {
|
|
||||||
if (empty($commands[$i])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$commands[$i] = strtoupper($commands[$i]);
|
|
||||||
|
|
||||||
switch ($commands[$i]) {
|
|
||||||
case 'SET': {
|
|
||||||
$redis->set($commands[$i+1], $commands[$i+2]);
|
|
||||||
$i += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'HSET': {
|
|
||||||
$redis->hSet($commands[$i+1], $commands[$i+2], $commands[$i+3]);
|
|
||||||
$i += 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'LPUSH': {
|
|
||||||
$redis->lPush($commands[$i+1], $commands[$i+2]);
|
|
||||||
$i += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'RPUSH': {
|
|
||||||
$redis->rPush($commands[$i+1], $commands[$i+2]);
|
|
||||||
$i += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'LSET': {
|
|
||||||
$redis->lSet($commands[$i+1], $commands[$i+2], $commands[$i+3]);
|
|
||||||
$i += 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SADD': {
|
|
||||||
$redis->sAdd($commands[$i+1], $commands[$i+2]);
|
|
||||||
$i += 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'ZADD': {
|
|
||||||
$redis->zAdd($commands[$i+1], $commands[$i+2], $commands[$i+3]);
|
|
||||||
$i += 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Refresh the top so the key tree is updated.
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
top.location.href = top.location.pathname+'?overview&s=<?php echo $server['id']?>';
|
|
||||||
</script>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Import</h2>
|
|
||||||
<form action="<?php echo format_html($_SERVER['REQUEST_URI'])?>" method="post">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="commands">Commands:<br>
|
|
||||||
<br>
|
|
||||||
<span class="info">
|
|
||||||
Valid are:<br>
|
|
||||||
SET<br>
|
|
||||||
HSET<br>
|
|
||||||
LPUSH<br>
|
|
||||||
RPUSH<br>
|
|
||||||
LSET<br>
|
|
||||||
SADD<br>
|
|
||||||
ZADD
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<textarea name="commands" id="commands" cols="80" rows="20"></textarea>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="submit" class="button" value="Import">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,205 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get all keys from Redis.
|
|
||||||
$keys = $redis->keys('*');
|
|
||||||
|
|
||||||
sort($keys);
|
|
||||||
|
|
||||||
$namespaces = array(); // Array to hold our top namespaces.
|
|
||||||
|
|
||||||
// Build an array of nested arrays containing all our namespaces and containing keys.
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
// Ignore keys that are to long (Redis supports keys that can be way to long to put in an url).
|
|
||||||
if (strlen($key) > $config['maxkeylen']) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$key = explode($config['seperator'], $key);
|
|
||||||
|
|
||||||
// $d will be a reference to the current namespace.
|
|
||||||
$d = &$namespaces;
|
|
||||||
|
|
||||||
// We loop though all the namespaces for this key creating the array for each.
|
|
||||||
// Each time updating $d to be a reference to the last namespace so we can create the next one in it.
|
|
||||||
for ($i = 0; $i < (count($key) - 1); ++$i) {
|
|
||||||
if (!isset($d[$key[$i]])) {
|
|
||||||
$d[$key[$i]] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$d = &$d[$key[$i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Containing an item named __phpredisadmin__ means it's also a key.
|
|
||||||
// This means that creating an actual key named __phpredisadmin__ will make this bug.
|
|
||||||
$d[$key[count($key) - 1]] = array('__phpredisadmin__' => true);
|
|
||||||
|
|
||||||
// Unset $d so we don't accidentally overwrite it somewhere else.
|
|
||||||
unset($d);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This is basically the same as the click code in index.js.
|
|
||||||
// Just build the url for the frame based on our own url.
|
|
||||||
if (count($_GET) == 0) {
|
|
||||||
$iframe = 'overview.php';
|
|
||||||
} else {
|
|
||||||
$iframe = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], '?') + 1);
|
|
||||||
|
|
||||||
if (strpos($iframe, '&') !== false) {
|
|
||||||
$iframe = substr_replace($iframe, '.php?', strpos($iframe, '&'), 1);
|
|
||||||
} else {
|
|
||||||
$iframe .= '.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Recursive function used to print the namespaces.
|
|
||||||
function print_namespace($item, $name, $fullkey, $islast) {
|
|
||||||
global $config, $redistypes, $server, $redis;
|
|
||||||
|
|
||||||
// Is this also a key and not just a namespace?
|
|
||||||
if (isset($item['__phpredisadmin__'])) {
|
|
||||||
// Unset it so we won't loop over it when printing this namespace.
|
|
||||||
unset($item['__phpredisadmin__']);
|
|
||||||
|
|
||||||
$type = $redis->type($fullkey);
|
|
||||||
|
|
||||||
if (!isset($redistypes[$type])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $redistypes[$type];
|
|
||||||
$class = array();
|
|
||||||
$len = false;
|
|
||||||
|
|
||||||
if (isset($_GET['key']) && ($fullkey == $_GET['key'])) {
|
|
||||||
$class[] = 'current';
|
|
||||||
}
|
|
||||||
if ($islast) {
|
|
||||||
$class[] = 'last';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the number of items in the key.
|
|
||||||
if (!isset($config['faster']) || !$config['faster']) {
|
|
||||||
switch ($type) {
|
|
||||||
case 'hash':
|
|
||||||
$len = $redis->hLen($fullkey);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'list':
|
|
||||||
$len = $redis->lSize($fullkey);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'set':
|
|
||||||
// This is currently the only way to do this, this can be slow since we need to retrieve all keys
|
|
||||||
$len = count($redis->sMembers($fullkey));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'zset':
|
|
||||||
// This is currently the only way to do this, this can be slow since we need to retrieve all keys
|
|
||||||
$len = count($redis->zRange($fullkey, 0, -1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
<li<?php echo empty($class) ? '' : ' class="'.implode(' ', $class).'"'?>>
|
|
||||||
<a href="?view&s=<?php echo $server['id']?>&key=<?php echo urlencode($fullkey)?>"><?php echo format_html($name)?><?php if ($len !== false) { ?><span class="info">(<?php echo $len?>)</span><?php } ?></a>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does this namespace also contain subkeys?
|
|
||||||
if (count($item) > 0) {
|
|
||||||
?>
|
|
||||||
<li class="folder<?php echo empty($fullkey) ? '' : ' collapsed'?><?php echo $islast ? ' last' : ''?>">
|
|
||||||
<div class="icon"><?php echo format_html($name)?> <span class="info">(<?php echo count($item)?>)</span>
|
|
||||||
<?php if (!empty($fullkey)) { ?><a href="delete.php?s=<?php echo $server['id']?>&tree=<?php echo urlencode($fullkey)?>:" class="deltree"><img src="images/delete.png" width="10" height="10" title="Delete tree" alt="[X]"></a><?php } ?>
|
|
||||||
</div><ul>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$l = count($item);
|
|
||||||
|
|
||||||
foreach ($item as $childname => $childitem) {
|
|
||||||
// $fullkey will be empty on the first call.
|
|
||||||
if (empty($fullkey)) {
|
|
||||||
$childfullkey = $childname;
|
|
||||||
} else {
|
|
||||||
$childfullkey = $fullkey.$config['seperator'].$childname;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_namespace($childitem, $childname, $childfullkey, (--$l == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'index';
|
|
||||||
$page['js'][] = 'index';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
<h1 class="logo"><a href="?overview&s=<?php echo $server['id']?>">phpRedisAdmin</a></h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<select id="server">
|
|
||||||
<?php foreach ($config['servers'] as $i => $srv) { ?>
|
|
||||||
<option value="<?php echo $i?>" <?php echo ($server['id'] == $i) ? 'selected="selected"' : ''?>><?php echo isset($srv['name']) ? format_html($srv['name']) : $srv['host'].':'.$srv['port']?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<?php if (isset($login)) { ?>
|
|
||||||
<a href="logout.php"><img src="images/logout.png" width="16" height="16" title="Logout" alt="[L]"></a>
|
|
||||||
<?php } ?>
|
|
||||||
<a href="?info&s=<?php echo $server['id']?>"><img src="images/info.png" width="16" height="16" title="Info" alt="[I]"></a>
|
|
||||||
<a href="?export&s=<?php echo $server['id']?>"><img src="images/export.png" width="16" height="16" title="Export" alt="[E]"></a>
|
|
||||||
<a href="?import&s=<?php echo $server['id']?>"><img src="images/import.png" width="16" height="16" title="Import" alt="[I]"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="?edit&s=<?php echo $server['id']?>" class="add">Add another key</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="text" id="filter" size="24" value="type here to filter" class="info">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div id="keys">
|
|
||||||
<ul>
|
|
||||||
<?php print_namespace($namespaces, 'Keys', '', empty($namespaces))?>
|
|
||||||
</ul>
|
|
||||||
</div><!-- #keys -->
|
|
||||||
|
|
||||||
<div id="frame">
|
|
||||||
<iframe src="<?php echo format_html($iframe)?>" id="iframe" frameborder="0" scrolling="0"></iframe>
|
|
||||||
</div><!-- #frame -->
|
|
||||||
|
|
||||||
</div><!-- #sidebar -->
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,60 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_GET['reset']) && method_exists($redis, 'resetStat')) {
|
|
||||||
$redis->resetStat();
|
|
||||||
|
|
||||||
header('Location: info.php');
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fetch the info
|
|
||||||
$info = $redis->info();
|
|
||||||
$alt = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Info</h2>
|
|
||||||
|
|
||||||
<?php if (method_exists($redis, 'resetStat')) { ?>
|
|
||||||
<p>
|
|
||||||
<a href="?reset&s=<?php echo $server['id']?>" class="reset">Reset usage statistics</a>
|
|
||||||
</p>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr><th><div>Key</div></th><th><div>Value</div></th></tr>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
foreach ($info as $key => $value) {
|
|
||||||
if ($key == 'allocation_stats') { // This key is very long to split it into multiple lines
|
|
||||||
$value = str_replace(',', ",\n", $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<tr <?php echo $alt ? 'class="alt"' : ''?>><td><div><?php echo format_html($key)?></div></td><td><div><?php echo nl2br(format_html($value))?></div></td></tr>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$alt = !$alt;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
</table>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,30 +0,0 @@
|
||||||
|
|
||||||
$(function() {
|
|
||||||
if (history.replaceState) {
|
|
||||||
window.parent.history.replaceState({}, '', document.location.href.replace('?', '&').replace(/([a-z]*)\.php/, '?$1'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$('#type').change(function(e) {
|
|
||||||
$('#hkeyp' ).css('display', e.target.value == 'hash' ? 'block' : 'none');
|
|
||||||
$('#indexp').css('display', e.target.value == 'list' ? 'block' : 'none');
|
|
||||||
$('#scorep').css('display', e.target.value == 'zset' ? 'block' : 'none');
|
|
||||||
}).change();
|
|
||||||
|
|
||||||
|
|
||||||
$('.delkey, .delval').click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (confirm($(this).hasClass('delkey') ? 'Are you sure you want to delete this key and all it\'s values?' : 'Are you sure you want to delete this value?')) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: this.href,
|
|
||||||
data: 'post=1',
|
|
||||||
success: function(url) {
|
|
||||||
top.location.href = top.location.pathname+url;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
|
|
||||||
$(function() {
|
|
||||||
$('#sidebar a').click(function(e) {
|
|
||||||
if (e.currentTarget.href.indexOf('/?') == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var href;
|
|
||||||
|
|
||||||
if ((e.currentTarget.href.indexOf('?') == -1) ||
|
|
||||||
(e.currentTarget.href.indexOf('?') == (e.currentTarget.href.length - 1))) {
|
|
||||||
href = 'overview.php';
|
|
||||||
} else {
|
|
||||||
href = e.currentTarget.href.substr(e.currentTarget.href.indexOf('?') + 1);
|
|
||||||
|
|
||||||
if (href.indexOf('&') != -1) {
|
|
||||||
href = href.replace('&', '.php?');
|
|
||||||
} else {
|
|
||||||
href += '.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#iframe').attr('src', href);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$('#server').change(function(e) {
|
|
||||||
if (location.href.indexOf('?') == -1) {
|
|
||||||
location.href = location.href+'?s='+e.target.value;
|
|
||||||
} else if (location.href.indexOf('&s=') == -1) {
|
|
||||||
location.href = location.href+'&s='+e.target.value;
|
|
||||||
} else {
|
|
||||||
location.href = location.href.replace(/s=[0-9]*/, 's='+e.target.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$('li.current').parents('li.folder').removeClass('collapsed');
|
|
||||||
|
|
||||||
$('li.folder').click(function(e) {
|
|
||||||
var t = $(this);
|
|
||||||
|
|
||||||
if ((e.pageY >= t.offset().top) &&
|
|
||||||
(e.pageY <= t.offset().top + t.children('div').height())) {
|
|
||||||
e.stopPropagation();
|
|
||||||
t.toggleClass('collapsed');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('a').click(function() {
|
|
||||||
$('li.current').removeClass('current');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('li a').click(function() {
|
|
||||||
$(this).parent().addClass('current');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$('#filter').focus(function() {
|
|
||||||
if ($(this).hasClass('info')) {
|
|
||||||
$(this).removeClass('info').val('');
|
|
||||||
}
|
|
||||||
}).keyup(function() {
|
|
||||||
var val = $(this).val();
|
|
||||||
|
|
||||||
$('li:not(.folder)').each(function(i, el) {
|
|
||||||
var key = $('a', el).get(0);
|
|
||||||
var key = unescape(key.href.substr(key.href.indexOf('key=') + 4));
|
|
||||||
|
|
||||||
if (key.indexOf(val) == -1) {
|
|
||||||
$(el).addClass('hidden');
|
|
||||||
} else {
|
|
||||||
$(el).removeClass('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('li.folder').each(function(i, el) {
|
|
||||||
if ($('li:not(.hidden, .folder)', el).length == 0) {
|
|
||||||
$(el).addClass('hidden');
|
|
||||||
} else {
|
|
||||||
$(el).removeClass('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.deltree').click(function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (confirm('Are you sure you want to delete this whole tree and all it\'s keys?')) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: this.href,
|
|
||||||
data: 'post=1',
|
|
||||||
success: function(url) {
|
|
||||||
top.location.href = top.location.pathname;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// This fill will perform HTTP digest authentication. This is not the most secure form of authentication so be carefull when using this.
|
|
||||||
|
|
||||||
|
|
||||||
$realm = 'phpRedisAdmin';
|
|
||||||
|
|
||||||
// Using the md5 of the user agent and IP should make it a bit harder to intercept and reuse the responses.
|
|
||||||
$opaque = md5('phpRedisAdmin'.$_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR']);
|
|
||||||
|
|
||||||
|
|
||||||
if (!isset($_SERVER['PHP_AUTH_DIGEST']) || empty($_SERVER['PHP_AUTH_DIGEST'])) {
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
$needed_parts = array(
|
|
||||||
'nonce' => 1,
|
|
||||||
'nc' => 1,
|
|
||||||
'cnonce' => 1,
|
|
||||||
'qop' => 1,
|
|
||||||
'username' => 1,
|
|
||||||
'uri' => 1,
|
|
||||||
'response' => 1
|
|
||||||
);
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$keys = implode('|', array_keys($needed_parts));
|
|
||||||
|
|
||||||
preg_match_all('/('.$keys.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))/', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
foreach ($matches as $m) {
|
|
||||||
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
|
|
||||||
unset($needed_parts[$m[1]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($needed_parts)) {
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($config['login'][$data['username']])) {
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
|
|
||||||
die('Invalid username and/or password combination.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$login = $config['login'][$data['username']];
|
|
||||||
$login['name'] = $data['username'];
|
|
||||||
|
|
||||||
$password = md5($login['name'].':'.$realm.':'.$login['password']);
|
|
||||||
|
|
||||||
$response = md5($password.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']));
|
|
||||||
|
|
||||||
if ($data['response'] != $response) {
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.$opaque.'"');
|
|
||||||
die('Invalid username and/or password combination.');
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
$needed_parts = array(
|
|
||||||
'nonce' => 1,
|
|
||||||
'nc' => 1,
|
|
||||||
'cnonce' => 1,
|
|
||||||
'qop' => 1,
|
|
||||||
'username' => 1,
|
|
||||||
'uri' => 1,
|
|
||||||
'response' => 1
|
|
||||||
);
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$keys = implode('|', array_keys($needed_parts));
|
|
||||||
|
|
||||||
preg_match_all('/('.$keys.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))/', $_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
foreach ($matches as $m) {
|
|
||||||
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
|
|
||||||
unset($needed_parts[$m[1]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!isset($_GET['nonce'])) {
|
|
||||||
header('Location: logout.php?nonce='.$data['nonce']);
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($data['nonce'] == $_GET['nonce']) {
|
|
||||||
unset($_SERVER['PHP_AUTH_DIGEST']);
|
|
||||||
|
|
||||||
require 'login.inc.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
header('Location: '.substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], 'logout.php')));
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,84 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$info = array();
|
|
||||||
|
|
||||||
foreach ($config['servers'] as $i => $server) {
|
|
||||||
if (!isset($server['db'])) {
|
|
||||||
$server['db'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup a connection to this Redis server.
|
|
||||||
$redis->close();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$redis->connect($server['host'], $server['port']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
die('ERROR: Could not connect to Redis ('.$server['host'].':'.$server['port'].')');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($server['auth'])) {
|
|
||||||
if (!$redis->auth($server['auth'])) {
|
|
||||||
die('ERROR: Authentication failed ('.$server['host'].':'.$server['port'].')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($server['db'] != 0) {
|
|
||||||
if (!$redis->select($server['db'])) {
|
|
||||||
die('ERROR: Selecting database failed ('.$server['host'].':'.$server['port'].','.$server['db'].')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$info[$i] = $redis->info();
|
|
||||||
$info[$i]['size'] = $redis->dbSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<?php foreach ($config['servers'] as $i => $server) { ?>
|
|
||||||
<div class="server">
|
|
||||||
<h2><?php echo isset($server['name']) ? $server['name'] : format_html($server['host'])?></h2>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
|
|
||||||
<tr><td><div>Redis version:</div></td><td><div><?php echo $info[$i]['redis_version']?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Keys:</div></td><td><div><?php echo $info[$i]['size']?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Memory used:</div></td><td><div><?php echo format_size($info[$i]['used_memory'])?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Uptime:</div></td><td><div><?php echo format_ago($info[$i]['uptime_in_seconds'])?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Last save:</div></td><td><div><?php echo format_ago(time() - $info[$i]['last_save_time'], true)?> <a href="save.php?s=<?php echo $i?>"><img src="images/save.png" width="16" height="16" title="Save Now" alt="[S]" class="imgbut"></a></div></td></tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<p class="clear">
|
|
||||||
<a href="https://github.com/ErikDubbelboer/phpRedisAdmin" target="_blank">phpRedisAdmin on GitHub</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="http://redis.io/documentation" target="_blank">Redis Documentation</a>
|
|
||||||
</p>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
// Returns true when the user is using IE
|
|
||||||
function is_ie() {
|
|
||||||
if (isset($_SERVER['HTTP_USER_AGENT']) &&
|
|
||||||
(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page = array(
|
|
||||||
'css' => array('common'),
|
|
||||||
'js' => array()
|
|
||||||
);
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['old'], $_POST['key'])) {
|
|
||||||
if (strlen($_POST['key']) > $config['maxkeylen']) {
|
|
||||||
die('ERROR: Your key is to long (max length is '.$config['maxkeylen'].')');
|
|
||||||
}
|
|
||||||
|
|
||||||
$redis->rename($_POST['old'], $_POST['key']);
|
|
||||||
|
|
||||||
|
|
||||||
// Refresh the top so the key tree is updated.
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<script>
|
|
||||||
top.location.href = top.location.pathname+'?view&s=<?php echo $server['id']?>&key=<?php echo urlencode($_POST['key'])?>';
|
|
||||||
</script>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Edit Name of <?php echo format_html($_GET['key'])?></h2>
|
|
||||||
<form action="<?php echo format_html($_SERVER['REQUEST_URI'])?>" method="post">
|
|
||||||
|
|
||||||
<input type="hidden" name="old" value="<?php echo format_html($_GET['key'])?>">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="key">Key:</label>
|
|
||||||
<input type="text" name="key" id="key" size="30" <?php echo isset($_GET['key']) ? 'value="'.format_html($_GET['key']).'"' : ''?>>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="submit" class="button" value="Rename">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Saving</h2>
|
|
||||||
|
|
||||||
...
|
|
||||||
<?php
|
|
||||||
|
|
||||||
// Flush everything so far cause the next command could take some time.
|
|
||||||
flush();
|
|
||||||
|
|
||||||
$redis->save();
|
|
||||||
|
|
||||||
?>
|
|
||||||
done.
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isset($_POST['key'], $_POST['ttl'])) {
|
|
||||||
if ($_POST['ttl'] == -1) {
|
|
||||||
$redis->persist($_POST['key']);
|
|
||||||
} else {
|
|
||||||
$redis->setTimeout($_POST['key'], $_POST['ttl']);
|
|
||||||
}
|
|
||||||
|
|
||||||
header('Location: view.php?key='.urlencode($_POST['key']));
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2>Edit TTL</h2>
|
|
||||||
<form action="<?php echo format_html($_SERVER['REQUEST_URI'])?>" method="post">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="key">Key:</label>
|
|
||||||
<input type="text" name="key" id="key" size="30" <?php echo isset($_GET['key']) ? 'value="'.format_html($_GET['key']).'"' : ''?>>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<label for="ttl"><abbr title="Time To Live">TTL</abbr>:</label>
|
|
||||||
<input type="text" name="ttl" id="ttl" size="30" <?php echo isset($_GET['ttl']) ? 'value="'.format_html($_GET['ttl']).'"' : ''?>> <span class="info">(-1 to remove the TTL)</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<input type="submit" class="button" value="Edit TTL">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
||||||
?>
|
|
|
@ -1,207 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once 'common.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$page['css'][] = 'frame';
|
|
||||||
$page['js'][] = 'frame';
|
|
||||||
|
|
||||||
require 'header.inc.php';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!isset($_GET['key'])) {
|
|
||||||
?>
|
|
||||||
Invalid key
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$type = $redis->type($_GET['key']);
|
|
||||||
$exists = $redis->exists($_GET['key']);
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
<h2><?php echo format_html($_GET['key'])?>
|
|
||||||
<?php if ($exists) { ?>
|
|
||||||
<a href="rename.php?s=<?php echo $server['id']?>&key=<?php echo urlencode($_GET['key'])?>"><img src="images/edit.png" width="16" height="16" title="Rename" alt="[R]"></a>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&key=<?php echo urlencode($_GET['key'])?>" class="delkey"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
<a href="export.php?s=<?php echo $server['id']?>&key=<?php echo urlencode($_GET['key'])?>"><img src="images/export.png" width="16" height="16" title="Export" alt="[E]"></a>
|
|
||||||
<?php } ?>
|
|
||||||
</h2>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if (!$exists) {
|
|
||||||
?>
|
|
||||||
This key does not exist.
|
|
||||||
<?php
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$alt = false;
|
|
||||||
$type = $redistypes[$type];
|
|
||||||
$ttl = $redis->ttl($_GET['key']);
|
|
||||||
$encoding = $redis->object('encoding', $_GET['key']);
|
|
||||||
|
|
||||||
|
|
||||||
switch ($type) {
|
|
||||||
case 'string':
|
|
||||||
$value = $redis->get($_GET['key']);
|
|
||||||
$size = strlen($value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'hash':
|
|
||||||
$values = $redis->hGetAll($_GET['key']);
|
|
||||||
$size = count($values);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'list':
|
|
||||||
$size = $redis->lSize($_GET['key']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'set':
|
|
||||||
$values = $redis->sMembers($_GET['key']);
|
|
||||||
$size = count($values);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'zset':
|
|
||||||
$values = $redis->zRange($_GET['key'], 0, -1);
|
|
||||||
$size = count($values);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
<table>
|
|
||||||
|
|
||||||
<tr><td><div>Type:</div></td><td><div><?php echo format_html($type)?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div><abbr title="Time To Live">TTL</abbr>:</div></td><td><div><?php echo ($ttl == -1) ? 'does not expire' : $ttl?> <a href="ttl.php?s=<?php echo $server['id']?>&key=<?php echo urlencode($_GET['key'])?>&ttl=<?php echo $ttl?>"><img src="images/edit.png" width="16" height="16" title="Edit TTL" alt="[E]" class="imgbut"></a></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Encoding:</div></td><td><div><?php echo format_html($encoding)?></div></td></tr>
|
|
||||||
|
|
||||||
<tr><td><div>Size:</div></td><td><div><?php echo $size?> <?php echo ($type == 'string') ? 'characters' : 'items'?></div></td></tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// String
|
|
||||||
if ($type == 'string') { ?>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr><td><div><?php echo nl2br(format_html($value))?></div></td><td><div>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=string&key=<?php echo urlencode($_GET['key'])?>"><img src="images/edit.png" width="16" height="16" title="Edit" alt="[E]"></a>
|
|
||||||
</div></td><td><div>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&type=string&key=<?php echo urlencode($_GET['key'])?>" class="delval"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
</div></td></tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Hash
|
|
||||||
else if ($type == 'hash') { ?>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr><th><div>Key</div></th><th><div>Value</div></th><th><div> </div></th><th><div> </div></th></tr>
|
|
||||||
|
|
||||||
<?php foreach ($values as $hkey => $value) { ?>
|
|
||||||
<tr <?php echo $alt ? 'class="alt"' : ''?>><td><div><?php echo format_html($hkey)?></div></td><td><div><?php echo nl2br(format_html($value))?></div></td><td><div>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=hash&key=<?php echo urlencode($_GET['key'])?>&hkey=<?php echo urlencode($hkey)?>"><img src="images/edit.png" width="16" height="16" title="Edit" alt="[E]"></a>
|
|
||||||
</div></td><td><div>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&type=hash&key=<?php echo urlencode($_GET['key'])?>&hkey=<?php echo urlencode($hkey)?>" class="delval"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
</div></td></tr>
|
|
||||||
<?php $alt = !$alt; } ?>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// List
|
|
||||||
else if ($type == 'list') { ?>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr><th><div>Index</div></th><th><div>Value</div></th><th><div> </div></th><th><div> </div></th></tr>
|
|
||||||
|
|
||||||
<?php for ($i = 0; $i < $size; ++$i) {
|
|
||||||
$value = $redis->lGet($_GET['key'], $i);
|
|
||||||
?>
|
|
||||||
<tr <?php echo $alt ? 'class="alt"' : ''?>><td><div><?php echo $i?></div></td><td><div><?php echo nl2br(format_html($value))?></div></td><td><div>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=list&key=<?php echo urlencode($_GET['key'])?>&index=<?php echo $i?>"><img src="images/edit.png" width="16" height="16" title="Edit" alt="[E]"></a>
|
|
||||||
</div></td><td><div>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&type=list&key=<?php echo urlencode($_GET['key'])?>&index=<?php echo $i?>" class="delval"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
</div></td></tr>
|
|
||||||
<?php $alt = !$alt; } ?>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set
|
|
||||||
else if ($type == 'set') {
|
|
||||||
|
|
||||||
?>
|
|
||||||
<table>
|
|
||||||
<tr><th><div>Value</div></th><th><div> </div></th><th><div> </div></th></tr>
|
|
||||||
|
|
||||||
<?php foreach ($values as $value) {
|
|
||||||
$display_value = $redis->exists($value) ? '<a href="view.php?s='.$server['id'].'&key='.urlencode($value).'">'.nl2br(format_html($value)).'</a>' : nl2br(format_html($value));
|
|
||||||
?>
|
|
||||||
<tr <?php echo $alt ? 'class="alt"' : ''?>><td><div><?php echo $display_value ?></div></td><td><div>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=set&key=<?php echo urlencode($_GET['key'])?>&value=<?php echo urlencode($value)?>"><img src="images/edit.png" width="16" height="16" title="Edit" alt="[E]"></a>
|
|
||||||
</div></td><td><div>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&type=set&key=<?php echo urlencode($_GET['key'])?>&value=<?php echo urlencode($value)?>" class="delval"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
</div></td></tr>
|
|
||||||
<?php $alt = !$alt; } ?>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ZSet
|
|
||||||
else if ($type == 'zset') { ?>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr><th><div>Score</div></th><th><div>Value</div></th><th><div> </div></th><th><div> </div></th></tr>
|
|
||||||
|
|
||||||
<?php foreach ($values as $value) {
|
|
||||||
$score = $redis->zScore($_GET['key'], $value);
|
|
||||||
$display_value = $redis->exists($value) ? '<a href="view.php?s='.$server['id'].'&key='.urlencode($value).'">'.nl2br(format_html($value)).'</a>' : nl2br(format_html($value));
|
|
||||||
?>
|
|
||||||
<tr <?php echo $alt ? 'class="alt"' : ''?>><td><div><?php echo $score?></div></td><td><div><?php echo $display_value ?></div></td><td><div>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=zset&key=<?php echo urlencode($_GET['key'])?>&score=<?php echo $score?>&value=<?php echo urlencode($value)?>"><img src="images/edit.png" width="16" height="16" title="Edit" alt="[E]"></a>
|
|
||||||
<a href="delete.php?s=<?php echo $server['id']?>&type=zset&key=<?php echo urlencode($_GET['key'])?>&value=<?php echo urlencode($value)?>" class="delval"><img src="images/delete.png" width="16" height="16" title="Delete" alt="[X]"></a>
|
|
||||||
</div></td></tr>
|
|
||||||
<?php $alt = !$alt; } ?>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ($type != 'string') { ?>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="edit.php?s=<?php echo $server['id']?>&type=<?php echo $type?>&key=<?php echo urlencode($_GET['key'])?>" class="add">Add another value</a>
|
|
||||||
</p>
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
|
|
||||||
require 'footer.inc.php';
|
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 2.8 KiB |
|
@ -74,7 +74,7 @@ body, th, td, font {
|
||||||
#body_container { background: #E3E3E3; padding: 0 2px 4px; }
|
#body_container { background: #E3E3E3; padding: 0 2px 4px; }
|
||||||
#page_container {
|
#page_container {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: #FFFFFF; border: 1px solid #D1D7DC;
|
background: #FFFFFF; border: 1px solid #CFD4D8;
|
||||||
}
|
}
|
||||||
#page_header {
|
#page_header {
|
||||||
position: relative; width: 100%;
|
position: relative; width: 100%;
|
||||||
|
@ -114,11 +114,11 @@ wbr { display: inline-block; }
|
||||||
/* ---------------------------------- *
|
/* ---------------------------------- *
|
||||||
Links
|
Links
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
:link:focus, :visited:focus { color: #DD6900; }
|
:link:focus, :visited:focus { color: #444; }
|
||||||
:link { color: #006699; text-decoration: none !important; }
|
:link { color: #222; text-decoration: none !important; }
|
||||||
:visited { color: #006699; text-decoration: none !important; }
|
:visited { color: #222; text-decoration: none !important; }
|
||||||
:link:hover, :visited:hover { color: #DD6900; text-decoration: underline !important; }
|
:link:hover, :visited:hover { color: #444; text-decoration: underline !important; }
|
||||||
:link:active, :visited:active { color: #DD6900; text-decoration: underline !important; }
|
:link:active, :visited:active { color: #444; text-decoration: underline !important; }
|
||||||
|
|
||||||
.colorAdmin, a.colorAdmin, a.colorAdmin:visited { color: #A00 !important; }
|
.colorAdmin, a.colorAdmin, a.colorAdmin:visited { color: #A00 !important; }
|
||||||
.colorSuperMod, a.colorSuperMod, a.colorSuperMod:visited { color: #0080FF !important; }
|
.colorSuperMod, a.colorSuperMod, a.colorSuperMod:visited { color: #0080FF !important; }
|
||||||
|
@ -164,14 +164,14 @@ a.seed:visited, a.seedmed:visited, a.seedsmall:visited
|
||||||
font-size: 11px; text-decoration: none;
|
font-size: 11px; text-decoration: none;
|
||||||
}
|
}
|
||||||
a.topictitle:visited, a.torTopic:visited, a.tLink:visited {
|
a.topictitle:visited, a.torTopic:visited, a.tLink:visited {
|
||||||
color: #5493B4;
|
color: #444;
|
||||||
}
|
}
|
||||||
/* ---------------------------------- *
|
/* ---------------------------------- *
|
||||||
Backgrounds
|
Backgrounds
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
.row1, .row1 td { background: #EFEFEF; }
|
.row1, .row1 td { background: #eff0f3; }
|
||||||
.row2, .row2 td { background: #DEE3E7; }
|
.row2, .row2 td { background: #e3e8ed; }
|
||||||
.row3, .row3 td { background: #D1D7DC; }
|
.row3, .row3 td { background: #d2d7e2; }
|
||||||
.row4, .row4 td { background: #ECECEC; }
|
.row4, .row4 td { background: #ECECEC; }
|
||||||
.row5, .row5 td { background: #E7E7E7; }
|
.row5, .row5 td { background: #E7E7E7; }
|
||||||
.row6, .row6 td { background: #E9E9E6; }
|
.row6, .row6 td { background: #E9E9E6; }
|
||||||
|
@ -213,7 +213,7 @@ td.small { font-size: 10px !important; }
|
||||||
.gen, .med, .genmed,
|
.gen, .med, .genmed,
|
||||||
.small, .gensmall { color: #000000; }
|
.small, .gensmall { color: #000000; }
|
||||||
a.gen, a.med, a.genmed,
|
a.gen, a.med, a.genmed,
|
||||||
a.small, a.gensmall { color: #006699; text-decoration: none; }
|
a.small, a.gensmall { color: #222; text-decoration: none; }
|
||||||
/* ---------------------------------- *
|
/* ---------------------------------- *
|
||||||
Post elements
|
Post elements
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
|
@ -253,7 +253,7 @@ a.small, a.gensmall { color: #006699; text-decoration: none; }
|
||||||
/* ---------------------------------- *
|
/* ---------------------------------- *
|
||||||
Spoiler
|
Spoiler
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
.sp-wrap { padding: 0; background: #E9E9E6; }
|
.sp-wrap { padding: 0; background: #EDEDED; }
|
||||||
.sp-head { border-width: 0; font-size: 11px; padding: 1px 14px 3px; margin-left: 6px; line-height: 15px; font-weight: bold; color: #2A2A2A; cursor: pointer; }
|
.sp-head { border-width: 0; font-size: 11px; padding: 1px 14px 3px; margin-left: 6px; line-height: 15px; font-weight: bold; color: #2A2A2A; cursor: pointer; }
|
||||||
.sp-body { border-width: 1px 0 0 0; display: none; font-weight: normal; background: #F5F5F5; border-bottom: 1px solid #C3CBD1;}
|
.sp-body { border-width: 1px 0 0 0; display: none; font-weight: normal; background: #F5F5F5; border-bottom: 1px solid #C3CBD1;}
|
||||||
.sp-fold { width: 98%; margin: 0 auto; text-align: right; font-size: 10px; color: #444444; }
|
.sp-fold { width: 98%; margin: 0 auto; text-align: right; font-size: 10px; color: #444444; }
|
||||||
|
@ -311,12 +311,12 @@ input.mainoption, input.main {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The buttons used for bbCode styling in message post */
|
/* The buttons used for bbCode styling in message post */
|
||||||
input.button, .buttons input { border: 1px solid; background: #F5F5F5; }
|
input.button, .buttons input { border:1px dotted; background: #F6F6FF; }
|
||||||
input.long { padding-left: 20px; padding-right: 20px; }
|
input.long { padding-left: 20px; padding-right: 20px; }
|
||||||
|
.buttons input:hover {border:1px solid #DEDEDE; background:#FFF;}
|
||||||
input.button, .buttons input,
|
input.button, .buttons input,
|
||||||
input.mainoption, input.main, input.liteoption, input.lite {
|
input.mainoption, input.main, input.liteoption, input.lite {
|
||||||
color: #000000; border-color: #B4B4B4 #000000 #000000 #B4B4B4;
|
color: #000000; border-color: #ABABAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "gte IE 7" in page_header.tpl */
|
/* "gte IE 7" in page_header.tpl */
|
||||||
|
@ -406,7 +406,7 @@ table.forumline {
|
||||||
.forumline th, .thHead {
|
.forumline th, .thHead {
|
||||||
padding: 6px 8px 7px; text-align: center;
|
padding: 6px 8px 7px; text-align: center;
|
||||||
color: #D5E4EC; font-size: 11px; font-weight: bold;
|
color: #D5E4EC; font-size: 11px; font-weight: bold;
|
||||||
background: #006699 url(../images/cellpic3.gif) repeat-x;
|
background: #1C508C url(../images/cellpic1.gif) repeat-x;
|
||||||
}
|
}
|
||||||
/* "lte IE 6" in page_header.tpl */
|
/* "lte IE 6" in page_header.tpl */
|
||||||
.forumline th:first-child { border-left-color: #92A3A4; }
|
.forumline th:first-child { border-left-color: #92A3A4; }
|
||||||
|
@ -427,7 +427,7 @@ table.message td {
|
||||||
|
|
||||||
.cat, td.cat, td.catTitle, td.catHead, td.catBottom {
|
.cat, td.cat, td.catTitle, td.catHead, td.catBottom {
|
||||||
padding: 5px 4px 6px;
|
padding: 5px 4px 6px;
|
||||||
background: #E0E5E9 url(../images/cellpic1.gif) repeat-x;
|
background: #E0E5E9 url(../images/cellpic.gif) repeat-x;
|
||||||
}
|
}
|
||||||
.catTitle {
|
.catTitle {
|
||||||
font-weight: bold; letter-spacing: 1px;
|
font-weight: bold; letter-spacing: 1px;
|
||||||
|
@ -482,7 +482,7 @@ table.smilies td { padding: 3px; text-align: center; }
|
||||||
TopMenu, Quick Login, PM Info, Loguot..
|
TopMenu, Quick Login, PM Info, Loguot..
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
.topmenu {
|
.topmenu {
|
||||||
background: #EFEFEF; border: 1px solid #CFD4D8;
|
background: #eff0f3; border: 1px solid #CFD4D8;
|
||||||
margin: 3px 4px 0; padding: 0 3px; overflow: hidden;
|
margin: 3px 4px 0; padding: 0 3px; overflow: hidden;
|
||||||
}
|
}
|
||||||
.topmenu a:link, .topmenu a:visited { text-decoration: none; }
|
.topmenu a:link, .topmenu a:visited { text-decoration: none; }
|
||||||
|
@ -509,11 +509,11 @@ table.smilies td { padding: 3px; text-align: center; }
|
||||||
Main navigation
|
Main navigation
|
||||||
* ---------------------------------- */
|
* ---------------------------------- */
|
||||||
#main-nav {
|
#main-nav {
|
||||||
padding: 2px 10px; margin: 0 4px;
|
padding: 4px 10px; margin: 0px;
|
||||||
border: solid #CFD4D8; border-width: 1px 0; background: #CFD4D8;
|
border: solid #C3CBD1 /*#CFD4D8*/; border-width: 0 0 1px 0px; background: #eff0f3 url('../images/cellpic.gif');
|
||||||
}
|
}
|
||||||
#main-nav b { padding: 0 4px 0 1px; }
|
#main-nav b { padding: 0 4px 0 1px; }
|
||||||
#main-nav a { color: #535F62; text-decoration: none; }
|
#main-nav a { color: #444; text-decoration: none; }
|
||||||
#main-nav a:hover, #main-nav a:active {
|
#main-nav a:hover, #main-nav a:active {
|
||||||
text-decoration: none !important; color: #000000;
|
text-decoration: none !important; color: #000000;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,7 @@ table.smilies td { padding: 3px; text-align: center; }
|
||||||
#forums_wrap { clear: both; padding-top: 1px; }
|
#forums_wrap { clear: both; padding-top: 1px; }
|
||||||
.cat_title { /* Category header */
|
.cat_title { /* Category header */
|
||||||
padding: 3px 8px 5px; letter-spacing: 1px; text-indent: 0.6em;
|
padding: 3px 8px 5px; letter-spacing: 1px; text-indent: 0.6em;
|
||||||
background: #DEE3E7 url(../images/cellpic1.gif) repeat-x;
|
background: #DEE3E7 url(../images/cellpic.gif) repeat-x;
|
||||||
}
|
}
|
||||||
.cat_title a { text-decoration: none; color: #333333 !important; }
|
.cat_title a { text-decoration: none; color: #333333 !important; }
|
||||||
table.forums { width: 100%; }
|
table.forums { width: 100%; }
|
||||||
|
@ -622,7 +622,7 @@ table.forums { width: 100%; }
|
||||||
}
|
}
|
||||||
.subforums em { display: none; }
|
.subforums em { display: none; }
|
||||||
.subforums + .moderators { margin-top: 0; }
|
.subforums + .moderators { margin-top: 0; }
|
||||||
.dot-sf { color: #417998 !important; font-size: 11px; margin-right: 4px; }
|
.dot-sf { color: #444 !important; font-size: 11px; margin-right: 4px; }
|
||||||
.new .dot-sf { color: #CA4200 !important; }
|
.new .dot-sf { color: #CA4200 !important; }
|
||||||
.sf_title { white-space: normal; }
|
.sf_title { white-space: normal; }
|
||||||
.sf_icon { margin-right: 1px; }
|
.sf_icon { margin-right: 1px; }
|
||||||
|
@ -866,7 +866,7 @@ a.menu-root, a.menu-root:visited, a.menu-root:hover {
|
||||||
text-decoration: none !important; }
|
text-decoration: none !important; }
|
||||||
.menu-sub { position: absolute; display: none; z-index: 1000; }
|
.menu-sub { position: absolute; display: none; z-index: 1000; }
|
||||||
.menu-sub table { background: #FFFFFF; border: 1px solid #92A3A4; }
|
.menu-sub table { background: #FFFFFF; border: 1px solid #92A3A4; }
|
||||||
.menu-sub table th { background: #71869F; color: #F0F8FF; font-weight: bold; font-size: 11px; }
|
.menu-sub table th { background: #566C98; color: #F0F8FF; font-weight: bold; font-size: 11px; }
|
||||||
.menu-sub table td { background: #E7E7E7; font-size: 11px; }
|
.menu-sub table td { background: #E7E7E7; font-size: 11px; }
|
||||||
.menu-sub table td.cat { background: #B5BEC3; }
|
.menu-sub table td.cat { background: #B5BEC3; }
|
||||||
.menu-sub legend { font-weight: bold; }
|
.menu-sub legend { font-weight: bold; }
|
||||||
|
@ -877,8 +877,8 @@ a.menu-root, a.menu-root:visited, a.menu-root:hover {
|
||||||
display/**/: block;
|
display/**/: block;
|
||||||
position: absolute; z-index: -1; filter: mask(); }
|
position: absolute; z-index: -1; filter: mask(); }
|
||||||
.menu-a { background: #FFFFFF; border: 1px solid #92A3A4; }
|
.menu-a { background: #FFFFFF; border: 1px solid #92A3A4; }
|
||||||
.menu-a a { color: #0000A0; background: #E7E7E7; padding: 4px 10px 5px; margin: 1px; display: block; text-decoration: none !important; }
|
.menu-a a { color: #222; background: #E7E7E7; padding: 4px 10px 5px; margin: 1px; display: block; text-decoration: none !important; }
|
||||||
.menu-a a:hover { color: #0000FF; background: #D1D7DC; text-decoration: none !important; }
|
.menu-a a:hover { color: #444; background: #EFEFEF; text-decoration: none !important; }
|
||||||
/* ================================================================ *
|
/* ================================================================ *
|
||||||
Ajax
|
Ajax
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
Before Width: | Height: | Size: 722 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 989 B |
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 1,001 B |
Before Width: | Height: | Size: 663 B After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 1.2 KiB |