Ruby-ログのローテーション

ログのローテーション

ログファイルの世代管理の実装例です。



#!/usr/bin/env ruby
#/usr/local/bin/ruby 

module STW
  #
  # @brief   ログ出力
  #
  class Log
    #!
    # @brief      初期処理
    # @param[in]  filename  ログ出力先ファイルパス
    #
    def initialize( filename )
      require "fileutils"

      @msg = ""
      @logfile  = filename
      @operator = "unknown user"

      # ログファイルのローテーション情報
      @lotation_size = 2000000
      @lotation_num  = 4

      # ローテーションの確認
      if( is_log_lotation() == true )
        exec_log_lotation()
      end
    end

    #!
    # @brief      ログの出力ユーザを設定する
    # @param[in]  logmsg  ログメッセージ
    #
    def set_loguser( username )
      @operator = username
    end

    #!
    # @brief      ログの出力
    # @param[in]  logmsg  ログメッセージ
    #
    def writelog( logmsg )
      @msg = "\"#{logmsg}\","
      @msg = @msg + "\"#{@operator}\","
      @msg = @msg + "\"#{Time.new}\""
      write_logfile()
    end

    #!
    # @brief      ログメッセージをバッファに保存する
    # @param[in]  logmsg  ログメッセージ
    #
    def buff_msg( logmsg )
      @msg = @msg + "#{logmsg}\n"
    end

    #!
    # @brief      バッファしたログメッセージを出力する
    #
    def write_buffmsg()
      @msg = @msg + "\"#{@operator}\"\n"
      @msg = @msg + "\"#{Time.new}\"\n"
      @msg = @msg + "---\n"
      write_logfile()
    end

    private
    #!
    # @brief      ログの出力
    #
    def write_logfile()
      fd = open( @logfile, "a" )
      fd.flock( File::LOCK_EX )
      fd.write( @msg + "\n" )
      fd.close
    end

    #!
    # @brief   ログファイルのローテーション退避を行う
    #
    def exec_log_lotation()
      # ローテーション末尾ファイルを削除する
      if( File.exist?( "#{@logfile}.#{@lotation_num}" ) ) 
        FileUtils.rm( "#{@logfile}.#{@lotation_num}" )
      end 

      # ローテーションの順番を移動する
      @lotation_num.downto(0) do |i| 
        if( File.exist?( "#{@logfile}.#{i}" ) ) 
          File.rename( "#{@logfile}.#{i}", "#{@logfile}.#{i+1}" )
        end 
      end 

      # 対象をバックアップする
      FileUtils.cp( "#{@logfile}", "#{@logfile}.0" )

      # バックアップ後にはクリアする
      File.truncate( @logfile, 0 ) 
    end

    #!
    # @brief   ログファイルのローテーションを行うか確認する
    # @return  true  ローテーションを行う
    # @return  false ローテーションを行わない
    #
    def is_log_lotation()
      # ファイルの存在確認
      return( false ) if( File.exist?( @logfile ) == false )

      # ファイルサイズの確認
      st = File::stat( @logfile )
      return( false ) if( st.size < @lotation_size )

      return( true ) 
    end
  end
end # module


関連ページ