How to send system metrics to a log file in Perl?
Question
How to send system metrics to a log file in Perl?
How to Send System Metrics to a Log File in Perl
Collecting system metrics and logging them to a file is a common task for system administrators and developers monitoring server health or debugging performance issues. In Perl, you can easily gather key system statistics and output them in a structured, readable form to a log file.
This answer covers:
- How to extract basic system information like CPU load, memory usage, and uptime
- Best practices for logging data with timestamps
- Perl-specific tips such as file handling, TMTOWTDI ("There's more than one way to do it"), and context considerations
- A runnable code example for Unix-like systems using /proc and standard command output
Gathering System Metrics in Perl
On Unix and Linux systems, some of the easiest sources for metrics are:
/proc/loadavgfor load averages/proc/meminfofor memory statistics- the
uptimecommand for system uptime dateorlocaltimefor timestamps
Perl’s ability to open and read text files line-by-line makes it straightforward to parse these resources. Using backticks or qx(), you can capture command output, but reading files directly is often faster and cleaner.
Logging with Timestamps
It is important to prefix each log entry with a timestamp, ideally in ISO 8601 format (e.g., 2024-04-27T13:45:00) for easy sorting and parsing by log monitoring tools.
Key Perl Concepts Relevant Here
- Sigils: Scalars like
$loadavghold string or numeric data. Arrays@datahold multiple lines or elements. - Context: When reading from files or running commands, context (scalar vs list) affects behavior. e.g.,
my @lines = <FILE>;reads all lines into an array. - TMTOWTDI: Perl permits multiple ways to read system metrics—by external commands, modules, or file parsing.
Common Pitfalls
- Be careful to open files with proper error checking to avoid silent failures.
- File formats like
/proc/meminfocan change slightly between kernel versions, so code may need adjustments. - Running external commands like
uptimeassumes they exist inPATH. - Ensure filehandles are closed properly or use lexical filehandles for automatic scope closing.
Runnable Example: Logging Basic System Metrics
This script reads system load averages, memory usage, and uptime, then appends a timestamped log entry to system_metrics.log in the current directory. It demonstrates Perl file IO, parsing, and basic formatting.
#!/usr/bin/perl
use strict;
use warnings;
# Log file path
my $log_file = "system_metrics.log";
# Get timestamp in ISO 8601 format
my ($sec,$min,$hour,$mday,$mon,$year) = localtime();
$year += 1900;
$mon += 1;
my $timestamp = sprintf("%04d-%02d-%02dT%02d:%02d:%02d",
$year, $mon, $mday, $hour, $min, $sec);
# Read load averages from /proc/loadavg
my $loadavg = "";
if (open my $fh, '<', '/proc/loadavg') {
$loadavg = <$fh>;
chomp $loadavg;
close $fh;
} else {
$loadavg = "N/A";
}
# Read total and free memory from /proc/meminfo
my ($mem_total, $mem_free) = ("N/A", "N/A");
if (open my $meminfo, '<', '/proc/meminfo') {
while (<$meminfo>) {
if (/^MemTotal:\s+(\d+)\skB/) { $mem_total = $1; }
if (/^MemFree:\s+(\d+)\skB/) { $mem_free = $1; }
last if $mem_total ne "N/A" && $mem_free ne "N/A";
}
close $meminfo;
}
# Get uptime from `uptime` command (fallback if needed)
my $uptime = "";
my $uptime_out = qx{uptime};
if ($? == 0) {
$uptime = $uptime_out;
$uptime =~ s/^\s+|\s+$//g; # trim whitespace
} else {
$uptime = "N/A";
}
# Format log entry
my $log_entry = sprintf(
"[%s] LoadAverage: %s | MemTotal: %s kB | MemFree: %s kB | Uptime: %s\n",
$timestamp, $loadavg, $mem_total, $mem_free, $uptime
);
# Append to log file
open my $logfh, '>>', $log_file or die "Cannot open $log_file: $!";
print $logfh $log_entry;
close $logfh;
# Print confirmation to STDOUT
print "Logged system metrics at $timestamp\n";
Explanation
- The script uses
localtime()to get the current datetime and formats it as ISO 8601. /proc/loadavgreturns the system load average; reading the first line suffices./proc/meminfois parsed for total and free memory in kilobytes.- The output of
uptimeprovides a human-readable system uptime and load info. - The log entry gets appended to a file with a newline termination.
- Finally, a confirmation message prints out the timestamp that was logged.
Extending and Customizing
You can extend this basic approach by:
- Collecting additional metrics like disk usage (
df), network stats, or process counts. - Using modules like
Sys::HostnameorTime::HiRes(core modules on modern Perl) for enhanced logging. - Scheduling the script periodically using cron for continuous monitoring.
- Implementing JSON or CSV output for easier integration into monitoring dashboards.
This approach works on Perl 5.10+ and does not require any external modules beyond core. It showcases Perl’s strength in text parsing and file handling, perfectly suited for sysadmin tasks.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 21ms
Logged system metrics at 2025-12-30T13:02:25
(empty)