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

pull/2090/head^2
Isaac Connor 2018-04-30 10:12:41 -04:00
commit 2845f891bc
11 changed files with 128 additions and 57 deletions

View File

@ -529,6 +529,8 @@ sub MoveTo {
my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint
if ( ! $$NewStorage{Id} ) { if ( ! $$NewStorage{Id} ) {
return "New storage does not have an id. Moving will not happen."; return "New storage does not have an id. Moving will not happen.";
} elsif ( $$NewStorage{Id} == $$self{StorageId} ) {
return "Event is already located at " . $NewPath;
} elsif ( !$NewPath ) { } elsif ( !$NewPath ) {
return "New path ($NewPath) is empty."; return "New path ($NewPath) is empty.";
} elsif ( ! -e $NewPath ) { } elsif ( ! -e $NewPath ) {

View File

@ -161,9 +161,9 @@ sub Sql {
my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/; my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/;
$self->{Sql} .= 'M.'.$temp_attr_name; $self->{Sql} .= 'M.'.$temp_attr_name;
} elsif ( $term->{attr} eq 'ServerId' or $term->{attr} eq 'MonitorServerId' ) { } elsif ( $term->{attr} eq 'ServerId' or $term->{attr} eq 'MonitorServerId' ) {
$self->{Sql} .= 'M.'.$term->{attr}; $self->{Sql} .= 'M.ServerId';
} elsif ( $term->{attr} eq 'StorageServerId' ) { } elsif ( $term->{attr} eq 'StorageServerId' ) {
$self->{Sql} .= 'S.'.$term->{attr}; $self->{Sql} .= 'S.ServerId';
} elsif ( $term->{attr} eq 'FilterServerId' ) { } elsif ( $term->{attr} eq 'FilterServerId' ) {
$self->{Sql} .= $Config{ZM_SERVER_ID}; $self->{Sql} .= $Config{ZM_SERVER_ID};
# StartTime options # StartTime options

View File

@ -158,6 +158,7 @@ sub new {
( $this->{fileName} = $0 ) =~ s|^.*/||; ( $this->{fileName} = $0 ) =~ s|^.*/||;
$this->{logPath} = $Config{ZM_PATH_LOGS}; $this->{logPath} = $Config{ZM_PATH_LOGS};
$this->{logFile} = $this->{logPath}.'/'.$this->{id}.'.log'; $this->{logFile} = $this->{logPath}.'/'.$this->{id}.'.log';
($this->{logFile}) = $this->{logFile} =~ /^([\w\.\/]+)$/;
$this->{trace} = 0; $this->{trace} = 0;
@ -207,6 +208,7 @@ sub initialise( @ ) {
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) { if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) {
$tempLogFile = $logFile; $tempLogFile = $logFile;
} }
($tempLogFile) = $tempLogFile =~ /^([\w\.\/]+)$/;
my $tempLevel = INFO; my $tempLevel = INFO;
my $tempTermLevel = $this->{termLevel}; my $tempTermLevel = $this->{termLevel};
@ -582,24 +584,29 @@ sub logPrint {
} }
print($LOGFILE $message) if $level <= $this->{fileLevel}; print($LOGFILE $message) if $level <= $this->{fileLevel};
if ( $level <= $this->{databaseLevel} ) { if ( $level <= $this->{databaseLevel} ) {
my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )'; if ( ( $this->{dbh} and $this->{dbh}->ping() ) or ( $this->{dbh} = zmDbConnect() ) ) {
$this->{sth} = $this->{dbh}->prepare_cached($sql);
if ( !$this->{sth} ) { my $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL )';
$this->{databaseLevel} = NOLOG; $this->{sth} = $this->{dbh}->prepare_cached($sql);
Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr()); if ( !$this->{sth} ) {
} else {
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
, $this->{id}
, $$
, $level
, $code
, $string
, $this->{fileName}
);
if ( !$res ) {
$this->{databaseLevel} = NOLOG; $this->{databaseLevel} = NOLOG;
Error("Can't execute log entry '$sql': ".$this->{sth}->errstr()); Error("Can't prepare log entry '$sql': ".$this->{dbh}->errstr());
} else {
my $res = $this->{sth}->execute($seconds+($microseconds/1000000.0)
, $this->{id}
, $$
, $level
, $code
, $string
, $this->{fileName}
);
if ( !$res ) {
$this->{databaseLevel} = NOLOG;
Error("Can't execute log entry '$sql': ".$this->{dbh}->errstr());
}
} }
} else {
print(STDERR "Can't log to database: ");
} }
} # end if doing db logging } # end if doing db logging
print(STDERR $message) if $level <= $this->{termLevel}; print(STDERR $message) if $level <= $this->{termLevel};

View File

@ -242,6 +242,7 @@ use constant KILL_DELAY => 60; # seconds to wait between sending TERM and sendin
our %cmd_hash; our %cmd_hash;
our %pid_hash; our %pid_hash;
our %terminating_processes; our %terminating_processes;
our $zm_terminate = 0;
sub run { sub run {
my $fd = 0; my $fd = 0;
@ -276,9 +277,9 @@ sub run {
listen(SERVER, SOMAXCONN) or Fatal("Can't listen: $!"); listen(SERVER, SOMAXCONN) or Fatal("Can't listen: $!");
$SIG{CHLD} = \&reaper; $SIG{CHLD} = \&reaper;
$SIG{INT} = \&shutdownAll; $SIG{INT} = \&shutdown_sig_handler;
$SIG{TERM} = \&shutdownAll; $SIG{TERM} = \&shutdown_sig_handler;
$SIG{ABRT} = \&shutdownAll; $SIG{ABRT} = \&shutdown_sig_handler;
$SIG{HUP} = \&logrot; $SIG{HUP} = \&logrot;
my $rin = ''; my $rin = '';
@ -295,12 +296,18 @@ sub run {
dPrint(ZoneMinder::Logger::INFO, 'Loading Server record have ' . $$Server{Name}); dPrint(ZoneMinder::Logger::INFO, 'Loading Server record have ' . $$Server{Name});
} }
while( 1 ) { while( !$zm_terminate ) {
if ( $Config{ZM_SERVER_ID} ) { if ( $Config{ZM_SERVER_ID} ) {
if ( ! ( $secs_count % 60 ) ) { if ( ! ( $secs_count % 60 ) ) {
$dbh = zmDbConnect() if ! $dbh->ping(); Debug("Connecting");
while ( !$zm_terminate and ! ($dbh and $dbh->ping()) ) {
Warning("Not connected to db. Reconnecting");
$dbh = zmDbConnect();
Debug("Conneted? : $dbh");
}
my @cpuload = CpuLoad(); my @cpuload = CpuLoad();
Debug("UPdating Server record @cpuload");
if ( ! defined $dbh->do(q{UPDATE Servers SET Status=?,CpuLoad=?,TotalMem=?,FreeMem=?,TotalSwap=?,FreeSwap=? WHERE Id=?}, undef, 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} ) ) { '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()); Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
@ -308,7 +315,9 @@ sub run {
} }
$secs_count += 1; $secs_count += 1;
} }
Debug("Before select");
my $nfound = select(my $rout = $rin, undef, undef, $timeout); my $nfound = select(my $rout = $rin, undef, undef, $timeout);
Debug("Aftere select $nfound");
if ( $nfound > 0 ) { if ( $nfound > 0 ) {
if ( vec($rout, fileno(SERVER), 1) ) { if ( vec($rout, fileno(SERVER), 1) ) {
my $paddr = accept(CLIENT, SERVER); my $paddr = accept(CLIENT, SERVER);
@ -330,7 +339,8 @@ sub run {
# Do nothing, this is all we're here for # Do nothing, this is all we're here for
dPrint(ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n"); dPrint(ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n");
} elsif ( $command eq 'shutdown' ) { } elsif ( $command eq 'shutdown' ) {
shutdownAll(); # Breka out of while loop
last;
} elsif ( $command eq 'check' ) { } elsif ( $command eq 'check' ) {
check($daemon, @args); check($daemon, @args);
} elsif ( $command eq 'status' ) { } elsif ( $command eq 'status' ) {
@ -362,7 +372,9 @@ sub run {
#print( "Select timed out\n" ); #print( "Select timed out\n" );
} }
Debug("restartPending");
restartPending(); restartPending();
Debug("check_for_processes_to_kill");
check_for_processes_to_kill(); check_for_processes_to_kill();
} # end while } # end while
@ -377,9 +389,7 @@ sub run {
Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr()); Error("Failed Updating status of Server record for Id=$Config{ZM_SERVER_ID}".$dbh->errstr());
} }
} }
unlink(main::SOCK_FILE) or Error('Unable to unlink ' . main::SOCK_FILE .". Error message was: $!") if ( -e main::SOCK_FILE ); shutdownAll();
unlink(ZM_PID) or Error('Unable to unlink ' . ZM_PID .". Error message was: $!") if ( -e ZM_PID );
exit();
} }
sub cPrint { sub cPrint {
@ -426,10 +436,12 @@ sub start {
} }
my $sigset = POSIX::SigSet->new; my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new( SIGCHLD ); my $blockset = POSIX::SigSet->new(SIGCHLD);
Debug("Blocking SIGCHLD");
sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!"); sigprocmask(SIG_BLOCK, $blockset, $sigset) or Fatal("Can't block SIGCHLD: $!");
Debug("forking");
if ( my $cpid = fork() ) { if ( my $cpid = fork() ) {
logReinit(); #logReinit();
$process->{pid} = $cpid; $process->{pid} = $cpid;
$process->{started} = time(); $process->{started} = time();
@ -442,6 +454,7 @@ sub start {
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process; $cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!"); sigprocmask(SIG_SETMASK, $sigset) or Fatal("Can't restore SIGCHLD: $!");
Debug("unblocko child");
} elsif ( defined($cpid) ) { } elsif ( defined($cpid) ) {
# Force reconnection to the db. # Force reconnection to the db.
$dbh = zmDbConnect(1); $dbh = zmDbConnect(1);
@ -527,16 +540,18 @@ sub check_for_processes_to_kill {
my $sigset = POSIX::SigSet->new; my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new(SIGCHLD); my $blockset = POSIX::SigSet->new(SIGCHLD);
sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n"; sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "dying at block...\n";
foreach my $command ( %terminating_processes ) { foreach my $command ( keys %terminating_processes ) {
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
Debug("Have process $command at pid $$process{pid} $$process{term_sent_at}"); my $now = time;
if ( $$process{term_sent_at} and ( $$process{term_sent_at} - time > KILL_DELAY ) ) { Debug("Have process $command at pid $$process{pid} $$process{term_sent_at} - $now = " . ( $$process{term_sent_at} - $now ) );
if ( $$process{term_sent_at} and ( $$process{term_sent_at} - $now > KILL_DELAY ) ) {
dPrint(ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at " dPrint(ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at "
.strftime('%y/%m/%d %H:%M:%S', localtime()) .strftime('%y/%m/%d %H:%M:%S', localtime())
.' after ' . KILL_DELAY . ' seconds.' .' after ' . KILL_DELAY . ' seconds.'
." Sending KILL to pid $$process{pid}\n" ." Sending KILL to pid $$process{pid}\n"
); );
kill('KILL', $$process{pid}); kill('KILL', $$process{pid});
delete $terminating_processes{$command};
} }
} }
sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n"; sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n";
@ -595,8 +610,14 @@ sub logrot {
} }
} }
sub shutdown_sig_handler {
$zm_terminate = 1;
}
sub reaper { sub reaper {
my $saved_status = $!; my $saved_status = $!;
# Wait for a child to terminate
while ( (my $cpid = waitpid(-1, WNOHANG)) > 0 ) { while ( (my $cpid = waitpid(-1, WNOHANG)) > 0 ) {
my $status = $?; my $status = $?;
@ -620,8 +641,8 @@ sub reaper {
my $out_str = "'$process->{command}' "; my $out_str = "'$process->{command}' ";
if ( $exit_signal ) { if ( $exit_signal ) {
# 15 == TERM, 14 == ALARM
if ( $exit_signal == 15 || $exit_signal == 14 ) { if ( $exit_signal == 15 || $exit_signal == 14 ) {
# TERM or ALRM
$out_str .= 'exited'; $out_str .= 'exited';
} else { } else {
$out_str .= 'crashed'; $out_str .= 'crashed';
@ -659,22 +680,26 @@ sub reaper {
$process->{delay} = $Config{ZM_MAX_RESTART_DELAY}; $process->{delay} = $Config{ZM_MAX_RESTART_DELAY};
} }
} }
Debug("Delay for $$process{command} is now $$process{delay}");
} else { } else {
delete $cmd_hash{$$process{command}}; delete $cmd_hash{$$process{command}};
} }
} } # end while waitpid
$SIG{CHLD} = \&reaper; $SIG{CHLD} = \&reaper;
$! = $saved_status; $! = $saved_status;
Debug("Leaving reaper");
} }
sub restartPending { sub restartPending {
# Restart any pending processes # Restart any pending processes, we list them first because cmd_hash may change in foreach
foreach my $process ( values( %cmd_hash ) ) { my @processes = values %cmd_hash;
foreach my $process ( @processes ) {
if ( $process->{pending} && $process->{pending} <= time() ) { if ( $process->{pending} && $process->{pending} <= time() ) {
dPrint(ZoneMinder::Logger::INFO, "Starting pending process, $process->{command}\n"); dPrint(ZoneMinder::Logger::INFO, "Starting pending process, $process->{command}\n");
start($process->{daemon}, @{$process->{args}}); start($process->{daemon}, @{$process->{args}});
} }
} }
dPrint(ZoneMinder::Logger::INFO, "done restartPending");
} }
sub shutdownAll { sub shutdownAll {
@ -683,9 +708,14 @@ sub shutdownAll {
next if ! $pid_hash{$pid}; next if ! $pid_hash{$pid};
send_stop(1, $pid_hash{$pid}); send_stop(1, $pid_hash{$pid});
} }
while ( %terminating_processes ) { my $count= KILL_DELAY;
while ( (keys %terminating_processes) and $count) {
check_for_processes_to_kill(); check_for_processes_to_kill();
sleep(1) if %terminating_processes; if ( %terminating_processes ) {
Debug("Still " . %terminating_processes . ' to die. count is: ' . $count . ' sleeping');
sleep(1);
$count --;
}
} }
dPrint(ZoneMinder::Logger::INFO, "Server shutdown at " dPrint(ZoneMinder::Logger::INFO, "Server shutdown at "
.strftime('%y/%m/%d %H:%M:%S', localtime()) .strftime('%y/%m/%d %H:%M:%S', localtime())

View File

@ -94,7 +94,7 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)
: ($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS}) : ($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS})
; ;
logInit(); logInit($filter_id?(id=>'zmfilter_'.$filter_id.'.log'):());
sub HupHandler { sub HupHandler {
Info("Received HUP, reloading"); Info("Received HUP, reloading");
&ZoneMinder::Logger::logHupHandler(); &ZoneMinder::Logger::logHupHandler();

View File

@ -259,7 +259,7 @@ Event::~Event() {
"UPDATE Events SET Name='%s %" PRIu64 "', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' WHERE Id = %" PRIu64, "UPDATE Events SET Name='%s %" PRIu64 "', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' WHERE Id = %" PRIu64,
monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id ); monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id );
db_mutex.lock(); db_mutex.lock();
while ( mysql_query(&dbconn, sql) ) { while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn)); Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
db_mutex.unlock(); db_mutex.unlock();
sleep(1); sleep(1);
@ -424,16 +424,16 @@ void Event::updateNotes( const StringSetMap &newNoteSetMap ) {
#else #else
static char escapedNotes[ZM_SQL_MED_BUFSIZ]; static char escapedNotes[ZM_SQL_MED_BUFSIZ];
mysql_real_escape_string( &dbconn, escapedNotes, notes.c_str(), notes.length() ); mysql_real_escape_string(&dbconn, escapedNotes, notes.c_str(), notes.length());
snprintf( sql, sizeof(sql), "UPDATE Events SET Notes = '%s' WHERE Id = %" PRIu64, escapedNotes, id ); snprintf(sql, sizeof(sql), "UPDATE Events SET Notes = '%s' WHERE Id = %" PRIu64, escapedNotes, id);
db_mutex.lock(); db_mutex.lock();
if ( mysql_query( &dbconn, sql ) ) { if ( mysql_query(&dbconn, sql) ) {
Error( "Can't insert event: %s", mysql_error( &dbconn ) ); Error("Can't insert event: %s", mysql_error(&dbconn));
} }
db_mutex.unlock(); db_mutex.unlock();
#endif #endif
} } // end if update
} }
void Event::AddFrames( int n_frames, Image **images, struct timeval **timestamps ) { void Event::AddFrames( int n_frames, Image **images, struct timeval **timestamps ) {
@ -487,7 +487,7 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %" PRIu64 ", %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %" PRIu64 ", %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec );
frameCount++; frameCount++;
} } // end foreach frame
if ( frameCount ) { if ( frameCount ) {
Debug( 1, "Adding %d/%d frames to DB", frameCount, n_frames ); Debug( 1, "Adding %d/%d frames to DB", frameCount, n_frames );
@ -545,7 +545,10 @@ Debug(3, "Writing video");
Debug( 1, "Adding frame %d of type \"%s\" to DB", frames, Event::frame_type_names[frame_type] ); Debug( 1, "Adding frame %d of type \"%s\" to DB", frames, Event::frame_type_names[frame_type] );
static char sql[ZM_SQL_MED_BUFSIZ]; static char sql[ZM_SQL_MED_BUFSIZ];
snprintf(sql, sizeof(sql), "INSERT INTO Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score ) values ( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d )", id, frames, frame_type_names[frame_type], timestamp.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score); snprintf(sql, sizeof(sql),
"INSERT INTO Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score )"
" VALUES ( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d )",
id, frames, frame_type_names[frame_type], timestamp.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score);
db_mutex.lock(); db_mutex.lock();
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
Error("Can't insert frame: %s", mysql_error(&dbconn)); Error("Can't insert frame: %s", mysql_error(&dbconn));
@ -558,7 +561,7 @@ Debug(3, "Writing video");
// We are writing a Bulk frame // We are writing a Bulk frame
if ( frame_type == BULK ) { if ( frame_type == BULK ) {
snprintf( sql, sizeof(sql), snprintf(sql, sizeof(sql),
"UPDATE Events SET Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %" PRIu64, "UPDATE Events SET Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %" PRIu64,
( delta_time.positive?"":"-" ), ( delta_time.positive?"":"-" ),
delta_time.sec, delta_time.fsec, delta_time.sec, delta_time.fsec,
@ -570,7 +573,7 @@ Debug(3, "Writing video");
id id
); );
db_mutex.lock(); db_mutex.lock();
while ( mysql_query(&dbconn, sql) ) { while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
Error("Can't update event: %s", mysql_error(&dbconn)); Error("Can't update event: %s", mysql_error(&dbconn));
db_mutex.unlock(); db_mutex.unlock();
sleep(1); sleep(1);

View File

@ -543,7 +543,7 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) ); mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line ); snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line );
if (mysql_query(&dbconn, sql)) { if ( mysql_query(&dbconn, sql) ) {
Level tempDatabaseLevel = mDatabaseLevel; Level tempDatabaseLevel = mDatabaseLevel;
databaseLevel(NOLOG); databaseLevel(NOLOG);
Error("Can't insert log entry: sql(%s) error(%s)", sql, mysql_error(&dbconn)); Error("Can't insert log entry: sql(%s) error(%s)", sql, mysql_error(&dbconn));

View File

@ -1246,9 +1246,9 @@ bool Monitor::Analyse() {
Info("%s: %d - Analysing at %.2f fps", name, image_count, new_fps); Info("%s: %d - Analysing at %.2f fps", name, image_count, new_fps);
if ( fps != new_fps ) { if ( fps != new_fps ) {
fps = new_fps; fps = new_fps;
db_mutex.lock();
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf(sql, sizeof(sql), "INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf", id, fps, fps); snprintf(sql, sizeof(sql), "INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf", id, fps, fps);
db_mutex.lock();
if ( mysql_query(&dbconn, sql) ) { if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn)); Error("Can't run query: %s", mysql_error(&dbconn));
} }

@ -1 +1 @@
Subproject commit c3976f1478c681b0bbc132ec3a3e82c3984eeed5 Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef

View File

@ -451,6 +451,11 @@ class Event {
$values[] = $this->{'Id'}; $values[] = $this->{'Id'};
dbQuery( $sql, $values ); dbQuery( $sql, $values );
} }
public function link_to($text=null) {
if ( !$text )
$text = $this->{'Id'};
return '<a href="?view=event&amp;eid='. $this->{'Id'}.'">'.$text.'</a>';
}
} # end class } # end class

View File

@ -102,6 +102,7 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
if ( count($EventsByMonitor[$event['MonitorId']]['Events']) ) { if ( count($EventsByMonitor[$event['MonitorId']]['Events']) ) {
$last_event = end($EventsByMonitor[$event['MonitorId']]['Events']); $last_event = end($EventsByMonitor[$event['MonitorId']]['Events']);
#Logger::Debug(print_r($last_event,true));
$gap = $last_event->EndTimeSecs() - $event['StartTimeSecs']; $gap = $last_event->EndTimeSecs() - $event['StartTimeSecs'];
if ( $gap < $EventsByMonitor[$event['MonitorId']]['MinGap'] ) if ( $gap < $EventsByMonitor[$event['MonitorId']]['MinGap'] )
@ -140,7 +141,10 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
<tr> <tr>
<th class="colId"><?php echo translate('Id') ?></th> <th class="colId"><?php echo translate('Id') ?></th>
<th class="colName"><i class="material-icons md-18">videocam</i>&nbsp;<?php echo translate('Name') ?></th> <th class="colName"><i class="material-icons md-18">videocam</i>&nbsp;<?php echo translate('Name') ?></th>
<th class="colServer"><?php echo translate('Server') ?></th>
<th class="colEvents"><?php echo translate('Events') ?></th> <th class="colEvents"><?php echo translate('Events') ?></th>
<th class="colFirstEvent"><?php echo translate('FirstEvent') ?></th>
<th class="colLastEvent"><?php echo translate('LastEvent') ?></th>
<th class="colMinGap"><?php echo translate('MinGap') ?></th> <th class="colMinGap"><?php echo translate('MinGap') ?></th>
<th class="colMaxGap"><?php echo translate('MaxGap') ?></th> <th class="colMaxGap"><?php echo translate('MaxGap') ?></th>
<th class="colMissingFiles"><?php echo translate('MissingFiles') ?></th> <th class="colMissingFiles"><?php echo translate('MissingFiles') ?></th>
@ -152,8 +156,25 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
$monitor = $displayMonitors[$monitor_i]; $monitor = $displayMonitors[$monitor_i];
$Monitor = new Monitor($monitor); $Monitor = new Monitor($monitor);
$montagereview_link = "?view=montagereview&live=0&MonitorId=". $monitor['Id'] . '&minTime='.$minTime.'&maxTime='.$maxTime; $montagereview_link = "?view=montagereview&live=0&MonitorId=". $monitor['Id'] . '&minTime='.$minTime.'&maxTime='.$maxTime;
if ( isset($EventsByMonitor[$Monitor->Id()]) ) {
$EventCounts = $EventsByMonitor[$Monitor->Id()];
$MinGap = $EventCounts['MinGap'];
$MaxGap = $EventCounts['MaxGap'];
$FileMissing = $EventCounts['FileMissing'];
$ZeroSize = $EventCounts['ZeroSize'];
$FirstEvent = $EventCounts['Events'][0];
$LastEvent = end($EventCounts['Events']);
} else {
$MinGap = 0;
$MaxGap = 0;
$FileMissing = 0;
$ZeroSize = 0;
$FirstEvent = 0;
$LastEvent = 0;
}
?> ?>
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>"> <tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>" title="<?php echo $monitor['Id'] ?>">
<td class="colId"><a href="<?php echo $montagereview_link ?>"><?php echo $monitor['Id'] ?></a></td> <td class="colId"><a href="<?php echo $montagereview_link ?>"><?php echo $monitor['Id'] ?></a></td>
@ -168,11 +189,14 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
}, $Monitor->GroupIds() ) ); }, $Monitor->GroupIds() ) );
?> ?>
</div></td> </div></td>
<td class="colServer"><?php echo $Monitor->Server()->Name()?></td>
<td class="colEvents"><?php echo isset($EventsByMonitor[$Monitor->Id()])?count($EventsByMonitor[$Monitor->Id()]['Events']):0 ?></td> <td class="colEvents"><?php echo isset($EventsByMonitor[$Monitor->Id()])?count($EventsByMonitor[$Monitor->Id()]['Events']):0 ?></td>
<td class="colMinGap"><?php echo isset($EventsByMonitor[$Monitor->Id()])?$EventsByMonitor[$Monitor->Id()]['MinGap']:0 ?></td> <td class="colFirstEvent"><?php echo $FirstEvent ? $FirstEvent->link_to($FirstEvent->Id().' at ' . $FirstEvent->StartTime()) : 'none'?></td>
<td class="colMaxGap"><?php echo isset($EventsByMonitor[$Monitor->Id()])?$EventsByMonitor[$Monitor->Id()]['MaxGap']:0 ?></td> <td class="colLastEvent"><?php echo $LastEvent ? $LastEvent->link_to($LastEvent->Id().' at ' . $LastEvent->StartTime()) : 'none'?></td>
<td class="colFileMissing"><?php echo isset($EventsByMonitor[$Monitor->Id()])?$EventsByMonitor[$Monitor->Id()]['FileMissing']:0 ?></td> <td class="colMinGap"><?php echo $MinGap ?></td>
<td class="colZeroSize"><?php echo isset($EventsByMonitor[$Monitor->Id()])?$EventsByMonitor[$Monitor->Id()]['ZeroSize']:0 ?></td> <td class="colMaxGap"><?php echo $MaxGap ?></td>
<td class="colFileMissing<?php echo $FileMissing ? ' errorText' : ''?>"><?php echo $FileMissing ?></td>
<td class="colZeroSize<?php echo $ZeroSize ? ' errorText' : ''?>"><?php echo $ZeroSize ?></td>
</tr> </tr>
<?php <?php
} # end for each monitor } # end for each monitor