System Administration and DevOps

Other tools: Rex (Perl-based deployment/configuration management, like Ansible), Sys::Hostname, Sys::Syslog (core), Proc::ProcessTable, Filesys::Df, Linux::Inotify2, Unix::Passwd, Nagios/Icinga plugins (Monitoring::Plugin), Log::Log4perl / Log::Any / Log::Dispatch (logging), Config::General, Email::Stuffer (alerts).

Windows administration: Win32::OLE (WMI, Office automation), Win32::Service, Win32::TieRegistry, Win32::Process.

#!/usr/bin/env perl
# Disk usage report with alerts
use v5.36;
my $threshold = 80;
for (qx(df -hP)) {
    next if /^Filesystem/;                           # skip the header line
    my ($fs, $size, $used, $avail, $pct, $mount) = split;
    $pct =~ tr/%//d;
    printf "%-30s %3d%% %s\n", $mount, $pct, $pct >= $threshold ? '  <-- WARNING' : '';
}
# Rotate and compress old logs
use v5.36;
use File::Find;
use IO::Compress::Gzip qw(gzip $GzipError);
find(sub {
    return unless -f && /\.log$/ && -M _ > 7;        # older than 7 days
    gzip $_ => "$_.gz" or die "gzip failed: $GzipError";
    unlink $_;
}, '/var/log/myapp');
# Remote commands over SSH on many hosts in parallel
use Net::OpenSSH;
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new(10);
for my $host (qw(web1 web2 db1)) {
    $pm->start and next;
    my $ssh = Net::OpenSSH->new($host, timeout => 10);
    if ($ssh->error) { warn "$host: ", $ssh->error, "\n"; $pm->finish(1) }
    my $uptime = $ssh->capture('uptime');
    print "$host: $uptime";
    $pm->finish(0);
}
$pm->wait_all_children;