1 <& /elements/header.html, 'System Status' &>
3 <& /elements/init_overlib.html &>
5 % foreach my $section ( keys %status ) {
6 <FONT CLASS="fsinnerbox-title"><% mt($section) |h %></FONT>
7 <TABLE CLASS="fsinnerbox">
8 % foreach my $item ( @{ $status{$section} } ) {
10 <TD ALIGN="right"><% $item->{title} %></TH>
11 <TD><B><% $item->{value} %></B></TD>
18 <& /elements/footer.html &>
26 -e '/usr/bin/lsb_release' and run( ['lsb_release', '-d'], '>',\$os );
27 if ( ! $@ && $os =~ /^\s*Description:\s*(.+)$/ ) {
29 } elsif ( my $deb_version = slurp('/etc/debian_version') ) {
30 $os = "Debian $deb_version";
34 -e '/usr/bin/dpkg-query'
35 and run( ['/usr/bin/dpkg-query',
36 '--showformat=${Version}', '--show', 'freeside'
41 ( my $perl_ver = $^V ) =~ s/^v//;
44 $db = 'PostgreSQL' if $db =~ /^Pg/;
45 $db = 'MySQL/MariaDB' if $db =~ /^mysql/;
47 my $db_ver = FS::Record->scalar_sql('SELECT VERSION()');
48 if ( $db eq 'PostgreSQL' && $db_ver =~ /^\s*PostgreSQL\s+([\w\.]+(\s+\([\w\s\.\+\-\:\~]+\))?)\s+on\s+/ ) {
52 my $db_size = 'Unknown';
53 if ( $db eq 'PostgreSQL' ) {
54 $db_size = FS::Record->scalar_sql(qq(
55 SELECT pg_size_pretty(pg_database_size('freeside'))
57 include('/elements/popup_link.html',
58 'action' => 'Status-db_size_detail.html',
59 'label' => '(details)',
60 'actionlabel' => 'Database size details',
64 tie my %status, 'Tie::IxHash',
66 { 'title' => 'Freeside version',
67 'value' => $FS::VERSION,
69 ( length($pkg_version)
70 ? ( { 'title' => 'Package version',
71 'value' => $pkg_version,
76 { 'title' => 'Operating System',
79 { 'title' => 'Perl version',
82 { 'title' => 'Database engine',
85 { 'title' => 'Database version',
88 { 'title' => 'Database size',
92 'Required Daemons' => [
93 { 'title' => 'Queue daemon',
94 'value' => _is_running('queued') ? 'Running' : 'Not running',
97 'Optional Daemons' => [
98 { 'title' => 'Self-service server(s)',
99 'value' => '(Not checked)', #XXX multiple pid files, per machine etc
101 { 'title' => 'Self-service XML-RPC server',
102 'value' => _is_running('selfservice-xmlrpcd') ? 'Running' : 'Not running',
104 { 'title' => 'Back office XML-RPC server',
105 'value' => _is_running('xmlrpcd') ? 'Running' : 'Not running',
107 { 'title' => 'RADIUS accounting import daemon',
108 'value' => _is_running('sqlradius-radacctd') ? 'Running' : 'Not running',
110 { 'title' => 'Prepaid daemon',
111 'value' => _is_running('prepaidd') ? 'Running' : 'Not running',
113 { 'title' => 'CDR Rewrite daemon',
114 'value' => _is_running('cdrrewrited') ? 'Running' : 'Not running',
116 { 'title' => 'CDR Prepaid daemon',
117 'value' => _is_running('cdrd') ? 'Running' : 'Not running',
119 { 'title' => 'CDR Real-time rating daemon',
120 'value' => _is_running('cdrrated') ? 'Running' : 'Not running',
122 #{ 'title' => 'Network monitoring port combiner', #?
123 # 'value' => _is_running('torrus-srvderive') ? 'Running' : 'Not running',
133 if ( $db eq 'PostgreSQL' ) {
135 my $enabled = FS::Record->scalar_sql('SHOW wal_level') eq 'hot_standby'
136 && FS::Record->scalar_sql('SHOW archive_mode') eq 'on';
139 FS::Record->scalar_sql('SHOW archive_command') =~ / postgres\@([\w\.\-]+):/
142 $status{'Replication'} = [
143 { 'title' => 'Status', #?
144 'value' => $enabled ? 'Enabled' : 'Disabled',
149 push @{ $status{'Replication'} },
150 { 'title' => 'Slave',
151 'value' => $slave || '(Missing, or unparseable archive_command)',
155 #how far behind is it? will be easier once we're off 9.1
156 # http://www.keithf4.com/monitoring_streaming_slave_lag/
157 # except pg_stat_replication still doesn't fill in the columns we need as
159 #push @{ $status{'Replication'} },
160 # { 'title' => 'Slave',
161 # 'value' => $slave || '(Missing, or unparseable archive_command)',
169 $status{'Replication'} = [
170 { 'title' => 'Enabled',
171 'value' => "(Not yet checked on $db)",
182 if ( _is_running('cdrd') ) {
184 my $delay = FS::Record->scalar_sql('
185 SELECT AVG(end_date-insert_date)
188 ORDER BY statnum DESC
192 my $h = int($delay/3600);
193 my $m = int( ($delay%3600) / 60 );
196 $delay = ( $h ? $h. 'h' : '' ).
197 ( $h||$m ? $m. 'm' : '').
202 my $pr_delay = FS::Record->scalar_sql('
203 SELECT AVG(end_date-start_date)
206 ORDER BY statnum DESC
210 my $h = int($delay/3600);
211 my $m = int( ($delay%3600) / 60 );
214 $pr_delay = ( $h ? $h. 'h' : '' ).
215 ( $h||$m ? $m. 'm' : '').
220 my $dayago = time2str('%Y-%m-%d %X', time - 86400);
221 my $cdrs = FS::Record->scalar_sql(qq{
222 SELECT COUNT(*) FROM cdr
223 WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
224 AND calldate > '$dayago'
227 $status{'CDR Processing'} = [
228 { 'title' => 'Current processing delay',
231 { 'title' => 'Average billing time',
232 'value' => $pr_delay,
234 { 'title' => 'Unprocessed CDRs (last 24 hours)',
246 my($store, $tokenize) = (0,0);
250 'hashref' => { 'disabled' => '', },
251 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
254 my $gateway = $agent->payment_gateway('method'=>'VISA card', 'nofatal'=>1, );
256 && $gateway->gateway_namespace eq 'Business::OnlinePayment';
257 eval "use Business::OnlinePayment";
259 my $bop = new Business::OnlinePayment( $gateway->gateway_module,
262 : @{ $gateway->get('options') }
264 my %actions = $bop->info('supported_actions');
265 if ( $actions{'CC'} && grep /^Tokenize$/, @{$actions{'CC'}} ) {
273 if ( $tokenize && ! $store ) {
275 $status{'PCI Compliance'} = [
276 { 'title' => 'Tokenization',
277 'value' => 'Enabled',
279 { 'title' => 'SAQ type',
280 'value' => 'A / A-EP',
286 my $conf = new FS::Conf; #wow, didn't need this before?
288 $status{'PCI Compliance'} = [
289 { 'title' => 'Tokenization',
290 'value' => $tokenize ? 'Partialy enabled (some agents)' : 'Disabled'
292 { 'title' => 'Encryption',
294 ( $conf->exists('encryption') && $conf->config('encryptionpublickey')
295 ? 'Enabled' : 'Disabled'
298 { 'title' => 'SAQ type',
299 'value' => 'D (enable tokenization for A / A-EP)',
312 my $pid_path = '/var/run'; #XXX hardcoded path
315 -e "$pid_path/freeside/$thing.pid" ? "$pid_path/freeside/$thing.pid" :
316 -e "$pid_path/freeside-$thing.pid" ? "$pid_path/freeside-$thing.pid" :
319 -e $pidfile and kill 0, slurp($pidfile)