Merge branch 'storageareas' of http://github.com/connortechnology/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2017-10-24 16:10:20 -07:00
commit fdbbc5101e
9 changed files with 159 additions and 16 deletions

View File

@ -403,7 +403,7 @@ CREATE TABLE `Monitors` (
`SectionLength` int(10) unsigned NOT NULL default '600',
`FrameSkip` smallint(5) unsigned NOT NULL default '0',
`MotionFrameSkip` smallint(5) unsigned NOT NULL default '0',
`AnalysisFPS` decimal(5,2) default NULL,
`AnalysisFPSLimit` decimal(5,2) default NULL,
`AnalysisUpdateDelay` smallint(5) unsigned NOT NULL default '0',
`MaxFPS` decimal(5,2) default NULL,
`AlarmMaxFPS` decimal(5,2) default NULL,
@ -426,6 +426,9 @@ CREATE TABLE `Monitors` (
`WebColour` varchar(32) NOT NULL default 'red',
`Exif` tinyint(1) unsigned NOT NULL default '0',
`Sequence` smallint(5) unsigned default NULL,
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
`zmcFPS` DECIMAL(5,2) NOT NULL default 0,
`zmaFPS` DECIMAL(5,2) NOT NULL default 0,
PRIMARY KEY (`Id`)
) ENGINE=@ZM_MYSQL_ENGINE@;

122
db/zm_update-1.31.10.sql Normal file
View File

@ -0,0 +1,122 @@
--
-- Add Type column to Storage
--
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'Status'
) > 0,
"SELECT 'Column Status already exists in Servers'",
"ALTER TABLE Servers ADD `Status` enum('Unknown','NotRunning','Running') NOT NULL default 'Unknown' AFTER `State_Id`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'CpuLoad'
) > 0,
"SELECT 'Column CpuLoad already exists in Servers'",
"ALTER TABLE Servers ADD `CpuLoad` DECIMAL(5,1) default NULL AFTER `Status`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'TotalMem'
) > 0,
"SELECT 'Column TotalMem already exists in Servers'",
"ALTER TABLE Servers ADD `TotalMem` bigint unsigned default null AFTER `CpuLoad`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'FreeMem'
) > 0,
"SELECT 'Column FreeMem already exists in Servers'",
"ALTER TABLE Servers ADD `FreeMem` bigint unsigned default null AFTER `TotalMem`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'TotalSwap'
) > 0,
"SELECT 'Column TotalSwap already exists in Servers'",
"ALTER TABLE Servers ADD `TotalSwap` bigint unsigned default null AFTER `FreeMem`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Servers'
AND column_name = 'FreeSwap'
) > 0,
"SELECT 'Column FreeSwap already exists in Servers'",
"ALTER TABLE Servers ADD `FreeSwap` bigint unsigned default null AFTER `TotalSwap`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Status'
) > 0,
"SELECT 'Column Status already exists in Monitors'",
"ALTER TABLE Monitors ADD `Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown' AFTER `Sequence`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'CaptureFPS'
) > 0,
"SELECT 'Column CaptureFPS already exists in Monitors'",
"ALTER TABLE Monitors ADD `CaptureFPS` DECIMAL(10,2) NOT NULL default 0 AFTER `Status`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'AnalysisFPSLimit'
) > 0,
"SELECT 'Column AnalysisFPSLimit already exists in Monitors'",
"ALTER TABLE Monitors CHANGE COLUMN `AnalysisFPS` `AnalysisFPSLimit` DECIMAL(5,2) default NULL"
));
PREPARE stmt FROM @s;
EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'AnalysisFPS'
) > 0,
"SELECT 'Column AnalysisFPS already exists in Monitors'",
"ALTER TABLE Monitors ADD `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0 AFTER `CaptureFPS`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -60,7 +60,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libsoap-wsdl-perl
,libio-socket-multicast-perl
,libdigest-sha-perl
,libsys-cpu-perl, libsys-meminfo-perl
,libsys-cpu-perl, libsys-cpuload-perl, libsys-meminfo-perl
,libdata-uuid-perl
,mysql-client | virtual-mysql-client
,perl-modules

View File

@ -70,6 +70,7 @@ use Socket;
use IO::Handle;
use Time::HiRes qw(usleep);
use Sys::MemInfo qw(totalmem freemem totalswap freeswap);
use Sys::CpuLoad;
use autouse 'Pod::Usage'=>qw(pod2usage);
#use Data::Dumper;
@ -230,6 +231,7 @@ use Socket;
use IO::Handle;
use Time::HiRes qw(usleep);
use Sys::MemInfo qw(totalmem freemem totalswap freeswap);
use Sys::CpuLoad;
#use Data::Dumper;
use constant KILL_DELAY => 100*1000; # 1/10th of a second
@ -263,13 +265,11 @@ sub run {
dPrint( ZoneMinder::Logger::INFO, 'Socket should be open at ' .main::SOCK_FILE );
my $dbh = zmDbConnect(1);
dPrint( ZoneMinder::Logger::INFO, 'Connected to db' );
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
unlink( main::SOCK_FILE ) or Error( 'Unable to unlink ' . main::SOCK_FILE .". Error message was: $!" ) if -e main::SOCK_FILE;
bind( SERVER, $saddr ) or Fatal( "Can't bind to " . main::SOCK_FILE . ": $!" );
listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" );
$SIG{CHLD} = \&reaper;
$SIG{INT} = \&shutdownAll;
$SIG{TERM} = \&shutdownAll;
@ -284,11 +284,10 @@ sub run {
while( 1 ) {
if ( $Config{ZM_SERVER_ID} ) {
$dbh = zmDbConnect() if ! $dbh->ping();
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
'Running', &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
my @cpuload = Sys::CpuLoad::load();
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef,
'Running', $cpuload[0], &totalmem, &freemem, &totalswap, &freeswap, $Config{ZM_SERVER_ID} ) ) {
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
} else {
Debug("Updated status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
}
}
my $nfound = select( my $rout = $rin, undef, undef, $timeout );

View File

@ -1180,6 +1180,11 @@ bool Monitor::Analyse() {
if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) {
fps = double(fps_report_interval)/(now.tv_sec-last_fps_time);
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "UPDATE Monitors SET AnalysisFPS = '%.2lf' WHERE Id = '%d'", fps, id );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
}
last_fps_time = now.tv_sec;
}
@ -1678,7 +1683,7 @@ void Monitor::Reload() {
static char sql[ZM_SQL_MED_BUFSIZ];
// This seems to have fallen out of date.
snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
@ -1843,7 +1848,7 @@ void Monitor::ReloadLinkedMonitors( const char *p_linked_monitors ) {
#if ZM_HAS_V4L
int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'";
;
if ( device[0] ) {
sql += " AND Device='";
@ -2032,7 +2037,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
#endif // ZM_HAS_V4L
int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'";
if ( staticConfig.SERVER_ID ) {
sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
}
@ -2215,7 +2220,7 @@ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const c
}
int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'";
if ( file[0] ) {
sql += " AND Path='";
sql += file;
@ -2365,7 +2370,7 @@ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose pu
#if HAVE_LIBAVFORMAT
int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'";
if ( file[0] ) {
sql += " AND Path = '";
sql += file;
@ -2525,7 +2530,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
#endif // HAVE_LIBAVFORMAT
Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) {
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id );
zmDbRow dbrow;
if ( ! dbrow.fetch( sql.c_str() ) ) {
@ -2981,6 +2986,11 @@ int Monitor::Capture() {
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
Info( "%s: %d - Capturing at %.2lf fps", name, image_count, fps );
last_fps_time = now;
static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "UPDATE Monitors SET CaptureFPS = '%.2lf' WHERE Id = '%d'", fps, id );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
}
}
// Icon: I'm not sure these should be here. They have nothing to do with capturing

View File

@ -221,6 +221,13 @@ int main(int argc, char *argv[]) {
}
Info("Starting Capture version %s", ZM_VERSION);
static char sql[ZM_SQL_SML_BUFSIZ];
for ( int i = 0; i < n_monitors; i ++ ) {
snprintf( sql, sizeof(sql), "UPDATE Monitors SET Status = 'Running' WHERE Id = '%d'", monitors[i]->Id() );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
}
}
zmSetDefaultTermHandler();
zmSetDefaultDieHandler();

View File

@ -1 +1 @@
1.31.9
1.31.10

View File

@ -41,7 +41,7 @@ var popupSizes = {
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 200 },
'frames': { 'width': 600, 'height': 700 },
'function': { 'width': 400, 'height': 250 },
'group': { 'width': 360, 'height': 320 },
'group': { 'width': 660, 'height': 520 },
'groups': { 'width': 440, 'height': 220 },
'image': { 'addWidth': 48, 'addHeight': 80 },
'log': { 'width': 1080, 'height': 720 },

View File

@ -205,6 +205,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
<th class="colName"><?php echo translate('Name') ?></th>
<th class="colHostname"><?php echo translate('Hostname') ?></th>
<th class="colStatus"><?php echo translate('Status') ?></th>
<th class="colCpuLoad"><?php echo translate('CpuLoad') ?></th>
<th class="colMemory"><?php echo translate('Free').'/'.translate('Total') . ' ' . translate('Memory') ?></th>
<th class="colSwap"><?php echo translate('Free').'/'.translate('Total') . ' ' . translate('Swap') ?></th>
<th class="colMark"><?php echo translate('Mark') ?></th>
@ -216,6 +217,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
<td class="colName"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Name']), $canEdit ) ?></td>
<td class="colHostname"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Hostname']), $canEdit ) ?></td>
<td class="colStatus"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server', validHtmlStr($row['Status']), $canEdit ) ?></td>
<td class="colCpuLoad"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server',$row['CpuLoad'], $canEdit ) ?></td>
<td class="colMemory"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server', human_filesize($row['FreeMem']) . ' / ' . human_filesize($row['TotalMem']), $canEdit ) ?></td>
<td class="colSwap"><?php echo makePopupLink( '?view=server&amp;id='.$row['Id'], 'zmServer', 'server', human_filesize($row['FreeSwap']) . ' / ' . human_filesize($row['TotalSwap']) , $canEdit ) ?></td>