アクセス ログ機能を実装する方法

download1.gif サンプル コードのダウンロード (PHPtips_AccessLog.msi, 251 KB)

※このサンプルをお使いいただくためには、Visual Studio 2005 が必要です。

Webサイトのアクセス状況をログに記録し、それを監視することは、サイトを運営する上でとても重要です。ページのアクセス数を記録することで、使用頻度の高いページや機能を知ることができます。また、アクセスのあったユーザーの IP アドレスを記録しておくことで、ユーザーによる何らかの被害を受けた場合にも、アクセスをブロックすべき IP アドレスを特定しやすいなど、セキュリティの面でも役立ちます。今回は、ASP.NET 2.0 でアクセス ログを作成する方法について紹介します。

アクセスの監視をサーバー アプリケーション全体に対して行う

PHP などのサーバーサイドスクリプトでは、サーバー アプリケーション内のアクセス ログを記録する機能を実装する場合、アクセス ログを記録するコードをそれぞれのページへ埋め込む方法を取ります。この方法では、ページ数が多いサーバー アプリケーションに実装する場合や保守面でとても手間が掛かっていました。

ASP.NET 2.0 では、Global.asax の中にアクセス情報を記録するコードを記述することで、サーバー アプリケーション内のすべてのページを監視してアクセス ログを記録することができます。

アクセス情報の記録

従来の ASP では、ServerVariables コレクションを使ってサーバーの環境変数から情報を取得していました。また、PHP でも、サーバーの環境変数($_SERVER)変数から情報を取得します。一方、ASP.NET 2.0 では、HttpRequest クラスのプロパティから参照することができます。今回は、Global.asax にアクセス ログを CSV 形式のファイルに保存するプロシージャを作成します。(リスト1)
AddAccessLog は、Url プロパティからリクエストのあった URL を、UserHostAddress プロパティからユーザーの IP アドレスを取得し、サーバーの日時と一緒に CSV 形式で保存します。

Private Sub AddAccessLog(ByVal strEvent As String)
        Dim strPath As String = Request.PhysicalApplicationPath + "AccessLog.csv"
        Dim fifCsv As System.IO.FileInfo = New System.IO.FileInfo(strPath)
        Dim smwCsv As System.IO.StreamWriter
        If fifCsv.Exists = False Then
            'ファイルが存在しない場合には新規に作成する
            smwCsv = fifCsv.CreateText()
            smwCsv.Flush()
            smwCsv.Close()
        End If
        smwCsv = fifCsv.AppendText()
        'イベント名を記録()
        smwCsv.Write(strEvent)
        smwCsv.Write(",")
        'リクエストした URL を記録
        smwCsv.Write(Request.Url.ToString)
        smwCsv.Write(",")
        '日時を記録
        smwCsv.Write(DateTime.Now.ToString)
        smwCsv.Write(",")
        'ユーザーの IP アドレスを記録
        smwCsv.Write(Request.UserHostAddress.ToString)
        smwCsv.Write(vbCrLf)
        smwCsv.Flush()
        smwCsv.Close()
    End Sub

リスト1.アクセス ログを記録する AddAccessLog プロシージャ

ログを記録するタイミング

ページ内にアクセス ログを記録するコードを埋め込んだ場合、アクセス情報が記録されるタイミングは、サーバー側で、そのコードが実行されたタイミングになります。従来の ASP では、Global.asa で Session_OnStart イベントや Session_OnEnd イベントによってサーバー アプリケーション内でセッションが開始したことや終了したことを監視できるので、セッション開始時や終了時にアクセス ログを記録することができました。しかし、セッションが確立した後に、サーバー アプリケーション内のページを移動した際にログを記録したい場合には、ページ内にアクセス ログを記録するコードを埋め込む必要がありました。
ASP.NET 2.0 では、リクエストの開始と終了に関連したイベントも監視できるため、それらのイベントを使うことで、サーバー アプリケーション内のページ移動についてもアクセス ログを記録することができます。ASP.NET 2.0 では、Global.asax でそれらのイベントを監視します。
今回は、Session_Start イベントと、BeginRequest イベントが発生したタイミングでログを記録します(図1)。Global.asax はリスト2 のようになります。

<%@ Application Language="VB" %>
<script runat="server">
    Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
        AddAccessLog("Session_Start")
    End Sub
    Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)
        AddAccessLog("BeginRequest")
    End Sub
    Private Sub AddAccessLog(ByVal strEvent As String)
        Dim strPath As String = Request.PhysicalApplicationPath + "AccessLog.csv"
        Dim fifCsv As System.IO.FileInfo = New System.IO.FileInfo(strPath)
        Dim smwCsv As System.IO.StreamWriter
        If fifCsv.Exists = False Then
            'ファイルが存在しない場合には新規に作成する
            smwCsv = fifCsv.CreateText()
            smwCsv.Flush()
            smwCsv.Close()
        End If
        smwCsv = fifCsv.AppendText()
        'イベント名を記録()
        smwCsv.Write(strEvent)
        smwCsv.Write(",")
        'リクエストした URL を記録
        smwCsv.Write(Request.Url.ToString)
        smwCsv.Write(",")
        '日時を記録
        smwCsv.Write(DateTime.Now.ToString)
        smwCsv.Write(",")
        'ユーザーの IP アドレスを記録
        smwCsv.Write(Request.UserHostAddress.ToString)
        smwCsv.Write(vbCrLf)
        smwCsv.Flush()
        smwCsv.Close()
    End Sub
</script>

リスト2.アクセス ログ機能を実装した Global.asax

Cc719196.AccessLog_fig01(ja-jp,MSDN.10).gif

図 1 AccessLog.csv