Linux Memory Visualization: CLI Tools to Generate Process-wise Memory Pie Charts Without X Server


2 views

When debugging memory issues on headless servers, traditional tools like top or htop provide textual output but lack visual representation. While solutions like Munin track historical trends, we often need snapshot visualizations for immediate analysis.

The most lightweight approach converts process memory data into visual formats through these steps:


# Step 1: Get process memory data
ps -eo pid,user,%mem,command --sort=-%mem | head -n 10 > process_mem.txt

# Step 2: Convert to CSV format
awk 'NR>1 {print $1","$2","$3}' process_mem.txt > mem_data.csv

Here's a complete Python script generating a pie chart PNG:


import pandas as pd
import matplotlib.pyplot as plt

def generate_mem_chart():
    # Read process data
    df = pd.read_csv('mem_data.csv', names=['PID','User','Memory'])
    
    # Create figure without GUI backend
    plt.switch_backend('Agg')
    fig, ax = plt.subplots(figsize=(10,8))
    
    # Generate pie chart
    ax.pie(df['Memory'], 
           labels=df['User'],
           autopct='%1.1f%%',
           shadow=True)
    
    ax.set_title('Process Memory Distribution')
    plt.savefig('memory_pie.png', dpi=100)

if __name__ == "__main__":
    generate_mem_chart()

For interactive filtering, create an HTML file with Chart.js:


<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <canvas id="memChart" width="800" height="400"></canvas>
    
    <script>
        fetch('mem_data.csv')
            .then(response => response.text())
            .then(data => {
                const rows = data.trim().split('\n');
                const chartData = {
                    labels: [],
                    datasets: [{
                        data: [],
                        backgroundColor: []
                    }]
                };
                
                rows.forEach(row => {
                    const [pid, user, mem] = row.split(',');
                    chartData.labels.push(${user} (${pid}));
                    chartData.datasets[0].data.push(parseFloat(mem));
                    chartData.datasets[0].backgroundColor.push(
                        hsl(${Math.random() * 360}, 70%, 50%)
                    );
                });
                
                new Chart(document.getElementById('memChart'), {
                    type: 'pie',
                    data: chartData,
                    options: { responsive: false }
                });
            });
    </script>
</body>
</html>

For regular monitoring, consider these enhancements:

  • Add cron job to regenerate visuals periodically
  • Implement memory threshold alerts
  • Include timestamp in output filenames

When troubleshooting memory issues on headless servers, traditional tools like top or htop provide raw numbers but lack visual representation. Here's a Python solution that generates both static HTML/SVG visualizations and PNG outputs without requiring X11.

# Install required packages on Debian/Ubuntu
sudo apt-get install python3-matplotlib python3-psutil

This script creates both interactive HTML (using Plotly) and static PNG outputs:

import psutil
import matplotlib.pyplot as plt
from plotly.graph_objects import Figure, Pie
import plotly.io as pio

def generate_memory_graphs():
    processes = []
    mem_usages = []
    
    for proc in psutil.process_iter(['pid', 'name', 'memory_percent']):
        try:
            if proc.info['memory_percent'] > 0.1:  # Filter small processes
                processes.append(f"{proc.info['name']} (PID: {proc.info['pid']})")
                mem_usages.append(proc.info['memory_percent'])
        except psutil.NoSuchProcess:
            continue

    # Generate Matplotlib PNG
    plt.figure(figsize=(12, 8))
    plt.pie(mem_usages, labels=processes, autopct='%1.1f%%')
    plt.title('Process Memory Allocation')
    plt.savefig('/tmp/memory_usage.png', dpi=150, bbox_inches='tight')
    
    # Generate Plotly HTML
    fig = Figure(data=[Pie(labels=processes, values=mem_usages)])
    pio.write_html(fig, '/tmp/memory_usage.html', auto_open=False)

if __name__ == "__main__":
    generate_memory_graphs()

For environments without Python available:

#!/bin/bash
# Generate memory data file
ps -eo pid,user,%mem,command --sort=-%mem | awk 'NR<=11 && NR>1 {print $3,$4" ("$1")"}' > /tmp/mem.dat

# Create gnuplot script
cat << EOF > /tmp/mem.gnuplot
set terminal png size 800,600
set output '/tmp/memory_gnuplot.png'
set title "Process Memory Usage"
set style data histograms
set style fill solid
plot '/tmp/mem.dat' using 1:xtic(2) title "Memory %"
EOF

gnuplot /tmp/mem.gnuplot

To make the visualization accessible via web without installing a full monitoring suite:

# Simple Python HTTP server for access
python3 -m http.server 8000 --directory /tmp

Combine with cron for periodic updates:

# Add to crontab -e
*/5 * * * * /usr/bin/python3 /path/to/memory_graph.py

Extend the Python script to include process filtering by memory threshold or process name:

def filter_processes(min_mem=0.5, exclude_list=['systemd', 'sshd']):
    return [proc for proc in psutil.process_iter(['pid', 'name', 'memory_percent'])
            if proc.info['memory_percent'] > min_mem 
            and not any(exc in proc.info['name'] for exc in exclude_list)]