Rotating backups with Ruby

Today I’ve made some simple scripts to get my backups update. Two entries in our crontab will make the rest of work for us.

The first one gets a backup of our database, the second rotates the files. I also add support to Syslog, because I would like to know if my script worked out.

#!/bin/bash
DATE=$(date +%Y-%m-%d)
mysqldump -h host userdb  database  --password=1234 | gzip > \
${HOME}/path/files/file-${DATE}.gz  

Crontab

Let’s add some entries to our crontab: user@home:~> crontab -e As far as I concern I would review the entries, it’s pretty easy to make some mistakes while we’re writing, besides I guess it’s a best practice. user@home:~> crontab -l The above command will show our entries.

# m h  dom mon dow   command
HOME=/path/user/home
PATH=PATH:/path/to/ruby

0 00 * * * ${HOME}/scripts/backup_db_blog.sh
0 00 * * * ${HOME}/scripts/rotatedb.rb

It’s a MUST to leave an empty line at the end of the cron, otherwise the cron will not run. There is another thing to take into account, PATHS. Don’t forget to set them.

Syslog

Due to I wanted support Syslog, I had to set it up correctly in my /etc/syslog.conf local7.* /var/log/backups.log Aside to create the above file, you must reload syslog daemon. Afterwards, I wanted to know if that configuration would work. There is a command that will help you:

user@home:~> logger -p local7.debug "Sending a message to debug"
user@home:~> more /var/log/backups.log
Aug  6 20:31:22 home user: Sending a message to debug

The first argument local7 is the Syslog’s FACILITY and the other one is the PRIORITY. You must adapt to your own script.
Here is the script to rotate. After then days, will remove only the four oldest backups.

#!/usr/bin/env ruby
%w(syslog).each {|c| require c }

BACKUP='/path/to/backup/directory'

module SyslogMsg
  Syslog.open("rotatedb", Syslog::LOG_PID  \
             | Syslog::LOG_CONS ,  Syslog::LOG_LOCAL7 )
  def send(msg="Message sent")
    Syslog.log(Syslog::LOG_DEBUG, msg)
  end
end

include SyslogMsg
files = []

Dir.entries(BACKUP).each do |e|
  if e !~ /^\./
    files << e
  end
end
files.sort!

if files.length > 10
  0.upto(4) do |index|
    File.delete( BACKUP + "/" + files[index] )
  end
  SyslogMsg::send("Backups for mysql rotated.")
end

Finally, if you get some troubles, review the above steps, check that you have the right permissions and you have reloaded your syslog configuration. If you try the logger command and you see the message you have just sent, everything should work out.