]> git.proxmox.com Git - pmg-api.git/blame - PMG/CLI/pmgreport.pm
pmgreport: add mail traffic
[pmg-api.git] / PMG / CLI / pmgreport.pm
CommitLineData
3dfe317a
DM
1package PMG::CLI::pmgreport;
2
3use strict;
4use Data::Dumper;
5use Template;
6use POSIX qw(strftime);
7
8use PVE::INotify;
9use PVE::CLIHandler;
10
11use PMG::Utils;
12use PMG::Config;
13use PMG::RESTEnvironment;
308c2bfc 14
3dfe317a 15use PMG::API2::Nodes;
308c2bfc
DM
16use PMG::ClusterConfig;
17use PMG::Cluster;
18use PMG::API2::Cluster;
02251e49
DM
19use PMG::RuleDB;
20use PMG::Statistic;
3dfe317a
DM
21
22use base qw(PVE::CLIHandler);
23
24my $nodename = PVE::INotify::nodename();
25
26sub setup_environment {
27 PMG::RESTEnvironment->setup_default_cli_env();
308c2bfc
DM
28
29 my $rpcenv = PMG::RESTEnvironment->get();
30 # API /config/cluster/nodes need a ticket to connect to other nodes
31 my $ticket = PMG::Ticket::assemble_ticket('root@pam');
32 $rpcenv->set_ticket($ticket);
3dfe317a
DM
33}
34
35my $get_system_table_data = sub {
36
37 my $ni = PMG::API2::NodeInfo->status({ node => $nodename });
38
39 my $data = [];
40
41 push @$data, { text => 'Hostname', value => $nodename };
42
43 my $uptime = $ni->{uptime} ? PMG::Utils::format_uptime($ni->{uptime}) : '-';
44
45 push @$data, { text => 'Uptime', value => $uptime };
46
47 push @$data, { text => 'Version', value => $ni->{pmgversion} };
48
49 my $loadavg15 = '-';
50 if (my $d = $ni->{loadavg}) {
308c2bfc 51 $loadavg15 = sprintf("%.2f", $d->[2]);
3dfe317a
DM
52 }
53 push @$data, { text => 'Load', value => $loadavg15 };
54
55 my $mem = '-';
56 if (my $d = $ni->{memory}) {
57 $mem = sprintf("%.2f%%", $d->{used}*100/$d->{total});
58 }
59 push @$data, { text => 'Memory', value => $mem };
60
61 my $disk = '-';
62 if (my $d = $ni->{rootfs}) {
63 $disk = sprintf("%.2f%%", $d->{used}*100/$d->{total});
64 }
65 push @$data, { text => 'Disk', value => $disk };
66
67 return $data
68};
69
308c2bfc
DM
70my $get_cluster_table_data = sub {
71
72 my $res = PMG::API2::Cluster->status({});
73 return undef if !scalar(@$res);
74
75 my $data = [];
76
77 foreach my $ni (@$res) {
78 my $state = 'A';
79 $state = 'S' if !$ni->{insync};
80
81 my $loadavg1 = '-';
82 if (my $d = $ni->{loadavg}) {
83 $loadavg1 = sprintf("%.2f", $d->[0]);
84 }
85
86 my $memory = '-';
87 if (my $d = $ni->{memory}) {
88 $memory = sprintf("%.2f%%", $d->{used}*100/$d->{total});
89 }
90
91 my $disk = '-';
92 if (my $d = $ni->{rootfs}) {
93 $disk = sprintf("%.2f%%", $d->{used}*100/$d->{total});
94 }
95
96 push @$data, {
97 hostname => $ni->{name},
98 ip => $ni->{ip},
99 type => $ni->{type},
100 state => $state,
101 loadavg1 => $loadavg1,
102 memory => $memory,
103 disk => $disk,
104 };
105 };
106
107 return $data;
108};
3dfe317a
DM
109
110__PACKAGE__->register_method ({
111 name => 'pmgreport',
112 path => 'pmgreport',
113 method => 'POST',
114 description => "Generate and send daily system report email.",
115 parameters => {
116 additionalProperties => 0,
308c2bfc
DM
117 properties => {
118 debug => {
119 description => "Debug mode. Print raw email to stdout instead of sending them.",
120 type => 'boolean',
121 optional => 1,
122 default => 0,
123 },
124 auto => {
125 description => "Auto mode. Use setting from system configuration (set when invoked fron cron).",
126 type => 'boolean',
127 optional => 1,
128 default => 0,
129 },
130 receiver => {
131 description => "Send report to this email address. Default is the administratior email address.",
132 type => 'string', format => 'email',
133 optional => 1,
134 },
2f7031b7
DM
135 timespan => {
136 description => "Select time span for included email statistics.\n\nNOTE: System and cluster performance data is always from current time (when script is run).",
137 type => 'string',
138 enum => ['today', 'yesterday'],
139 default => 'today',
140 optional => 1,
141 },
308c2bfc 142 },
3dfe317a
DM
143 },
144 returns => { type => 'null'},
145 code => sub {
146 my ($param) = @_;
147
2f7031b7
DM
148 my $timespan = $param->{timespan} // 'today';
149 my ($start, $end) = PMG::Utils::lookup_timespan($timespan);
3dfe317a 150
2f7031b7 151 my $fqdn = PVE::Tools::get_fqdn($nodename);
3dfe317a
DM
152
153 my $vars = {
154 hostname => $nodename,
155 fqdn => $fqdn,
156 date => strftime("%F", localtime($end - 1)),
157 };
158
308c2bfc
DM
159 my $cinfo = PMG::ClusterConfig->new();
160 my $role = $cinfo->{local}->{type} // '-';
161
162 if ($role eq '-') {
163 $vars->{system} = $get_system_table_data->();
164 } else {
165 $vars->{cluster} = $get_cluster_table_data->();
166 if ($role eq 'master') {
167 # OK
168 } else {
169 return undef if $param->{auto}; # silent exit - do not send report
170 }
171 }
3dfe317a 172
02251e49
DM
173
174 my $stat = PMG::Statistic->new ($start, $end);
175 my $rdb = PMG::RuleDB->new();
176
177 # update statistics
178 PMG::Statistic::update_stats($rdb->{dbh}, $cinfo);
179
180 my $totals = $stat->total_mail_stat($rdb);
02251e49
DM
181
182 # Generate data for incoming mails
183 my $data = [];
184 push @$data, { text => 'Incoming Mails', value => $totals->{count_in}, percentage => $totals->{count_in_per} };
7264942e
DM
185 push @$data, { text => 'Spam Mails', value => $totals->{spamcount_in}, percentage => $totals->{spamcount_in_per} };
186 push @$data, { text => 'Virus Mails', value => $totals->{viruscount_in}, percentage => $totals->{viruscount_in_per} };
187 push @$data, { text => 'SPF rejects', value => $totals->{spfcount}, percentage => $totals->{spfcount_per} };
188 push @$data, { text => 'Mail Traffic', value => sprintf ("%.3f MByte", $totals->{traffic_in}) };
02251e49
DM
189
190 $vars->{incoming} = $data,
191
192 # Generate data for outgoing mails
193 $data = [];
194 push @$data, { text => 'Outgoing Mails', value => $totals->{count_out}, percentage => $totals->{count_out_per} };
195 push @$data, { text => 'Bounces', value => $totals->{bounces_out}, percentage => $totals->{bounces_out_per} };
7264942e 196 push @$data, { text => 'Mail Traffic', value => sprintf ("%.3f MByte", $totals->{traffic_out}) };
02251e49
DM
197
198 $vars->{outgoing} = $data,
199
3dfe317a
DM
200 my $tt = PMG::Config::get_template_toolkit();
201
202 my $cfg = PMG::Config->new();
308c2bfc 203 my $email = $param->{receiver} // $cfg->get ('admin', 'email');
3dfe317a
DM
204
205 if (!defined($email)) {
308c2bfc
DM
206 return undef if $param->{auto}; # silent exit - do not send report
207 die "no receiver configured\n";
3dfe317a
DM
208 }
209
210 my $mailfrom = "Proxmox Mail Gateway <postmaster>";
211 PMG::Utils::finalize_report($tt, 'pmgreport.tt', $vars, $mailfrom, $email, $param->{debug});
212
213 return undef;
214 }});
215
216our $cmddef = [ __PACKAGE__, 'pmgreport', [], undef ];
217
2181;