Анализ журнала IIS — как получить информацию о реферере

Согласно этой статье MSDN:

W3C Extended Формат файла журнала (IIS 6.0)

В нем говорится, что cs(Referrer) содержит информацию REFERER, которую можно прочитать из файлов журнала IIS.

Я пытаюсь отобразить информацию журнала с помощью элемента управления ASP.NET Repeater:

<asp:Repeater ID="rptlIISLogEntries" runat="server">
...
...
    <ItemTemplate>
        <tr>
            <td><%# Eval("time")%></td>
            <td><%# Eval("cs(Referrer)")%></td>
        </tr>
    </ItemTemplate>
</asp:Repeater>

Строка с Eval("cs(Referrer)" вызывает исключение:

DataBinding:'System.Data.DataRowView' does not contain a property with the name 'cs'.

У меня вопрос, как отобразить информацию REFERER в ретрансляторе?

Код для анализа файла журнала и привязки его к повторителю выглядит следующим образом:

string theDate =txtDate.Text;
        string FILE_NAME = @"\\" +txtMachine.Text +
           @"\C$\WINNT\System32\LogFiles\" +  
          drpSiteBox.SelectedItem.Text + @"\ex" + theDate + ".log";
        FileStream fs = new FileStream(FILE_NAME, FileMode.Open,
                             FileAccess.Read,FileShare.ReadWrite);
        StreamReader sr = new StreamReader(fs); 
        string strResult = sr.ReadToEnd();
        sr.Close();
        fs.Close();
        sr=null;
        fs=null;

        string[] arLogLines = strResult.Split(Convert.ToChar("\n"));
        dt = new DataTable("log");
        string revisedColmNames=arLogLines[3].Replace("#Fields: ","");
        string[] arColm=revisedColmNames.Split(Convert.ToChar(" "));
for(int j=0;j<arColm.Length;j++)
{   
    dt.Columns.Add(arColm[j]);
    Debug.WriteLine(arColm[j]);
}
for (i =arLogLines.Length-1; i>3;i--)
{  
    // need this because some logs get additional data appended 
    // aren't unhandled exceptions great? The CLR just loves 'em...
    try
    {
        dt.Rows.Add(arLogLines[i].Split(Convert.ToChar(" ")));
    }
    catch {}

}
DataGrid1.DataSource=dt;
DataGrid1.DataBind();

Примечание: это тот же код, что и в http://www.eggheadcafe.com/articles/20021203.asp


person balalakshmi    schedule 15.03.2010    source источник
comment
Вы регистрируете эту информацию? Как вы его регистрируете и как вы его извлекаете?   -  person Oded    schedule 15.03.2010
comment
Я регистрирую запросы, установив флажок «Включить ведение журнала» в консоли inetmgr, флажок «Расширенные свойства» также установлен. Для извлечения я использую Filestream для анализа файла журнала, а затем отображаю его с помощью повторителя asp.net.   -  person balalakshmi    schedule 15.03.2010


Ответы (1)


Проблема здесь связана с тем, как средство связывания данных работает с таблицей данных и обрабатывает имена столбцов/свойств. Eval использует отражение, и символы скобок в именах столбцов приводят к сбою (мне нужно снова вспомнить, как все это работает, это было давно).

Просто приведите базовый Container.DataItem к тому типу, которым он является (DataRowView), затем выберите столбец:

<%# ((System.Data.DataRowView)Container.DataItem)["cs(Referer)"]%>

Это также быстрее, потому что медленное отражение не используется.

Также я заметил, что вы неправильно написали «Referer» (у вас две буквы «r»), так что следите и за этим.

Чтобы заставить это работать, используя вместо этого Eval(), вам нужно проделать немного больше работы. Измените это:

for(int j=0;j<arColm.Length;j++)
{   
    dt.Columns.Add(arColm[j]);
    Debug.WriteLine(arColm[j]);
}

К этому:

for (int j = 0; j < arColm.Length; j++)
{
    string colName = arColm[j].Replace("(", "_").Replace(")", "");
    dt.Columns.Add(colName);
    Debug.WriteLine(colName);
}

В выражении связывателя данных Eval измените любой столбец с круглыми скобками в имени с:

Eval("cs(Referer)")

to:

Eval("cs_Referer")

Но я бы выбрал первый способ, он менее навязчив и намного быстрее.

person Kev    schedule 16.03.2010
comment
Да, пробовал. Это работало в локальной среде (где у меня есть права на установку logparser), но не работало на сервере развертывания, где у меня нет прав на установку Logparser. - person balalakshmi; 16.03.2010
comment
@balalakshmi - ах, хорошо, в этом случае вам нужно показать нам свой скрипт, который открывает и читает файлы журналов, и как вы привязываете эти данные к элементу управления Repeater. - person Kev; 16.03.2010
comment
@Kev Я попробовал решение ‹%# ((System.Data.DataRowView)Container.DataItem)[cs(Referer)]%›, оно работает нормально. Спасибо, что продолжаете работать в этой теме, чтобы помочь решить мои проблемы. - person balalakshmi; 18.03.2010
comment
На самом деле он правильно написал: Referrer[1]. Referer — это не слово в английском языке, но именно так оно пишется (ошибочно) в спецификациях HTTP[2]. Согласно документации MSDN, он хочет, чтобы здесь было правильное написание, как в cs(Referrer)[3]. Ничто так не запутает нас на следующие 20 лет, как небольшая орфографическая ошибка в спецификации... :-) [1]: merriam-webster.com/dictionary/referrer [2]: en .wikipedia.org/wiki/Referer [3]: microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/ - person Josh; 12.02.2013
comment
@JoshuaBeall - в контексте ответа и в отношении HTTP это написано неправильно. Я тоже прочитал спецификацию и прекрасно знаю, что REFERER — это опечатка, которая будет преследовать нас до скончания века :) - person Kev; 13.02.2013