7fd019e8c89ee93d0a0059f6c22bbb22460f6eee
[freeside.git] / httemplate / view / Status.html
1 <& /elements/header.html &>
2 % foreach my $section ( keys %status ) {
3 <FONT CLASS="fsinnerbox-title"><% mt($section) |h %></FONT>
4 <TABLE CLASS="fsinnerbox">
5 %   foreach my $item ( @{ $status{$section} } ) {
6       <TR>
7         <TD ALIGN="right"><% $item->{title} %></TH>
8         <TD><B><% $item->{value} %></B></TD>
9       </TR>
10 %   }
11 </TABLE>
12 <BR><BR>
13 % }
14 <& /elements/footer.html &>
15 <%init>
16
17 my $os;
18 -e '/usr/bin/lsb_release' and run( ['lsb_release', '-d'], '>',\$os );
19 if ( ! $@ && $os =~ /^\s*Description:\s*(.+)$/ ) {
20   $os = $1;
21 } elsif ( my $deb_version = slurp('/etc/debian_version') ) {
22   $os = "Debian $deb_version";
23 }
24
25 ( my $perl_ver = $^V ) =~ s/^v//;
26
27 my $db = driver_name;
28 $db = 'PostgreSQL'    if $db =~ /^Pg/;
29 $db = 'MySQL/MariaDB' if $db =~ /^mysql/;
30
31 my $db_ver = FS::Record->scalar_sql('SELECT VERSION()');
32 if ( $db eq 'PostgreSQL' && $db_ver =~ /^\s*PostgreSQL\s+([\w\.]+)\s+on\s+/ ) {
33   $db_ver = $1;
34 }
35
36 my $db_size = 'Unknown';
37 if ( $db eq 'PostgreSQL' ) {
38   $db_size = FS::Record->scalar_sql(qq(
39     SELECT pg_size_pretty(pg_database_size(datname))
40       FROM pg_catalog.pg_database
41      WHERE datname = 'freeside'
42   ));
43 }
44
45 tie my %status, 'Tie::IxHash',
46   'Basics' => [
47     { 'title' => 'Freeside version',
48       'value' => $FS::VERSION,
49     },
50     { 'title' => 'Operating System',
51       'value' => $os,
52     },
53     { 'title' => 'Perl version',
54       'value' => $perl_ver,
55     },
56     { 'title' => 'Database engine',
57       'value' => $db,
58     },
59     { 'title' => 'Database version',
60       'value' => $db_ver,
61     },
62     { 'title' => 'Database size',
63       'value' => $db_size,
64     },
65   ],
66   'Required Daemons' => [
67     { 'title' => 'Queue daemon',
68       'value' => _is_running('queued') ? 'Running' : 'Not running',
69     },
70   ],
71   'Optional Daemons' => [
72     { 'title' => 'Self-service server(s)',
73       'value' => '(Not checked)', #XXX multiple pid files, per machine etc
74     },
75     { 'title' => 'Self-service XML-RPC server',
76       'value' => _is_running('selfservice-xmlrpcd') ? 'Running' : 'Not running',
77     },
78     { 'title' => 'Back office XML-RPC server',
79       'value' => _is_running('xmlrpcd') ? 'Running' : 'Not running',
80     },
81     { 'title' => 'RADIUS accounting import daemon',
82       'value' => _is_running('sqlradius-radacctd') ? 'Running' : 'Not running',
83     },
84     { 'title' => 'Prepaid daemon',
85       'value' => _is_running('prepaidd') ? 'Running' : 'Not running',
86     },
87     { 'title' => 'CDR Rewrite daemon',
88       'value' => _is_running('cdrrewrited') ? 'Running' : 'Not running',
89     },
90     { 'title' => 'CDR Prepaid daemon',
91       'value' => _is_running('cdrd') ? 'Running' : 'Not running',
92     },
93     { 'title' => 'CDR Real-time rating daemon',
94       'value' => _is_running('cdrrated') ? 'Running' : 'Not running',
95     },
96     #{ 'title' => 'Network monitoring port combiner', #?
97     #  'value' => _is_running('torrus-srvderive') ? 'Running' : 'Not running',
98     #},
99   ],
100 ;
101
102 if ( $db eq 'PostgreSQL' ) {
103
104   my $enabled =    FS::Record->scalar_sql('SHOW wal_level')    eq 'hot_standby'
105                 && FS::Record->scalar_sql('SHOW archive_mode') eq 'on';
106
107   my $slave = 
108     FS::Record->scalar_sql('SHOW archive_command') =~ / postgres\@([\w\.\-]+): /
109       ? $1 : '';
110
111   $status{'Replication'} = [
112     { 'title' => 'Status', #?
113       'value' => $enabled ? 'Enabled' : 'Disabled',
114     },
115   ];
116
117   if ( $enabled ) {
118     push @{ $status{'Replication'} }, 
119       { 'title' => 'Slave',
120         'value' => $slave || '(Missing, or unparseable archive_command)',
121       },
122     ;
123     if ( $slave ) {
124       #how far behind is it?  will be easier once we're off 9.1
125       # http://www.keithf4.com/monitoring_streaming_slave_lag/
126       # except pg_stat_replication still doesn't fill in the columns we need as
127       # non-Pg user :/
128       push @{ $status{'Replication'} }, 
129         { 'title' => 'Slave',
130           'value' => $slave || '(Missing, or unparseable archive_command)',
131         },
132       ;
133     }
134   }
135
136 } else {
137
138   $status{'Replication'} = [
139     { 'title' => 'Enabled',
140       'value' => "(Not yet checked on $db)",
141     },
142   ];
143
144 }
145
146 if ( _is_running('cdrd') ) {
147
148   my $delay = FS::Record->scalar_sql('
149     SELECT AVG(end_date-insert_date)
150       FROM queue_stat
151       GROUP BY statnum
152       ORDER BY statnum DESC
153       LIMIT 100
154   ');
155   if ( $delay ) {
156     my $h = int($delay/3600);
157     my $m = int( ($delay%3600) / 60 );
158     my $s = $delay%60;
159
160     $delay = ( $h     ? $h. 'h' : '' ).
161              ( $h||$m ? $m. 'm' : '').
162                         $s. 's';
163
164   }
165
166   my $pr_delay = FS::Record->scalar_sql('
167     SELECT AVG(end_date-start_date)
168       FROM queue_stat
169       GROUP BY statnum
170       ORDER BY statnum DESC
171       LIMIT 100
172   ');
173   if ( $pr_delay ) {
174     my $h = int($delay/3600);
175     my $m = int( ($delay%3600) / 60 );
176     my $s = $delay%60;
177
178     $pr_delay = ( $h     ? $h. 'h' : '' ).
179                 ( $h||$m ? $m. 'm' : '').
180                            $s. 's';
181
182   }
183
184   my $dayago = time2str('%Y-%m-%d %X', time - 86400);
185   my $cdrs = FS::Record->scalar_sql(qq{
186     SELECT COUNT(*) FROM cdr
187       WHERE ( freesidestatus IS NULL OR freesidestatus = '' )
188         AND calldate > '$dayago'
189   });
190
191   $status{'CDR Processing'} = [
192     { 'title' => 'Current processing delay',
193       'value' => $delay,
194     },
195     { 'title' => 'Average billing time',
196       'value' => $pr_delay,
197     },
198     { 'title' => 'Unprocessed CDRs (last 24 hours)',
199       'value' => $cdrs,
200     },
201   ];
202
203 }
204
205 sub _is_running {
206   my $thing = shift;
207
208   my $pid_path = '/var/run'; #XXX hardcoded path
209
210   my $pidfile =
211     -e "$pid_path/freeside/$thing.pid" ? "$pid_path/freeside/$thing.pid" :
212     -e "$pid_path/freeside-$thing.pid" ? "$pid_path/freeside-$thing.pid" :
213    return 0;
214
215   -e $pidfile and kill 0, slurp($pidfile)
216 }
217
218 </%init>