Hello! Welcome back to our course on DevOps foundations.
In our last lesson, we built a practical and essential automation script for creating date-stamped backups. We also saw that a complete automation strategy includes logging the script's output. This raises an important question: what happens to those logs? If left unmanaged, log files from backups, web servers, applications, and system services can grow endlessly, consuming all available disk space and bringing a system to a halt.
Today, we'll tackle this problem head-on. This lesson is the perfect complement to our work on backups and monitoring, focusing on another critical aspect of automated system maintenance.
Today's Learning Outcome: By the end of this lesson, you will be able to automate log rotation for a specified application using a Bash script.
We will explore two approaches: first, by writing a simple, custom Bash script to understand the core logic, and second, by using logrotate, the powerful and industry-standard utility designed specifically for this task. This will give you both the fundamental understanding and the professional tooling needed in a real-world DevOps role.
1. What is Log Rotation?
Log rotation is the process of managing log files to prevent them from growing indefinitely. A typical rotation process involves:
- Archiving the current active log file (e.g., renaming
app.logtoapp.log.1). - Creating a new, empty log file for the application to write to (
app.log). - Optionally compressing the archived log files to save space (e.g.,
app.log.1.gz). - Deleting the oldest archived log files after a certain number of rotations to manage long-term disk usage.
This process ensures that log files remain small and manageable, making analysis easier and preventing disk space exhaustion.
The image below provides a great visual summary of this cycle.

2. The Manual Approach: A Custom Bash Script
To understand the mechanics of log rotation, let's start by writing a simple Bash script. While not as robust as standard tools, this approach directly addresses the "using a Bash script" part of our goal and reveals the underlying logic.
One common trigger for rotation is file size. The script below will check if a log file has exceeded a specific size and, if so, rename it with a timestamp.
The article 'Logging in bash scripts' provides a concise example of a size-based log rotation script. Let's study it to understand the basic implementation.
Read the section titled 'Log rotation'. Focus on the example Bash script provided. Pay attention to how it gets the file size and how it renames the log file.
Let's break down the core logic of that script:
#!/bin/bash
LOGFILE="/var/log/my-app.log"
MAX_SIZE_MB=1 # Set max size in MB
# Check if the log file exists and is a file
if [ -f "$LOGFILE" ]; then
# Get the size of the log file in megabytes
log_size_mb=$(du -m "$LOGFILE" | awk '{print $1}')
# If the log file is larger than MAX_SIZE_MB, rotate it
if [ "$log_size_mb" -gt "$MAX_SIZE_MB" ]; then
echo "Log file is larger than ${MAX_SIZE_MB}MB. Rotating."
# Move the current log to a new file with a timestamp
mv "$LOGFILE" "$LOGFILE.$(date +"%Y%m%d%H%M%S")"
# Create a new empty log file for the application to use
touch "$LOGFILE"
else
echo "Log file size is within limits."
fi
else
echo "Log file does not exist. Creating it."
touch "$LOGFILE"
fi
How it works:
du -m "$LOGFILE": Thedu(disk usage) command with the-mflag reports the file size in megabytes.awk '{print $1}': This command extracts the first column (the size number) from the output ofdu.if [ "$log_size_mb" -gt "$MAX_SIZE_MB" ]: A standard Bash conditional that checks if the log size is greater than our defined maximum.mv "$LOGFILE" "$LOGFILE.$(date ...)": If the condition is met, themvcommand renames the log file, appending a timestamp just like we did for our backups.touch "$LOGFILE": This creates a new, empty log file with the original name so the application can continue logging without interruption.
This script demonstrates the fundamental concept, but it has limitations: it doesn't compress old logs, doesn't delete the oldest archives, and requires its own cron job to run. For production systems, there's a better way.
3. The Professional Approach: Using logrotate
On virtually all Linux systems, the standard tool for managing logs is logrotate. It is a highly flexible and powerful utility that runs automatically, managing log files based on a set of declarative rules. As a DevOps engineer, logrotate will be your primary tool for this task.
Let's walk through a project to configure logrotate for a custom application.
Project 20: Automate Log Rotation with Logrotate
The article 'Project 20: Automate Log Rotation with Logrotate' is a perfect step-by-step guide for this. We will follow its structure to set up, configure, and test log rotation for a sample application.
First, read 'Step 1: What is Logrotate?', 'Step 2: Check if Logrotate is Installed', and 'Step 3: Create a Sample Log File for Testing'. Follow the commands to ensure logrotate is installed and to create a test directory and log file. This will prepare your environment for the next step.
The logrotate Configuration
Now that you have a test log file, the next step is to tell logrotate how to handle it. This is done by creating a simple configuration file. The main configuration for logrotate is /etc/logrotate.conf, but for individual applications, we add files to the /etc/logrotate.d/ directory. This keeps our system tidy and makes it easy to manage configurations for different services.
Let's examine how to write one of these configuration files.
Project 20: Automate Log Rotation with Logrotate
This is the most important part of the process. Let's study the configuration file structure and its directives.
Read 'Step 4: Write a Custom Logrotate Configuration'. Create the configuration file as instructed, but before saving, carefully review the 'Explanation' section that breaks down each directive. Understand what daily, rotate, compress, and postrotate do.
A typical logrotate configuration file for a web server log might look like this:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
Let's review the key directives:
/var/log/nginx/*.log: This defines which log files the rules apply to. Wildcards are supported.daily: Rotate logs once a day. Other options includeweekly,monthly, orsize 100M.rotate 14: Keep 14 of the most recent archived logs. Older ones will be deleted.compress: Compress the rotated log files usinggzip.notifempty: Do not rotate the log file if it is empty.create 0640 www-data adm: After rotating, create a new log file with the specified permissions (0640), owner (www-data), and group (adm).postrotate/endscript: This block contains a script to be run after the log file has been rotated. This is crucial for many applications, which need to be signaled to close their old log file handle and open the new one. For Nginx, sending theUSR1signal tells it to re-open its log files.
Test your understanding!
You need to configure log rotation for an application located at /opt/app/app.log. The requirements are:
- Rotate the log file once it reaches 50MB.
- Keep 5 old log files.
- The logs should be compressed.
What would the logrotate configuration look like?
Show answer
/opt/app/app.log {
size 50M
rotate 5
compress
missingok
notifempty
}
This configuration targets the specified file, triggers rotation based on size, defines the retention count, and enables compression, while also including good default practices like missingok and notifempty.
Testing and Automating logrotate
With your configuration file in place, the final steps are to test it and ensure it runs automatically.
Project 20: Automate Log Rotation with Logrotate
The last step is to verify our configuration and understand how the automation works.
Read through 'Step 5: Test the Logrotate Configuration' and 'Step 6: Automate Logrotate with Cron'. Follow the commands to test your configuration.
Key Commands for Testing:
- Dry Run:
sudo logrotate -d /etc/logrotate.d/your_config_file- The
-d(debug) flag makeslogrotateperform a "dry run." It will show you exactly what it would do without actually modifying any files. This is perfect for verifying your syntax and logic.
- The
- Forced Run:
sudo logrotate -f /etc/logrotate.d/your_config_file- The
-f(force) flag forceslogrotateto run, even if the conditions (likedailyorsize) haven't been met. This is useful for immediately testing that the entire process works as expected.
- The
Automation:
As the article notes, you almost never need to set up a cron job for logrotate yourself. Most Linux distributions, including Ubuntu and CentOS, ship with a pre-configured daily cron job (often located at /etc/cron.daily/logrotate) that runs logrotate on all configuration files in /etc/logrotate.d/.
By simply placing your configuration file in that directory, you have already automated the process.
Conclusion
Congratulations! You've mastered another fundamental automation task that is essential for maintaining healthy, stable systems. You now understand not only the "how" but also the "why" behind log rotation.
Key Takeaways:
- Log rotation is essential to prevent log files from consuming all disk space and to keep them manageable.
- A basic Bash script can perform simple rotation (e.g., based on size), which helps in understanding the core mechanics.
logrotateis the industry-standard tool for this job. It is powerful, flexible, and uses a declarative configuration.- To manage logs for a new application, you simply add a configuration file to
/etc/logrotate.d/. - Automation is built-in. A system cron job typically runs
logrotatedaily, so no manual scheduling is usually required.
Next Up
In this module, we've built several practical scripts for monitoring, backups, and now, log management. These projects have given you a taste of the power of Bash. To truly master automation, however, you need a deeper understanding of the scripting language itself.
In our next lesson, we will begin the next module, "Scripting and Automation with Bash," by diving into the fundamental building blocks of the language. We will formally cover control structures like if, for, and while loops, giving you the structured programming tools needed to write more complex and intelligent scripts.