How to Programmatically Check Last yum Update Timestamp on Linux Servers


3 views

In enterprise server environments, maintaining patch compliance is crucial for security and stability. For systems using yum package management (RHEL, CentOS, etc.), administrators often need to verify when the last system-wide update was performed - particularly when:

  • Auditing security compliance
  • Maintaining change control procedures
  • Monitoring automated update systems

While yum doesn't provide a built-in command to query the last update timestamp, several reliable methods exist:

Method 1: Parsing yum Log Files

The most robust approach examines yum's transaction logs:

# Check current log
last_update=$(grep -i "Updated:" /var/log/yum.log | tail -1 | awk '{print $1,$2}')

# Include rotated logs if needed
if [ -z "$last_update" ]; then
    last_update=$(zgrep -h "Updated:" /var/log/yum.log* | tail -1 | awk '{print $1,$2}')
fi

echo "Last yum update: $last_update"

Method 2: Querying RPM Database

For systems with frequent package updates, this method provides more granular data:

# Get installation times of all packages, sorted
rpm -qa --last | head -n 10

Here's an enhanced version suitable for Nagios/Icinga monitoring:

#!/bin/bash

# Thresholds (days)
WARNING_DAYS=14
CRITICAL_DAYS=30

# Get last update from logs
LAST_UPDATE=$(zgrep -h "Updated:" /var/log/yum.log* | tail -1)
if [ -z "$LAST_UPDATE" ]; then
    echo "UNKNOWN: No yum updates found in logs"
    exit 3
fi

# Extract and parse date
LOG_DATE=$(echo "$LAST_UPDATE" | awk '{print $1,$2}')
EPOCH_TIME=$(date -d "$LOG_DATE" +%s 2>/dev/null)
CURRENT_EPOCH=$(date +%s)

if [ -z "$EPOCH_TIME" ]; then
    echo "UNKNOWN: Failed to parse date from logs"
    exit 3
fi

# Calculate days since last update
DAYS_ELAPSED=$(( (CURRENT_EPOCH - EPOCH_TIME) / 86400 ))

# Evaluate thresholds
if [ "$DAYS_ELAPSED" -ge "$CRITICAL_DAYS" ]; then
    echo "CRITICAL: Last yum update $DAYS_ELAPSED days ago on $LOG_DATE"
    exit 2
elif [ "$DAYS_ELAPSED" -ge "$WARNING_DAYS" ]; then
    echo "WARNING: Last yum update $DAYS_ELAPSED days ago on $LOG_DATE"
    exit 1
else
    echo "OK: Last yum update $DAYS_ELAPSED days ago on $LOG_DATE"
    exit 0
fi

For more accurate results in complex environments:

  • Combine log parsing with rpm --last data
  • Use journalctl for systems with journald: journalctl -u yum -n 20
  • Consider package-specific updates vs system-wide updates

For newer systems with yum history available:

yum history | grep -E "Update|Upgrade" | tail -n 5

In enterprise Linux environments, particularly those with staged deployment pipelines, tracking the last successful yum update operation is crucial for maintaining security compliance and operational continuity. The problem compounds when managing multiple servers across different environments (staging vs production) with varying update policies.

The most straightforward approach examines /var/log/yum.log:

# Basic timestamp extraction
LAST_UPDATE=$(grep "Updated:" /var/log/yum.log | tail -1 | awk '{print $1,$2}')
echo "Last update occurred on: $LAST_UPDATE"

However, this has several limitations:

  • Log rotation may archive older entries in yum.log.1
  • Doesn't distinguish between full system updates and single package updates
  • Date format requires additional parsing for automation

Here's a more robust implementation that handles log rotation and provides machine-readable output:

#!/bin/bash

# Check both current and rotated logs
for LOG in /var/log/yum.log /var/log/yum.log.*; do
    [ -f "$LOG" ] || continue
    
    # Extract newest timestamp matching system update pattern
    TS=$(grep -E "Updated:.*(\\$|yum)" "$LOG" | \
         tail -1 | \
         awk '{print $1" "$2" "$NF}' | \
         sed 's/:[0-9]\+$//')
    
    [ -n "$TS" ] && break
done

# Convert to epoch for monitoring systems
EPOCH=$(date -d "$TS" +%s 2>/dev/null)
if [ -n "$EPOCH" ]; then
    echo "LAST_YUM_UPDATE=$EPOCH"
else
    echo "ERROR: Unable to determine last update time"
    exit 1
fi

For systems using yum version 3.2.22+ (RHEL/CentOS 6+), the history feature provides more structured data:

# Get last update transaction ID
LAST_TID=$(yum history | awk '/Update/ {print $1}' | tail -1)

# Get detailed timestamp
yum history info "$LAST_TID" | grep -E "Begin time|Command line"

For Nagios/Icinga integration, here's a complete NRPE plugin implementation:

#!/bin/bash
WARNING_DAYS=14
CRITICAL_DAYS=30

# Get last update timestamp
LAST_UPDATE=$(grep -h "Updated:" /var/log/yum.log* | \
             sort -r | \
             head -1 | \
             awk '{print $1,$2,$3}')

# Convert to days since update
NOW_EPOCH=$(date +%s)
LAST_EPOCH=$(date -d "$LAST_UPDATE" +%s 2>/dev/null || echo 0)
DAYS_SINCE=$(( (NOW_EPOCH - LAST_EPOCH) / 86400 ))

# Evaluation logic
if [ $LAST_EPOCH -eq 0 ]; then
    echo "UNKNOWN: Could not parse last update time"
    exit 3
elif [ $DAYS_SINCE -ge $CRITICAL_DAYS ]; then
    echo "CRITICAL: Last yum update was $DAYS_SINCE days ago"
    exit 2
elif [ $DAYS_SINCE -ge $WARNING_DAYS ]; then
    echo "WARNING: Last yum update was $DAYS_SINCE days ago"
    exit 1
else
    echo "OK: Last yum update was $DAYS_SINCE days ago"
    exit 0
fi
  • Systems using DNF instead of yum will require different logging paths
  • Minimal container environments may not maintain yum logs
  • Automated patch management systems might bypass standard yum commands

For environments where log parsing isn't reliable, consider creating a marker file during your update procedures:

# In your update script:
touch /var/lib/yum/last_update.timestamp
chmod 644 /var/lib/yum/last_update.timestamp