]>
git.proxmox.com Git - pmg-api.git/blob - PMG/CLI/pmgreport.pm
1 package PMG
:: CLI
:: pmgreport
;
6 use POSIX
qw(strftime) ;
14 use PMG
:: RESTEnvironment
;
17 use PMG
:: ClusterConfig
;
19 use PMG
:: API2
:: Cluster
;
23 use PMG
:: API2
:: Statistics
;
25 use base
qw(PVE::CLIHandler) ;
27 my $nodename = PVE
:: INotify
:: nodename
();
29 sub setup_environment
{
30 PMG
:: RESTEnvironment-
> setup_default_cli_env ();
32 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
33 # API /config/cluster/nodes need a ticket to connect to other nodes
34 my $ticket = PMG
:: Ticket
:: assemble_ticket
( 'root @pam ' );
35 $rpcenv -> set_ticket ( $ticket );
38 my $get_system_table_data = sub {
40 my $ni = PMG
:: API2
:: NodeInfo-
> status ({ node
=> $nodename });
44 push @$data, { text
=> 'Hostname' , value
=> $nodename };
46 my $uptime = $ni ->{ uptime
} ? PMG
:: Utils
:: format_uptime
( $ni ->{ uptime
}) : '-' ;
48 push @$data, { text
=> 'Uptime' , value
=> $uptime };
50 push @$data, { text
=> 'Version' , value
=> $ni ->{ pmgversion
} };
53 if ( my $d = $ni ->{ loadavg
}) {
54 $loadavg15 = sprintf ( "%.2f" , $d ->[ 2 ]);
56 push @$data, { text
=> 'Load' , value
=> $loadavg15 };
59 if ( my $d = $ni ->{ memory
}) {
60 $mem = sprintf ( "%.2f %% " , $d ->{ used
}* 100 / $d ->{ total
});
62 push @$data, { text
=> 'Memory' , value
=> $mem };
65 if ( my $d = $ni ->{ rootfs
}) {
66 $disk = sprintf ( "%.2f %% " , $d ->{ used
}* 100 / $d ->{ total
});
68 push @$data, { text
=> 'Disk' , value
=> $disk };
73 my $get_cluster_table_data = sub {
75 my $res = PMG
:: API2
:: Cluster-
> status ({});
76 return undef if ! scalar ( @$res );
80 foreach my $ni ( @$res ) {
82 $state = 'S' if ! $ni ->{ insync
};
84 if ( my $err = $ni ->{ conn_error
}) {
86 $state = encode_entities
( "ERROR: $err " );
90 if ( my $d = $ni ->{ loadavg
}) {
91 $loadavg1 = sprintf ( "%.2f" , $d ->[ 0 ]);
95 if ( my $d = $ni ->{ memory
}) {
96 $memory = sprintf ( "%.2f %% " , $d ->{ used
}* 100 / $d ->{ total
});
100 if ( my $d = $ni ->{ rootfs
}) {
101 $disk = sprintf ( "%.2f %% " , $d ->{ used
}* 100 / $d ->{ total
});
105 hostname
=> $ni ->{ name
},
109 loadavg1
=> $loadavg1,
118 my $get_incoming_table_data = sub {
124 text
=> 'Incoming Mails' ,
125 value
=> $totals ->{ count_in
},
128 my $count_in = $totals ->{ count_in
};
130 my $junk_in_per = $count_in ?
sprintf ( " %0 .2f" , ( $totals ->{ junk_in
}* 100 )/ $count_in ) : undef ;
133 text
=> 'Junk Mails' ,
134 value
=> $totals ->{ junk_in
},
135 percentage
=> $junk_in_per,
138 my $spamcount_in_per = $count_in ?
sprintf ( " %0 .2f" , ( $totals ->{ spamcount_in
}* 100 )/ $count_in ) : undef ;
141 text
=> 'Spam Mails' ,
142 value
=> $totals ->{ spamcount_in
},
143 percentage
=> $spamcount_in_per,
146 my $spfcount_per = $count_in ?
sprintf ( " %0 .2f" , ( $totals ->{ spfcount
}* 100 )/ $count_in ) : undef ;
149 text
=> 'SPF rejects' ,
150 value
=> $totals ->{ spfcount
},
151 percentage
=> $spfcount_per,
154 my $bounces_in_per = $count_in ?
sprintf ( " %0 .2f" , ( $totals ->{ bounces_in
}* 100 )/ $count_in ) : undef ;
158 value
=> $totals ->{ bounces_in
},
159 percentage
=> $bounces_in_per,
162 my $viruscount_in_per = $count_in ?
sprintf ( " %0 .2f" , ( $totals ->{ viruscount_in
}* 100 )/ $count_in ) : undef ;
164 text
=> 'Virus Mails' ,
165 value
=> $totals ->{ viruscount_in
},
166 percentage
=> $viruscount_in_per,
170 text
=> 'Mail Traffic' ,
171 value
=> sprintf ( "%.3f MByte" , $totals ->{ bytes_in
}/( 1024 * 1024 )),
177 my $get_outgoing_table_data = sub {
183 text
=> 'Outgoing Mails' ,
184 value
=> $totals ->{ count_out
},
187 my $count_out = $totals ->{ count_out
};
189 my $bounces_out_per = $count_out ?
sprintf ( " %0 .2f" , ( $totals ->{ bounces_out
}* 100 )/ $count_out ) : undef ;
193 value
=> $totals ->{ bounces_out
},
194 percentage
=> $bounces_out_per,
198 text
=> 'Mail Traffic' ,
199 value
=> sprintf ( "%.3f MByte" , $totals ->{ bytes_out
}/( 1024 * 1024 )),
205 my $get_virus_table_data = sub {
206 my ( $virusinfo ) = @_ ;
210 foreach my $entry ( @$virusinfo ) {
211 next if ! $entry ->{ count
};
212 last if scalar ( @$data ) >= 10 ;
213 push @$data, { name
=> $entry ->{ name
}, count
=> $entry ->{ count
} };
216 return undef if ! scalar ( @$data );
221 my $get_quarantine_table_data = sub {
222 my ( $dbh, $qtype ) = @_ ;
224 my $ref = PMG
:: DBTools
:: get_quarantine_count
( $dbh, $qtype );
226 return undef if !( $ref && $ref ->{ count
});
231 text
=> "Quarantine Size (MBytes)" ,
232 value
=> int ( $ref ->{ mbytes
}),
236 text
=> "Number of Mails" ,
237 value
=> $ref ->{ count
},
241 text
=> "Average Size (Bytes)" ,
242 value
=> int ( $ref ->{ avgbytes
}),
247 text
=> "Average Spam Level" ,
248 value
=> int ( $ref ->{ avgspam
}),
255 __PACKAGE__-
> register_method ({
259 description
=> "Generate and send daily system report email." ,
261 additionalProperties
=> 0 ,
264 description
=> "Debug mode. Print raw email to stdout instead of sending them." ,
270 description
=> "Auto mode. Use setting from system configuration (set when invoked fron cron)." ,
276 description
=> "Send report to this email address. Default is the administratior email address." ,
277 type
=> 'string' , format
=> 'email' ,
281 description
=> "Select time span for included email statistics. \n\n NOTE: System and cluster performance data is always from current time (when script is run)." ,
283 enum
=> [ 'today' , 'yesterday' ],
289 returns
=> { type
=> 'null' },
293 my $timespan = $param ->{ timespan
} // 'today' ;
294 my ( $start, $end ) = PMG
:: Utils
:: lookup_timespan
( $timespan );
296 my $fqdn = PVE
:: Tools
:: get_fqdn
( $nodename );
299 hostname
=> $nodename,
301 date
=> strftime
( " %F " , localtime ( $end - 1 )),
304 my $cinfo = PMG
:: ClusterConfig-
> new ();
305 my $role = $cinfo ->{ local }->{ type
} // '-' ;
308 $vars ->{ system } = $get_system_table_data ->();
310 $vars ->{ cluster
} = $get_cluster_table_data ->();
311 if ( $role eq 'master' ) {
314 return undef if $param ->{ auto
}; # silent exit - do not send report
318 my $rdb = PMG
:: RuleDB-
> new ();
321 PMG
:: Statistic
:: update_stats
( $rdb ->{ dbh
}, $cinfo );
323 my $totals = PMG
:: API2
:: Statistics-
> mail (
324 { starttime
=> $start, endtime
=> $end });
326 $vars ->{ incoming
} = $get_incoming_table_data ->( $totals );
328 $vars ->{ outgoing
} = $get_outgoing_table_data ->( $totals );
330 my $stat = PMG
:: Statistic-
> new ( $start, $end );
331 my $virusinfo = $stat -> total_virus_stat ( $rdb );
332 if ( my $data = $get_virus_table_data ->( $virusinfo )) {
333 $vars ->{ virusstat
} = $data ;
336 if ( my $data = $get_quarantine_table_data ->( $rdb ->{ dbh
}, 'V' )) {
337 $vars ->{ virusquar
} = $data ;
340 if ( my $data = $get_quarantine_table_data ->( $rdb ->{ dbh
}, 'S' )) {
341 $vars ->{ spamquar
} = $data ;
344 my $tt = PMG
:: Config
:: get_template_toolkit
();
346 my $cfg = PMG
:: Config-
> new ();
347 my $email = $param ->{ receiver
} // $cfg -> get ( 'admin' , 'email' );
349 if (! defined ( $email )) {
350 return undef if $param ->{ auto
}; # silent exit - do not send report
351 die "no receiver configured \n " ;
354 my $enable = $cfg -> get ( 'admin' , 'dailyreport' ) // 1 ;
356 if ( $param ->{ auto
} && ! $enable ) {
357 # do nothing when disabled
361 my $mailfrom = "Proxmox Mail Gateway <postmaster>" ;
362 PMG
:: Utils
:: finalize_report
( $tt, 'pmgreport.tt' , $vars, $mailfrom, $email, $param ->{ debug
});
367 our $cmddef = [ __PACKAGE__
, 'pmgreport' , [], undef ];