module Flydata # Directory structure # log_dir # - log_path # + .flydata # + [log_file_name] # + trash <- temprary directory # - [log_archived_files] # + backup <- backup archive files when initialize # - [log_archived_files] class LogMonitor FLYDATA_DIR = '.flydata' TRASH_DIR = 'trash' BACKUP_DIR = 'backup' DEFAULT_DAYS_TO_TRASH = 7 #days DEFAULT_DAYS_TO_DELETE = DEFAULT_DAYS_TO_TRASH + 7 #days def initialize(log_path, options={}) # check arguments raise "Cannot access to log path... #{log_path}" unless File.exist?(log_path) @log_path = log_path @options = options @days_to_trash = @options[:days_to_trash] ? @options[:days_to_trash] : DEFAULT_DAYS_TO_TRASH @days_to_delete = @options[:days_to_delete] ? @options[:days_to_delete] : DEFAULT_DAYS_TO_DELETE @setup_flag = false # initialize paths @flydata_path = File.join(File.dirname(@log_path), FLYDATA_DIR, File.basename(@log_path)) @backup_path = File.join(@flydata_path, BACKUP_DIR) @trash_path = File.join(@flydata_path, TRASH_DIR) end def setup # create directories FileUtils.mkdir_p(@flydata_path) FileUtils.mkdir_p(@backup_path) # backup_files to avoid to delete non-uploaded files backup_files @setup_flag = true self end def rotate check_setup_done # move files to trash trash_files # delete trashed files delete_files end private def check_setup_done raise "Setup hasn't been done, yet." unless @setup_flag end def archived_files Dir::glob("#{@log_path}?*") end def trashed_files Dir::glob("#{File.join(@trash_path, File.basename(@log_path))}?*") end def backup_files # use trash dir as checkpoint to backup initial archive files unless File.exist?(@trash_path) archived_files.each {|f| puts "buckup file: #{f} -> #{@backup_path}" FileUtils.mv(f, @backup_path) } FileUtils.mkdir_p(@trash_path) end end def trash_files archived_files.each {|f| # check date and trash if @days_to_trash.days.ago > File.stat(f).mtime to_path = File.join(@trash_path, File.basename(f)) to_path = "#{to_path}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" if File.exist?(to_path) puts "trash file: #{f} -> #{to_path}" FileUtils.mv(f, File.join(@trash_path, File.basename(f))) end } end def delete_files trashed_files.each {|f| if @days_to_delete.days.ago > File.stat(f).mtime file_path = File.join(@trash_path, File.basename(f)) puts "delete file: #{file_path}" FileUtils.rm(file_path) end } end end end