=head1 NAME

Sys::Statistics::Linux::CpuInfo - Collect linux cpu statistics.

=head1 SYNOPSIS

   use Sys::Statistics::Linux::CpuInfo;

   my $lxs  = new Sys::Statistics::Linux::CpuInfo;
   my $info = $lxs->get;

=head1 DESCRIPTION

Sys::Statistics::Linux::CpuInfo gathers cpu informations from the virtual F</proc> filesystem (procfs).

For more informations read the documentation of the front-end module L<Sys::Statistics::Linux>.

=head1 CPU STATISTICS

Generated by F</proc/cpuinfo> for each cpu (cpu0, cpu1 ...).

    model_name  - The model name.
    cpu_mhz     - The speed in MHz of the processor.
    cache_size  - The cache size of the prozessor.
    bogomips    - The speed in bogomips of the processor.

Note that not all keys are available on different hardware architectures. If you meet a arch that
provide a different place to find the keys then I would be pleased if you send me an output
of C</proc/cpuinfo>.

=head1 METHODS

=head2 new()

Call C<new()> to create a new object.

   my $lxs = Sys::Statistics::Linux::CpuInfo->new;

=head2 get()

Call C<get()> to get the statistics. C<get()> returns the statistics as a hash reference.

   my $info = $lxs->get;

=head1 EXPORTS

No exports.

=head1 SEE ALSO

B<proc(5)>

=head1 REPORTING BUGS

Please report all bugs to <jschulz.cpan(at)bloonix.de>.

=head1 AUTHOR

Jonny Schulz <jschulz.cpan(at)bloonix.de>.

=head1 COPYRIGHT

Copyright (c) 2006, 2007 by Jonny Schulz. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=cut

package Sys::Statistics::Linux::CpuInfo;
our $VERSION = '0.02';

use strict;
use warnings;
use Carp qw(croak);

sub new {
    my $class = shift;
    my %self = (
        files => {
            cpuinfo => '/proc/cpuinfo',
            sysinfo => '/proc/sysinfo',
        }
    );
    return bless \%self, $class;
}

sub get {
    my $self  = shift;
    my $class = ref $self;
    my $file  = $self->{files};
    my (%infos, $proc, $bogomips, $s390);

    open my $fh, '<', $file->{cpuinfo} or croak "$class: unable to open $file->{cpuinfo} ($!)";

    while (my $line = <$fh>) {
        if ($line =~ /^processor\s*:\s*(\d+)/) {
            $proc = $1;
        } elsif ($line =~ /^processor\s*(\d+)/) {
            $infos{"cpu$1"}->{bogomips} = $bogomips;
        } elsif ($line =~ /^(model\s+name|cpu\s+MHz|cache\s+size|bogomips)\s*:\s*(.+)/) {
            my ($name, $value) = ($1, $2);
            $name =~ tr/ /_/;
            $name =~ tr/A-Z/a-z/;
            chomp($value);
            $infos{"cpu$proc"}->{$name} = $value;
        } elsif ($line =~ /^bogomips\s+per\s+cpu:\s*(.+)/) {
            $s390 = 1;
            $bogomips = $1;
        }
        next unless $proc;
    }

    if ($s390) {
        my %sInfo;
        open my $fh, '<', $file->{sysinfo} or croak "$class: unable to open $file->{sysinfo} ($!)";
        while (my $line = <$fh>) {
            if ($line =~ /^(Manufacturer|Type|Model):\s*(.+)/) {
                my ($name, $value) = ($1, $2);
                $value =~ s/\s+//g;
                $sInfo{$name} = $value;
            }
        }
        close $fh;
        foreach my $x (keys %infos) {
            $infos{$x}{model_name} = "$sInfo{Manufacturer} $sInfo{Type}";
            $infos{$x}{model} = $sInfo{Model};
        }
    }

    close($fh);
    return \%infos;
}

1;
