????
| Current Path : /usr/lib/sonarpush/SonarPush/Providers/ |
| Current File : //usr/lib/sonarpush/SonarPush/Providers/Hardware.pm |
package SonarPush::Providers::Hardware;
use base qw(SonarPush::Providers);
use strict;
use JSON::Tiny qw(decode_json encode_json);
=head1 NAME
SonarPush::Providers::Hardware - collects hardware information
=head1 DESCRIPTION
class of tasks for collecing various information about hardware that
is installed on a machine
=cut
sub cpu {
my $self = shift;
my $provider = 'cpu';
my %attrs = (
config => {
providedby => $provider,
datatype => "Text",
},
noConfig => {
providedby => $provider,
datatype => "None",
},
);
my $xml = {
name => $provider,
attributes => $attrs{noConfig},
value => [],
};
my $detailNode = {
name => 'detail',
attributes => $attrs{noConfig},
value => [],
};
my $flag = 1;
my $output = do {
local $/;
open(INPUT, "< /proc/cpuinfo");
<INPUT>;
};
my @logical = split(/\n\n/, $output);
my %wantedAttrs = map { $_ => 1 } ('physical id', 'cpu MHz', 'model name', 'cache size', 'cpu cores', 'siblings', 'flags');
my %attrTagNameMap = (
'physical id' => 'physid',
'cpu MHz' => 'speed',
'model name' => 'make',
'cache size' => 'cache',
'cpu cores' => 'cores',
'siblings' => 'siblings',
'flags' => 'hyperthreaded',
);
my @processorDetails;
for my $logicalProcessor (@logical) {
my @attributes = split(/\n/, $logicalProcessor);
chomp for @attributes;
my %attributes;
for my $attribute (@attributes) {
my ($name, $value) = split(/:/, $attribute);
$name =~ s/^\s+|\s+$//g;
$value =~ s/^\s+|\s+$//g;
if ($name eq 'flags') {
if ($value =~ /\bht\b/) {
$value = 'yes';
}
else {
$value = 'no';
}
}
if ($wantedAttrs{$name}) {
$attributes{ $attrTagNameMap{$name} } = $value;
}
}
push(@processorDetails, \%attributes);
}
my $totalCores = 0;
$totalCores += $_->{cores} for @processorDetails;
for my $topLevelNode (qw(make speed hyperthreaded)) {
# We should be safe to assume that the server has at least one processor.
push(@{ $xml->{value} }, { name => $topLevelNode, value => $processorDetails[0]{$topLevelNode}, attributes => $attrs{config} });
}
push(@{ $xml->{value} }, { name => 'count', value => scalar(@logical), attributes => $attrs{config} });
push(@{ $detailNode->{value} }, { name => 'totalcores', value => $totalCores, attributes => $attrs{config} });
push(@{ $xml->{value} }, $detailNode);
foreach my $processor (@processorDetails) {
my $physid = delete $processor->{physid};
my $node = {
name => "processor$physid",
attributes => $attrs{noConfig},
value => []
};
while (my ($name, $value) = each %{$processor}) {
push(@{ $node->{value} }, { name => $name, value => $value, attributes => $attrs{config} });
}
push(@{ $detailNode->{value} }, $node);
}
return $xml;
}
sub disk {
my ($self) = @_;
my $provider = 'disk';
my %attrs = (
config => {
providedby => $provider,
datatype => "Text",
},
noConfig => {
providedby => $provider,
datatype => "None",
},
);
my $xml = {
name => $provider,
attributes => $attrs{noConfig},
value => [],
};
my @content = do {
open my $file, '<', '/proc/partitions';
<$file>;
};
splice(@content, 0, 2);
my %device;
for my $disk (@content) {
$disk =~ s/^\s+|\s+$//g;
my @fields = split(/\s+/, $disk);
splice(@fields, 0, 2);
my ($size, $label) = @fields;
if (my ($disk, $partition) = $label =~ /^(\w+?)(\d+)$/) {
my $partition = { size => $size, label => $label };
push(@{ $device{$disk}{partitions} }, $partition);
next;
}
$device{$label}{size} = $size;
}
while (my ($disk, $details) = each %device) {
my $sizeNode = { name => 'size', attributes => $attrs{config}, value => $details->{size} };
my $partitionNode = { name => 'partitions', attributes => $attrs{noConfig}, value => [] };
my $diskNode = { name => $disk, attributes => $attrs{noConfig}, value => [ $sizeNode, $partitionNode ] };
for my $partition (@{ $details->{partitions} }) {
my $partitionDetails = { name => $partition->{label}, attributes => $attrs{noConfig}, value => [] };
push(@{ $partitionDetails->{value} }, { name => 'size', attributes => $attrs{config}, value => $partition->{size} });
push(@{ $partitionNode->{value} }, $partitionDetails);
}
push(@{ $xml->{value} }, $diskNode);
}
return $xml;
}
sub raiderexport {
my ($self) = @_;
my $provider = 'raiderexport';
my %attrs = (
textConfig => {
providedby => $provider,
datatype => 'Text',
},
numConfig => {
providedby => $provider,
datatype => 'Numeric',
Exponent => '0',
Incrementing => 'N',
},
noConfig => {
providedby => $provider,
datatype => 'None',
},
);
my $xml = {
name => $provider,
attributes => $attrs{noConfig},
value => [],
};
my $content = do {
local $/;
open my $file, '<', '/var/cache/raider/info/sonar.info';
<$file>;
};
return '' unless $content;
if (my $struct = decode_json($content)) {
my $controllers = {
name => 'controllers',
attributes => $attrs{noConfig},
value => [],
};
my $physicalDisks = {
name => 'physical_disks',
attributes => $attrs{noConfig},
value => [],
};
push(@{ $xml->{value} }, $controllers);
push(@{ $xml->{value} }, $physicalDisks);
for my $controller (sort keys %{ $struct->{controllers} }) {
my $controllerNode = {
name => "controller$controller",
attributes => $attrs{noConfig},
value => [],
};
push(@{ $controllers->{value} }, $controllerNode);
for my $subNode (sort keys %{ $struct->{controllers}{$controller} }) {
my $subNodeEntry = {
name => $subNode,
attributes => $attrs{textConfig},
value => $struct->{controllers}{$controller}{$subNode},
};
push(@{ $controllerNode->{value} }, $subNodeEntry);
if ($subNode eq 'logical_disks') {
$subNodeEntry->{attributes} = $attrs{noConfig};
$subNodeEntry->{value} = [];
for my $logicalDisk (sort keys %{ $struct->{controllers}{$controller}{$subNode} }) {
my $logicalDiskNode = {
name => "logical_disk$logicalDisk",
attributes => $attrs{noConfig},
value => [],
};
push(@{ $subNodeEntry->{value} }, $logicalDiskNode);
for my $logicalDiskAttr (sort keys %{ $struct->{controllers}{$controller}{$subNode}{$logicalDisk} }) {
my $value = $struct->{controllers}{$controller}{$subNode}{$logicalDisk}{$logicalDiskAttr};
if ($logicalDiskAttr =~ /^disks|physical_disks$/) {
$value = join(' ', @{$value});
}
push(@{ $logicalDiskNode->{value} }, {
name => $logicalDiskAttr,
attributes => $attrs{textConfig},
value => $value,
});
}
}
}
}
}
for my $physicalDisk (sort keys %{ $struct->{physical_disks} }) {
my $physicalDiskNode = {
name => "physical_disk$physicalDisk",
attributes => $attrs{noConfig},
value => [],
};
push(@{ $physicalDisks->{value} }, $physicalDiskNode);
for my $physicalDiskAttr (sort keys %{ $struct->{physical_disks}{$physicalDisk} }) {
my $physicalDiskAttrNode = {
name => $physicalDiskAttr,
attributes => $attrs{textConfig},
value => $struct->{physical_disks}{$physicalDisk}{$physicalDiskAttr},
};
push(@{ $physicalDiskNode->{value} }, $physicalDiskAttrNode);
if ($physicalDiskAttr eq 'smart_attributes') {
$physicalDiskAttrNode->{attributes} = $attrs{noConfig};
$physicalDiskAttrNode->{value} = [];
for my $smartAttr (sort keys %{ $struct->{physical_disks}{$physicalDisk}{$physicalDiskAttr} }) {
my $smartAttrNode = {
name => "attribute$smartAttr",
attributes => $attrs{noConfig},
value => [],
};
push(@{ $physicalDiskAttrNode->{value} }, $smartAttrNode);
for my $smartAttrProp (sort keys %{ $struct->{physical_disks}{$physicalDisk}{$physicalDiskAttr}{$smartAttr} }) {
my $smartAttrPropNode = {
name => $smartAttrProp,
attributes => $attrs{textConfig},
value => $struct->{physical_disks}{$physicalDisk}{$physicalDiskAttr}{$smartAttr}{$smartAttrProp},
};
push(@{ $smartAttrNode->{value} }, $smartAttrPropNode);
if ($smartAttrProp =~ /^(VALUE|WORST|RAW_VALUE)$/) {
$smartAttrPropNode->{attributes} = $attrs{numConfig};
}
}
}
}
}
}
}
return $xml;
}
1;