Apacheアクセスログと私(バグ取り)

今日はバグ取り等々をやることにする.

まず,エラー表示部.

エラー表示と言いつつ,robots.txtとかfavicon.icoへのアクセスを表示もすることにしたのだが,「エラーログの保持」→「エラーデータのあるステータスコードを見出しとして出力」→「エラーログの表示(ただし,robots.txtなどの場合は出力せず)」という流れにしていたため,「404 Not Found」と見出しを書いたあと,robots.txtとfavicon.icoしかエラーがない場合,見出しだけ出ているというお間抜けな状態だった.

考えてみれば,処理しないなら,そもそもエラーログを保持する必要もない.だから,リクエストファイルによる場合分けは先にしてしまうことにする.

それから,ハッシュのハッシュにしときながら,2つめのハッシュのキーは1, 2, 3...でしかなく,どう考えても,Arrayでこと足りるなと考えるに,難しく考えすぎたかと思い直し,コードを書き換えてみた.

#エラーログ表示関数
def errorlog_view(file)
  #エラー行を保持するためのハッシュ
  error = Hash.new
  #エラーを表示するかどうかのフラグ.(status => 1 or 0)の形になる.
  flg_error_view = Hash.new(0)
  # /robots.txtを探しに来た回数を入れるハッシュ
  count_robot = Hash.new(0)
  # /favicon.icoを探しに来た回数を入れるハッシュ
  count_fav = Hash.new(0)

  header_out("エラーログ") #ヘッダ表示
  logfile = open(file)
  while logline = logfile.gets
    line = Accesslog.new(logline)
    #アクセスされたファイルによって処理を分ける
    req_file = line.requestURI
    ig_error = Regexp.new("^" + IGNORE_ERROR)
    case req_file
      when "/robots.txt"
        count_robot[line.user_agent] += 1
        next
      when "/favicon.ico"
        count_fav[line.user_agent] += 1
        next
      when ig_error #無視ファイルは何もしない
        next
    end
    status = line.status
    if /^[4|5]/ =~ status #ステータスコード400台と500台だけ処理
      #必要行lineをerror[status]に入れていく.
      #errorはハッシュで,{Key => Array}.
      unless error.key?(status)
        error[status] = Array.new
      end
      #ステータスエラーの行を保持
      error[status] << line
    end
  end
  #得られた行を並べ替えて表示
  error.sort.each{|status, value|
    print "<h3> " + status + " " + STATUS[status] +"</h3> \n"
    print "<ol> \n"
    value.each{|line|
      print "<li> <dl class=\"log\"> \n"
      print "<dt> Access URI</dt> <dd> #{line.requestURI}</dd> \n"
      print "<dt> Datetime</dt> <dd> #{line.year}年#{line.month}月#{line.day}日"
      print "#{line.hour}時#{line.minute}分#{line.second}秒</dd> \n"
      print "<dt> IP Address</dt> <dd> #{line.ip}</dd> \n"
      print "<dt> Referer</dt> <dd> "
      case line.referer
        when "-"
          print "(ダイレクトアクセス)</dd> \n"
        else
          print "<a href=\"#{line.referer}\"> #{line.referer_unencode}</a> </dd> \n"
      end
      print "<dt> User Agent</dt> <dd> #{line.user_agent}</dd> \n"
      print "</dl> <hr> \n"
    }
    print "</ol> \n"
  }
  #ロボットのアクセス回数を表示
  print "<h3> robots.txtへのアクセス</h3> \n"
  print "<ul> \n"
  count_robot.each{|crawler,count|
    print "<li> #{count}回:#{crawler}</li> \n"
  }
  print "</ul> \n"
  #お気に入りアイコンへのアクセス回数を表示
  print "<h3> favicon.icoへのアクセス</h3> \n"
  print "<ul> \n"
  count_fav.each{|ua,count|
    print "<li> #{count}回:#{ua}</li> \n"
  }
  print "</ul> \n"

  footer_out() #フッタ表示
end

それから,生ログ表示部を作ったときに,「UTF-8を直せない」と言っていたのだが,uconvというものを知ったので,使ってみた.

RAAのuconvのところから,uconv-0.4.12.tar.gzをダウンロードし,展開した上で,すべてサーバー上の同じディレクトリにアップロードする.

それから,サーバーにシェルログインして,uconvのファイルを入れたディレクトリに移動.

ruby extconf.rb

と打つと,Makefileができたよ~というメッセージが出るので,おもむろに

make

と打つと,めでたくuconv.soというファイルができあがった.

このファイルを,cgiスクリプトを置いているディレクトリに放り込み,require "uconv"!

でもって,文字コード変換をやっているreferer_unencodeを次のように書き換えた.

def referer_unencode #リファラーを返す(アンエンコード済)
  ref = CGI.unescape(@all[10])
  case NKF.guess(ref)
    when 0
      chr_in = "-J"
    when 1
      chr_in = "-S"
    when 2
      chr_in = "-E"
    when 3
      begin
        return Uconv.u8toeuc(ref) + NKF.guess(ref).to_s
      rescue
          return NKF.nkf("-e", ref)
      end
  end
  return NKF.nkf("-e" + chr_in, ref)
end

出力結果(検索文字列を含む物以外は,ばっさり削除)

......ギース様,大人気?――じゃなくて.

かなり変換できるようになったなぁ.(まんぞく,まんぞく)

日時: 2004年10月20日 | PC/Web > Ruby |

コメントを投稿

(空欄でもかまいません)

(メールアドレスは管理人に通知されますが,Web上には表示されません)

Powered by Movable Type