just the relevant Pg info
[freeside.git] / httemplate / view / Status.html
index 019470e..f81c95d 100644 (file)
@@ -1,4 +1,7 @@
-<& /elements/header.html &>
+<& /elements/header.html, 'System Status' &>
+
+<& /elements/init_overlib.html &>
+
 % foreach my $section ( keys %status ) {
 <FONT CLASS="fsinnerbox-title"><% mt($section) |h %></FONT>
 <TABLE CLASS="fsinnerbox">
 </TABLE>
 <BR><BR>
 % }
+
 <& /elements/footer.html &>
 <%init>
 
+###
+# Basics and Daemons
+###
+
 my $os;
 -e '/usr/bin/lsb_release' and run( ['lsb_release', '-d'], '>',\$os );
 if ( ! $@ && $os =~ /^\s*Description:\s*(.+)$/ ) {
@@ -22,22 +30,49 @@ if ( ! $@ && $os =~ /^\s*Description:\s*(.+)$/ ) {
   $os = "Debian $deb_version";
 }
 
+my $pkg_version = '';
+-e '/usr/bin/dpkg-query'
+  and run( ['/usr/bin/dpkg-query',
+              '--showformat=${Version}', '--show', 'freeside'
+           ],
+           '>', \$pkg_version
+         );
+
 ( my $perl_ver = $^V ) =~ s/^v//;
 
 my $db = driver_name;
-$db = 'PostgreSQL' if $db =~ /^Pg/;
-$db = 'MySQL'      if $db =~ /^mysql/;
+$db = 'PostgreSQL'    if $db =~ /^Pg/;
+$db = 'MySQL/MariaDB' if $db =~ /^mysql/;
 
 my $db_ver = FS::Record->scalar_sql('SELECT VERSION()');
-if ( $db eq 'PostgreSQL' && $db_ver =~ /^\s*PostgreSQL\s+([\w\.]+)\s+on\s+/ ) {
+if ( $db eq 'PostgreSQL' && $db_ver =~ /^\s*PostgreSQL\s+([\w\.]+(\s+\([\w\s\.\+\-\:\~]+\))?)\s+on\s+/ ) {
   $db_ver = $1;
 }
 
+my $db_size = 'Unknown';
+if ( $db eq 'PostgreSQL' ) {
+  $db_size = FS::Record->scalar_sql(qq(
+               SELECT pg_size_pretty(pg_database_size('freeside'))
+             )). ' '.
+             include('/elements/popup_link.html',
+                       'action'      => 'Status-db_size_detail.html',
+                       'label'       => '(details)',
+                       'actionlabel' => 'Database size details',
+             );
+}
+
 tie my %status, 'Tie::IxHash',
   'Basics' => [
     { 'title' => 'Freeside version',
       'value' => $FS::VERSION,
     },
+    ( length($pkg_version)
+        ? ( { 'title' => 'Package version',
+              'value' => $pkg_version,
+            },
+          )
+        : ()
+    ),
     { 'title' => 'Operating System',
       'value' => $os,
     },
@@ -50,6 +85,9 @@ tie my %status, 'Tie::IxHash',
     { 'title' => 'Database version',
       'value' => $db_ver,
     },
+    { 'title' => 'Database size',
+      'value' => $db_size,
+    },
   ],
   'Required Daemons' => [
     { 'title' => 'Queue daemon',
@@ -87,6 +125,60 @@ tie my %status, 'Tie::IxHash',
   ],
 ;
 
+
+###
+# Replication
+###
+
+if ( $db eq 'PostgreSQL' ) {
+
+  my $enabled =    FS::Record->scalar_sql('SHOW wal_level')    eq 'hot_standby'
+                && FS::Record->scalar_sql('SHOW archive_mode') eq 'on';
+
+  my $slave = 
+    FS::Record->scalar_sql('SHOW archive_command') =~ / postgres\@([\w\.\-]+):/
+      ? $1 : '';
+
+  $status{'Replication'} = [
+    { 'title' => 'Status', #?
+      'value' => $enabled ? 'Enabled' : 'Disabled',
+    },
+  ];
+
+  if ( $enabled ) {
+    push @{ $status{'Replication'} }, 
+      { 'title' => 'Slave',
+        'value' => $slave || '(Missing, or unparseable archive_command)',
+      },
+    ;
+    if ( $slave ) {
+      #how far behind is it?  will be easier once we're off 9.1
+      # http://www.keithf4.com/monitoring_streaming_slave_lag/
+      # except pg_stat_replication still doesn't fill in the columns we need as
+      # non-Pg user :/
+      #push @{ $status{'Replication'} }, 
+      #  { 'title' => 'Slave',
+      #    'value' => $slave || '(Missing, or unparseable archive_command)',
+      #  },
+      #;
+    }
+  }
+
+} else {
+
+  $status{'Replication'} = [
+    { 'title' => 'Enabled',
+      'value' => "(Not yet checked on $db)",
+    },
+  ];
+
+}
+
+
+###
+# CDR Processing
+###
+
 if ( _is_running('cdrd') ) {
 
   my $delay = FS::Record->scalar_sql('
@@ -107,14 +199,113 @@ if ( _is_running('cdrd') ) {
 
   }
 
+  my $pr_delay = FS::Record->scalar_sql('
+    SELECT AVG(end_date-start_date)
+      FROM queue_stat
+      GROUP BY statnum
+      ORDER BY statnum DESC
+      LIMIT 100
+  ');
+  if ( $pr_delay ) {
+    my $h = int($delay/3600);
+    my $m = int( ($delay%3600) / 60 );
+    my $s = $delay%60;
+
+    $pr_delay = ( $h     ? $h. 'h' : '' ).
+                ( $h||$m ? $m. 'm' : '').
+                           $s. 's';
+
+  }
+
+  my $dayago = time2str('%Y-%m-%d %X', time - 86400);
+  my $cdrs = FS::Record->scalar_sql(qq{
+    SELECT COUNT(*) FROM cdr
+      WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
+        AND calldate > '$dayago'
+  });
+
   $status{'CDR Processing'} = [
     { 'title' => 'Current processing delay',
       'value' => $delay,
     },
+    { 'title' => 'Average billing time',
+      'value' => $pr_delay,
+    },
+    { 'title' => 'Unprocessed CDRs (last 24 hours)',
+      'value' => $cdrs,
+    },
+  ];
+
+}
+
+
+###
+# PCI Compliance
+###
+
+my($store, $tokenize) = (0,0);
+foreach my $agent (
+  qsearch({
+    'table'     => 'agent',
+    'hashref'   => { 'disabled' => '', },
+    'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+  })
+) {
+  my $gateway = $agent->payment_gateway('method'=>'VISA card', 'nofatal'=>1, );
+  next unless $gateway
+           && $gateway->gateway_namespace eq 'Business::OnlinePayment';
+  eval "use Business::OnlinePayment";
+  die $@ if $@; #die?
+  my $bop = new Business::OnlinePayment( $gateway->gateway_module,
+                                         $gateway->gatewaynum
+                                           ? $gateway->options
+                                           : @{ $gateway->get('options') }
+                                       );
+  my %actions = $bop->info('supported_actions');
+  if ( $actions{'CC'} && grep /^Tokenize$/, @{$actions{'CC'}} ) {
+    $tokenize++;
+  } else {
+    $store++;
+  }
+  
+}
+
+if ( $tokenize && ! $store ) {
+
+  $status{'PCI Compliance'} = [
+    { 'title' => 'Tokenization',
+      'value' => 'Enabled',
+    },
+    { 'title' => 'SAQ type',
+      'value' => 'A / A-EP',
+    },
+  ];
+
+} elsif ( $store ) {
+
+  my $conf = new FS::Conf; #wow, didn't need this before?
+
+  $status{'PCI Compliance'} = [
+    { 'title' => 'Tokenization',
+      'value' => $tokenize ? 'Partialy enabled (some agents)' : 'Disabled'
+    },
+    { 'title' => 'Encryption',
+      'value' =>
+        ( $conf->exists('encryption') && $conf->config('encryptionpublickey')
+            ? 'Enabled' : 'Disabled'
+        ),
+    },
+    { 'title' => 'SAQ type',
+      'value' => 'D (enable tokenization for A / A-EP)',
+    },
   ];
 
 }
 
+###
+# Subroutines
+###
+
 sub _is_running {
   my $thing = shift;