※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

クラスターを構成する2台のsyslogファイルを比較する必要があり、2つのファイルを時間でソートして出力するrubyのプログラムを書いてみた。
なお、2台の時刻がずれていたので、片方のログにある時刻に、指定された秒数を加算して補正できるようにした。
パラメタチェックは手抜きなので、例外がスローされるにまかせています。

■ソース(mergelog.rb)
#!/usr/bin/ruby

require "optparse"
require "time"

class Log
	@@dtstart = 0	# syslogメッセージ上の日付時刻開始位置
	
	def initialize(logfile, diff = 0)
		@file = open(logfile)			# ファイルストリーム
		@diff = diff
		read
	end
	
	def read
		@str = @file.gets
		if( @str != nil )
			@dtsize = @str.index(/\d\d\:\d\d\:\d\d/) + \
				@str[/\d\d\:\d\d\:\d\d/].size - @@dtstart
			@dt = Time.parse( @str[@@dtstart,@dtsize] )
			setDiffTime if @diff != 0
		end
	end
	
	def file; return @file; end
	def str; return @str; end
	def tabstr; return " \t" + @str; end
	def dtsize; return @dtsize; end
	def dt; return @dt; end

	def close; @file.close; end

	def setDiffTime
		@dt = @dt + @diff.to_i
		@str[@@dtstart,@dtsize] = @dt.strftime("%b %d %X")
	end
end

class Logs
	def initialize( logfile1, logfile2, diff = 0 )
		@log1 = Log.new(logfile1, diff)
		@log2 = Log.new(logfile2)
		@processing = 1
	end
	
	def read( log )
		puts( @processing == 1 ? log.str : log.tabstr )
		log.read
	end

	def whichread
		while( @log1.str != nil && @log2.str != nil )
			if( @log1.dt == @log2.dt )
				@processing = 3 - @processing
				read( @processing == 1 ? @log1 : @log2 ) 
			elsif( @log1.dt < @log2.dt )
				@processing = 1
				read( @log1 )
			else
				@processing = 2
				read( @log2 )
			end
		end

		while( @log1.str != nil )
			@processing = 1
			read( @log1 )
		end
		while( @log2.str != nil )
			@processing = 2
			read( @log2 )
		end
	end

	def close
		@log1.file.close
		@log2.file.close
	end
	
end

#
# main start
#

# Option
summary = <<__EOL__

指定された2つのファイルを時刻順にマージします。
2つのファイルは時刻でソートされている必要があります。
2つのファイルに時刻ずれがある場合は、-dオプションに
指定した秒数をファイル1に足します。

Usage: #{File::basename($0)} [options]
[options]
__EOL__

OptionParam = Hash.new
OptionParam[:d] = 0
opts = OptionParser.new(banner=summary,width=25 )
opts.on("-a","--file1 Logfile1", "必須"){|file| OptionParam[:a] = file }
opts.on("-b","--file2 Logfile2", "必須"){|file| OptionParam[:b] = file }
opts.on("-d","--diff  Time(sec)", "Time of file1 add this number") \
          {|diff| OptionParam[:d] = diff }
opts.parse!(ARGV)

# logファイル処理
logs = Logs.new(OptionParam[:a],OptionParam[:b], OptionParam[:d] )
logs.whichread
logs.close

■実行
1)ヘルプ
$ mergelog.rb --help

指定された2つのファイルを時刻順にマージします。
2つのファイルは時刻でソートされている必要があります。
2つのファイルに時刻ずれがある場合は、-dオプションに
指定した秒数をファイル1に足します。

Usage: mergelog.rb [options]
[options]
   -a, --file1 Logfile1      必須
   -b, --file2 Logfile2      必須
   -d, --diff  Time(sec)     Time of file1 add this number

2)syslog1とsyslog2を指定して実行
$ mergelog.rb -a syslog -b syslog2
	Feb 17 23:56:31 test log2_0001
Feb 17 23:56:31 test log1_0001
	Feb 17 23:57:31 test log2_0002
Feb 17 23:57:31 test log1_0002
わかりづらいが、「log1_」とあるのがsyslogで、「log2_」とあるのがsyslog2の内容。
Excelに貼り付けると別の列になるように、一方のファイルログはタブを先頭にうめてある。

3)syslogの日付を1時間(3600秒)へらしてみる。
$ mergelog.rb -a syslog -b syslog2 -d -3600
Feb 17 22:56:31 test log1_0001
Feb 17 22:57:31 test log1_0002
	Feb 17 23:56:31 test log2_0001
	Feb 17 23:57:31 test log2_0002



名前:
コメント: