at_yasu's blog

ロード的なことを

Log rotation

今まで使ってたShellスクリプトが、個人的に使いにくくなったので、ログのロテーションスクリプトを組みました。

**2008/11/07 14:00 更新

-pオプションの必須条件を廃止。
よくよく考えれば、ファイルのロテーションに使えるジャマイカと気づいて、-pを消しました。ここまできたら、apache_logってのも消したいけどご愛嬌で…
-qオプションの動作
-qオプションを動作するようにした。付けない場合、冗長に実行状況を流す。


使い方
コマンド:apache_log_rotation.py [-d] [-q] [-c compless_cmd] [-p apache_start_program] [base_path] file1 [file2...]

-q
静かになる。ただ、大して意味がありません:-p
-d
デバッグフラグ。だらだら冗長になり、かつロテーションを行いません。
-p
Apacheスタートプログラムまでのパスを指定して下さい。ロテーションを行う前にstopを、実行後にはstartを呼び出します。
-c
圧縮コマンドを指定して下さい。現在使えるのは、[gzip,bzip2]のみです。
[base_path]
ログがあるディレクトリまでを指定します。これが無い場合、ファイルパスを見に行きます。例を見て下さい。
file[1..]
ロテーションするログファイル名を指定して下さい。[base_directory_path]を指定している場合、そのディレクトリーからのfileを探します。無い場合は、fileを探します。優先順位として、file が存在すれば file をロテーションし、無い場合は「base_directory_path/file」を見てロテーションします。例を見て下さい。

Example: apache_log_rotation.py -q -p /usr/local/etc/rc.d/apache22 /home/www/log/ access_log error_log
Same as: apache_log_rotation.py -q -p /usr/local/etc/rc.d/apache22 /home/www/log/access_log /home/www/log/error_log


以下スクリプト

#!/usr/bin/env python2.5
#
# $Id: apache_log_rotation.py 45 2008-11-07 05:32:48Z yasui $

import getopt
import sys
import os
import dircache
import re

_REV = "$Id: apache_log_rotation.py 45 2008-11-07 05:32:48Z yasui $"
_QUIET_OPT = False
_DEBUG_OPT= False
_AP_OPT   = ''
_COMPLESS_CMD = 'gzip'
_COMPLESS_SUPPORTS = ['gzip','bzip2']

os.environ['PATH'] = "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"

def turn (file, basepath):
	# File path check
	_file = ''
	if os.path.exists(file):
		_file = os.path.basename(os.path.abspath(file))
		_path = os.path.dirname(os.path.abspath(file))
	else :
		_file = file
		_path = os.path.abspath(basepath or '/')

	if _DEBUG_OPT or not _QUIET_OPT:
		print "_path: %s\n_file: %s\n" % (_path, _file)

	if os.path.exists(_file):
		_file = os.path.basename(_file)
		_path = os.path.dirname(_file)
	else :
		if not os.path.exists(_path + '/' + _file) :
			print "Error: not found the %s" % (_file)
			return False

	# turnning
	fre = re.compile('^' + _file + r"\.\d+")
	get_files = []
	try:
		get_files = [e for e in dircache.listdir(_path) if fre.match(e)]
		get_files.sort()
	except:
		print "Except error"
		return False
	
	if _DEBUG_OPT or not _QUIET_OPT:
		print "The %s were old backup files count : %d. " % (_file ,len(get_files))
	
	# Turnning to _file
	new_file = "%s.%d" % (_file, len(get_files))
	if _DEBUG_OPT or not _QUIET_OPT:
		print "EXEC:: Rename %s %s" % (_path+'/'+_file,
			('%s/%s' % (_path, new_file)))

	if not _DEBUG_OPT:
		os.rename(_path+'/'+_file,
			("%s/%s" % ( _path , new_file)))
	
	# gzip compless
	if _DEBUG_OPT or not _QUIET_OPT:
		print ("EXEC:: %s %s\n"   % (_COMPLESS_CMD, "%s/%s" % (_path, new_file)))

	if not _DEBUG_OPT :
		os.system("%s %s" % (_COMPLESS_CMD, "%s/%s" % (_path, new_file)))

	return True

if __name__ == '__main__':
	files = [ ]
	basepath = ''
	usage = """usage: %s [dqh] [-c compless_cmd] [-p apache_start_program] [base_path] file1 [file2...]
    -h show this.
    -q quiet. default is False. I'll verbose if not use this.
    -d debug. Debug flag. The debug mode is not running the system command and get of backup.
    -p Apache Start program path. I'll be start/stop call for.
    -c Compless command name. command are %s. default gzip.

Example: %s -q -p /usr/local/etc/rc.d/apache22 /home/www/log/ access_log error_log
same as: %s -q -p /usr/local/etc/rc.d/apache22 /home/www/log/access_log /home/www/log/error_log

    Version: %s
""" % (sys.argv[0], _COMPLESS_SUPPORTS, sys.argv[0], sys.argv[0], _REV)
	
	optlist,filelist = getopt.getopt(sys.argv[1:],'hqdp:c:')
	if not filelist:
		print usage
		sys.exit(1)

	if len(filelist) >= 1:
		if os.path.isdir(filelist[0]):
			(basepath,files) = (filelist[0], filelist[1:])
		else :
			files = filelist
	else :
		print "Option is very short!!"
		print usage
		sys.exit(1)

	for opt,optarg in optlist:
		if opt == '-q':
			_QUIET_OPT=True
		elif opt == '-d':
			_DEBUG_OPT=True
		elif opt == '-p':
			if not os.path.exists(optarg):
				print "Error: not found Apache program path %s" %(optarg)
				print usage
				sys.exit(1)
			_AP_OPT = os.path.abspath(optarg)
		elif opt == '-c':
			if [e for e in _COMPLESS_SUPPORTS if e == optarg]:
				_COMPLESS_CMD = optarg
			else :
				print "sorry %s is not support" % (optarg)
				print usage
				sys.exit(1)
		elif opt == '-h':
			print usage
			sys.exit(0)
		else :
			print "unknown option: %s" % (opt)
			print usage
			sys.exit(1)
	
	if _DEBUG_OPT:
		print "Options:\n\toptlist:%s\n\tfilelist:%s\n\tfiles:%s\n" % (optlist, filelist, files)
	
	# dorun

	if _AP_OPT and not _DEBUG_OPT:
		os.system("%s stop" % (_AP_OPT))
	
	for file in files:
		if _DEBUG_OPT or not _QUIET_OPT:
			print "file:%s\nbasepath: %s" % (file,basepath)
		turn(file, basepath)
	
	if _AP_OPT and not _DEBUG_OPT:
		os.system("%s start" % (_AP_OPT))