Created
April 10, 2025 20:56
-
-
Save xanathar/70d4e51b6e181d57a3b78770d7d498b6 to your computer and use it in GitHub Desktop.
Plot log file aggregated by time using gnuplot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Check if a file was provided | |
if [ $# -lt 1 ] || [ $# -gt 3 ]; then | |
echo "Usage: $0 <logfile> [start_time] [end_time]" | |
echo "Example: $0 logfile.log '2023-01-01 00' '2023-01-02 23'" | |
echo "Note: If start_time and end_time are not provided, they will be automatically" | |
echo " extracted from the first and last lines of the log file." | |
exit 1 | |
fi | |
LOGFILE=$1 | |
START_TIME=$2 | |
END_TIME=$3 | |
# Extract start and end times automatically if not provided | |
if [ -z "$START_TIME" ] || [ -z "$END_TIME" ]; then | |
# Extract timestamp from first line for start time | |
if [ -z "$START_TIME" ]; then | |
FIRST_LINE=$(head -n 1 "$LOGFILE") | |
if [[ $FIRST_LINE =~ ^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}):[0-9]{2} ]]; then | |
AUTO_START_TIME="${BASH_REMATCH[1]}" | |
START_TIME="$AUTO_START_TIME" | |
echo "Automatically set start time to: $START_TIME" | |
else | |
echo "Warning: Could not extract start time from first line" | |
fi | |
fi | |
# Extract timestamp from last line for end time | |
if [ -z "$END_TIME" ]; then | |
LAST_LINE=$(tail -n 1 "$LOGFILE") | |
if [[ $LAST_LINE =~ ^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}):[0-9]{2} ]]; then | |
AUTO_END_TIME="${BASH_REMATCH[1]}" | |
# If start and end times are the same, add 1 minute to end time to avoid empty range | |
if [ "$AUTO_START_TIME" = "$AUTO_END_TIME" ]; then | |
# Add one minute to the end time | |
END_TIME="$AUTO_END_TIME:59" | |
echo "Start and end times were identical. Automatically adjusted end time to: $END_TIME" | |
else | |
END_TIME="$AUTO_END_TIME" | |
echo "Automatically set end time to: $END_TIME" | |
fi | |
else | |
echo "Warning: Could not extract end time from last line" | |
fi | |
fi | |
fi | |
# Create a temporary file for the processed data | |
TEMPFILE=$(mktemp) | |
# Extract timestamps from log and count occurrences per time unit | |
# Assuming the timestamp is in the format "YYYY-MM-DD HH:MM:SS" or similar at the start of each line | |
awk '{ | |
# Extract timestamp using regex | |
# This regex looks for a pattern like "YYYY-MM-DDThh:mm:ss" at the start of the line | |
if (match($0, /^([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}):[0-9]{2}/, timestamp_parts)) { | |
# timestamp_parts[1] contains the YYYY-MM-DDThh:mm part (aggregation by minute) | |
minute_timestamp = timestamp_parts[1]; | |
# Count lines per minute | |
count[minute_timestamp]++; | |
} | |
} | |
END { | |
# Output the counts | |
for (time in count) { | |
print time, count[time]; | |
} | |
}' "$LOGFILE" | sort > "$TEMPFILE" | |
# Create a gnuplot script | |
GNUPLOT_SCRIPT=$(mktemp) | |
cat > "$GNUPLOT_SCRIPT" << EOL | |
set terminal png size 1200,800 | |
set output 'log_activity.png' | |
set title 'Log Activity Over Time' font ",12" | |
set xlabel 'Time' offset 0,-5 | |
set ylabel 'Number of Log Entries' | |
set xdata time | |
set timefmt '%Y-%m-%dT%H:%M' | |
set format x '%Y-%m-%dT%H:%M' | |
# Rotate the x-axis labels vertically to prevent overlapping | |
set xtics rotate by 90 offset 0,-5 font ",8" | |
set xtics nomirror | |
# Add more bottom margin to accommodate the vertical labels | |
set bmargin 10 | |
set grid | |
set key off | |
set style fill solid 0.5 | |
EOL | |
# Set time range for x-axis if provided | |
if [ ! -z "$START_TIME" ] && [ ! -z "$END_TIME" ]; then | |
# Add a small buffer to the range to avoid empty range errors | |
echo "set xrange [\"$START_TIME\":\"$END_TIME\"]" >> "$GNUPLOT_SCRIPT" | |
elif [ ! -z "$START_TIME" ]; then | |
echo "set xrange [\"$START_TIME\":]" >> "$GNUPLOT_SCRIPT" | |
elif [ ! -z "$END_TIME" ]; then | |
echo "set xrange [:\"$END_TIME\"]" >> "$GNUPLOT_SCRIPT" | |
else | |
# If no range was set or extracted, don't set xrange explicitly | |
echo "# No explicit xrange - using auto range" >> "$GNUPLOT_SCRIPT" | |
fi | |
# Add the plot command | |
echo "plot '$TEMPFILE' using 1:2 with boxes" >> "$GNUPLOT_SCRIPT" | |
# Run gnuplot | |
gnuplot "$GNUPLOT_SCRIPT" | |
# Clean up temporary files | |
rm "$TEMPFILE" "$GNUPLOT_SCRIPT" | |
echo "Chart has been generated as log_activity.png" | |
xdg-open log_activity.png |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment