1package App::Netdisco::Util::Statistics;
2
3use Dancer qw/:syntax :script/;
4use Dancer::Plugin::DBIC 'schema';
5
6use Time::Piece; # for OO localtime
7
8use base 'Exporter';
9our @EXPORT = ();
10our @EXPORT_OK = qw/update_stats/;
11our %EXPORT_TAGS = (all => \@EXPORT_OK);
12
13=head1 NAME
14
15App::Netdisco::Util::Statistics
16
17=head1 DESCRIPTION
18
19Update the Netdisco statistics.
20
21There are no default exports, however the C<:all> tag will export all
22subroutines.
23
24=head1 EXPORT_OK
25
26=head2 update_stats()
27
28Update the Netdisco statistics, either new for today or updating today's
29figures.
30
31=cut
32
33sub update_stats {
34  my $schema = schema('netdisco');
35  eval { require SNMP::Info };
36  my $snmpinfo_ver = ($@ ? 'n/a' : $SNMP::Info::VERSION);
37  my $postgres_ver = pretty_version($schema->storage->dbh->{pg_server_version}, 2);
38
39  # TODO: (when we have the capabilities table?)
40  #  $stats{waps} = sql_scalar('device',['COUNT(*)'], {"model"=>"AIR%"});
41
42  $schema->txn_do(sub {
43    $schema->resultset('Statistics')->update_or_create({
44      day => localtime->ymd,
45
46      device_count =>
47        $schema->resultset('Device')->count_rs->as_query,
48      device_ip_count =>
49        $schema->resultset('DeviceIp')->count_rs->as_query,
50      device_link_count =>
51        ( $postgres_ver =~ m/^8\./ ? 0 :
52        $schema->resultset('Virtual::DeviceLinks')->search(undef, {
53            select => [ { coalesce => [ { sum => 'aggports' }, 0 ] } ],
54            as => ['totlinks'],
55        })->get_column('totlinks')->as_query ),
56      device_port_count =>
57        $schema->resultset('DevicePort')->count_rs->as_query,
58      device_port_up_count =>
59        $schema->resultset('DevicePort')->count_rs({up => 'up'})->as_query,
60      ip_table_count =>
61        $schema->resultset('NodeIp')->count_rs->as_query,
62      ip_active_count =>
63        $schema->resultset('NodeIp')->search({-bool => 'active'},
64          {columns => 'ip', distinct => 1})->count_rs->as_query,
65      node_table_count =>
66        $schema->resultset('Node')->count_rs->as_query,
67      node_active_count =>
68        $schema->resultset('Node')->search({-bool => 'active'},
69          {columns => 'mac', distinct => 1})->count_rs->as_query,
70
71      netdisco_ver => pretty_version($App::Netdisco::VERSION, 3),
72      snmpinfo_ver => $snmpinfo_ver,
73      schema_ver   => $schema->schema_version,
74      perl_ver     => pretty_version($], 3),
75      pg_ver       => $postgres_ver,
76
77    }, { key => 'primary' });
78  });
79}
80
81# take perl or pg versions and make pretty
82sub pretty_version {
83  my ($version, $seglen) = @_;
84  return unless $version and $seglen;
85  return $version if $version !~ m/^[0-9.]+$/;
86  $version =~ s/\.//g;
87  $version = (join '.', reverse map {scalar reverse}
88    unpack("(A${seglen})*", reverse $version));
89  $version =~ s/\.000/.0/g;
90  $version =~ s/\.0+([1-9]+)/.$1/g;
91  return $version;
92}
93
94true;
95