Plotting for write read time and avail logs.
This commit is contained in:
92
plot_alsa_status.py
Normal file
92
plot_alsa_status.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Parse ALSA status log file and plot avail value over time."""
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
TIMESTAMP_RE = re.compile(r"^===== (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+) =====")
|
||||
AVAIL_RE = re.compile(r"^avail\s*:\s*(\d+)")
|
||||
|
||||
|
||||
def parse_log(log_path):
|
||||
timestamps = []
|
||||
avail_values = []
|
||||
|
||||
with open(log_path, "r") as f:
|
||||
current_timestamp = None
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
|
||||
# Check for timestamp line
|
||||
ts_match = TIMESTAMP_RE.match(line)
|
||||
if ts_match:
|
||||
current_timestamp = datetime.strptime(ts_match.group(1), "%Y-%m-%d %H:%M:%S.%f")
|
||||
continue
|
||||
|
||||
# Check for avail line (only if we have a timestamp)
|
||||
if current_timestamp:
|
||||
avail_match = AVAIL_RE.match(line)
|
||||
if avail_match:
|
||||
timestamps.append(current_timestamp)
|
||||
avail_values.append(int(avail_match.group(1)))
|
||||
current_timestamp = None # Reset until next timestamp
|
||||
|
||||
if not timestamps:
|
||||
print("No valid timestamp/avail pairs found in the log file.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Convert to relative seconds from first timestamp
|
||||
t0 = timestamps[0]
|
||||
seconds = [(t - t0).total_seconds() for t in timestamps]
|
||||
return seconds, avail_values
|
||||
|
||||
|
||||
def plot(seconds, avail_values, out_path):
|
||||
plt.figure(figsize=(12, 6))
|
||||
plt.plot(seconds, avail_values, label="avail", linewidth=1, alpha=0.7)
|
||||
|
||||
# Add moving average (windowed mean)
|
||||
if len(avail_values) >= 10: # Only if we have enough data points
|
||||
window_size = min(50, len(avail_values) // 10) # Adaptive window size
|
||||
import numpy as np
|
||||
moving_avg = np.convolve(avail_values, np.ones(window_size)/window_size, mode='valid')
|
||||
# Adjust timestamps for the moving average (they align with window centers)
|
||||
ma_seconds = seconds[window_size-1:]
|
||||
plt.plot(ma_seconds, moving_avg, label=f"moving mean (window={window_size})", linewidth=2)
|
||||
|
||||
plt.xlabel("Time (s)")
|
||||
plt.ylabel("Available samples")
|
||||
plt.title("ALSA Available Samples Over Time")
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.tight_layout()
|
||||
plt.savefig(out_path, dpi=150)
|
||||
print(f"Plot saved to {out_path}")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {sys.argv[0]} <path_to_alsa_status_log>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
log_path = sys.argv[1]
|
||||
if not os.path.isfile(log_path):
|
||||
print(f"File not found: {log_path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
seconds, avail_values = parse_log(log_path)
|
||||
|
||||
log_dir = os.path.dirname(os.path.abspath(log_path))
|
||||
log_base = os.path.splitext(os.path.basename(log_path))[0]
|
||||
out_path = os.path.join(log_dir, f"{log_base}_avail_plot.png")
|
||||
|
||||
plot(seconds, avail_values, out_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user