Sys-Monitor-Lite

 view release on metacpan or  search on metacpan

lib/Sys/Monitor/Lite.pm  view on Meta::CPAN

    }

    return \@deduped;
}

sub _top_processes {
    my ($processes, $field, $n) = @_;
    return () unless $processes && @$processes && $n && $field;
    my @sorted = sort { ($b->{$field} // 0) <=> ($a->{$field} // 0) } @$processes;
    my $limit = $n < @sorted ? $n : scalar @sorted;
    return @sorted[0 .. $limit - 1];
}

sub _process_matches {
    my ($proc, $watch) = @_;
    return 0 unless $proc && $watch && @$watch;
    my $name = lc($proc->{name} // '');
    my $cmd  = lc($proc->{command} // '');
    for my $needle (@$watch) {
        return 1 if index($name, $needle) >= 0;
        return 1 if index($cmd,  $needle) >= 0;
    }
    return 0;
}

sub _df_stats {
    open my $df, '-|', 'df', '-P', '-k' or return {};
    my %stats;
    my $header = <$df>;
    while (my $line = <$df>) {
        chomp $line;
        $line =~ s/^\s+//;
        my @fields = split /\s+/, $line;
        next unless @fields >= 6;
        my ($fs, $blocks, $used, $avail, undef, $mount) = @fields[0,1,2,3,4,5];
        my $total = _maybe_number($blocks);
        my $used_bytes = _maybe_number($used);
        my $avail_bytes = _maybe_number($avail);
        next unless defined $mount && defined $total && defined $used_bytes && defined $avail_bytes;
        $stats{$mount} = {
            filesystem => $fs,
            type       => 'unknown',
            total      => $total * 1024,
            used       => $used_bytes * 1024,
            avail      => $avail_bytes * 1024,
        };
    }
    close $df;
    return \%stats;
}

sub _mounted_filesystems {
    my %seen;
    my @mounts;

    if (open my $fh, '<', '/proc/mounts') {
        while (my $line = <$fh>) {
            my ($device, $mount, $type, $opts) = (split /\s+/, $line)[0..3];
            next if $seen{$mount}++;
            next if $mount =~ m{^/(?:proc|sys|dev|run|snap)};
            next if $type =~ /^(?:proc|sysfs|tmpfs|devtmpfs|cgroup.+|rpc_pipefs|overlay)$/;
            next unless defined $mount && length $mount;

            my @options = defined $opts && length $opts ? split(/,/, $opts) : ();
            my $read_only = grep { $_ eq 'ro' } @options ? 1 : 0;

            push @mounts, {
                device    => $device,
                mount     => $mount,
                type      => $type,
                options   => \@options,
                read_only => $read_only,
            };
        }
        close $fh;
    }

    return \@mounts;
}

sub _mount_key {
    my ($path) = @_;
    return '' unless defined $path && length $path;
    my $key = $path;
    $key =~ s{^/}{root_};
    $key =~ s{[^A-Za-z0-9_.]}{_}g;
    $key =~ s{_+}{_}g;
    $key =~ s{_\z}{};
    return $key;
}

sub to_json {
    my ($data, %opts) = @_;
    my $encoder = JSON::PP->new->canonical->ascii(0);
    if ($opts{pretty}) {
        $encoder = $encoder->pretty;
    }
    return $encoder->encode($data);
}

sub to_yaml {
    my ($data) = @_;
    my $yaml = _yaml_dump($data, 0);
    $yaml .= "\n" unless $yaml =~ /\n\z/;
    return $yaml;
}

sub to_prometheus {
    my ($data, %opts) = @_;
    return '' unless defined $data;

    my $prefix = _sanitize_prefix($opts{prefix});
    my %base_labels;
    if ($opts{labels} && ref $opts{labels} eq 'HASH') {
        for my $key (sort keys %{ $opts{labels} }) {
            my $label = _label_name($key);
            next unless length $label;
            $base_labels{$label} = $opts{labels}{$key};
        }
    }



( run in 0.348 second using v1.01-cache-2.11-cpan-2398b32b56e )