Регистрация данных в Trace.axd в текстовом / XML-файле - PullRequest
3 голосов
/ 19 января 2011

Пытаясь отследить проблему с производительностью, которая возникает только в нашей производственной среде, мы включили трассировку в приложении, чтобы увидеть вызовы методов и время загрузки страницы.

Это работает хорошо, и есть многоинформации, которая помогает отследить проблемы.Однако единственный способ просмотреть эту информацию - перейти к Trace.axd, а затем просмотреть каждый запрос в отдельности.

Таким же образом можно только отслеживать первые X запросов, и X имеет максимальный лимитиз 10000

1006 * Есть ли способ направить эту информацию трассировки в файл или базу данных?Я считаю, что это можно сделать с помощью System.Diagnostics, однако мне не очень повезло.

Я включил трассировку, используя

<trace enabled="true" writeToDiagnosticsTrace="true" />

Я пытался использовать XmlWriterTraceListener, используя

  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add
          name="XmlWriterTraceListener"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData="c:\trace.xml"
          />
      </listeners>
    </trace>
  </system.diagnostics>

В результате получается xml-файл, содержащий метки времени и данные для таких элементов трассировки, как «Начальная загрузка», «Конечная загрузка» и т. Д.

Однако, кажется, что он только регистрируетсяодин запрос и не регистрирует все запросы.Кроме того, хотя время загрузки полезно, в идеале я хотел бы иметь доступ ко всей информации, которую можно увидеть в Trace.axd, такой как данные запроса, данные публикации, данные сеанса и т. Д.

Возможно ли это вообще без каких-либо серьезных изменений кода?В идеале я хотел бы включить это, используя только изменения web.config.

В качестве альтернативы я рассмотрел другие приложения, такие как инструменты профилирования RedGate и Equatec, однако сначала я хотел бы исчерпать неинвазивные параметры трассировки.

Приложение написано на ASP.Net 3.5 и C #.

Ответы [ 2 ]

4 голосов
/ 19 января 2011

У меня есть стандартный HttpModule, который я использую для всех своих веб-приложений для мониторинга производительности. Используемый регистратор может быть изменен, а также может выполнять такие действия, как удаление пробелов из источника, сжатие или отправка электронных писем, если достигнуты определенные пределы. Это проще, чем перелистывать следы asp.net, так как вы получаете только ту информацию, которую вы считаете неважной.

public class PerfHttpModule : IHttpModule {

    private static Common.Logging.ILog log = Common.Logging.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    public static readonly string CONTEXT_RequestStart = "PerfHttpModule_RequestStart";
    public static readonly string CONTEXT_RequestId = "PerfHttpModule_RequestId";

    public void Init(HttpApplication context) {
        context.BeginRequest += new EventHandler(context_BeginRequest);
        context.EndRequest += new EventHandler(context_EndRequest);
    }

    private void context_BeginRequest(object sender, EventArgs e) {
        try {
            if (HttpContext.Current != null) {
                HttpContext.Current.Items[CONTEXT_RequestStart] = DateTime.Now;
                HttpContext.Current.Items[CONTEXT_RequestId] = random.Next(999999).ToString("D6");
                log.Info("Url: " + HttpContext.Current.Request.Url + " (" + HttpContext.Current.Request.ContentLength + ")");
            }
        } catch {
        }
    }

    private void context_EndRequest(object sender, EventArgs e) {
        if (HttpContext.Current.Items.Contains(CONTEXT_RequestStart)) {
            DateTime time1 = (DateTime)HttpContext.Current.Items[CONTEXT_RequestStart];
            DateTime time2 = DateTime.Now;
            double ms = (time2 - time1).TotalMilliseconds;
            log.Info("TotalMilliseconds: " + ms);
            if (ms > AppSettings.SlowPage || ms > AppSettings.ErrorSlowPage) {
                StringBuilder sb = new StringBuilder();
                sb.Append("Slow page detected." + "\t");
                sb.Append("TotalMilliseconds: " + ms + "\t");
                sb.Append("Url: " + HttpContext.Current.Request.Url.ToString());
                if (ms > AppSettings.ErrorSlowPage) {
                    log.Error(sb.ToString());
                } else if (ms > AppSettings.SlowPage) {
                    log.Warn(sb.ToString());
                }
            }
        }
    }
}

UPDATE

        if (HttpContext.Current != null) {
                NameValueCollection tmp = new NameValueCollection(HttpContext.Current.Request.ServerVariables);
                foreach (string i in tmp.Keys) {

                }
            if (HttpContext.Current.Server != null) {
                if (HttpContext.Current.Server.GetLastError() != null) {

                }
            }
            if (HttpContext.Current.Session != null) {
                foreach (string i in HttpContext.Current.Session.Keys) {

                }
            }
            if (HttpContext.Current.Request.Cookies != null) {
                foreach (string i in HttpContext.Current.Request.Cookies.Keys) {

                }
            }
            if (HttpContext.Current.Response.Cookies != null) {
                foreach (string i in HttpContext.Current.Response.Cookies.Keys) {

                }
            }
            if (HttpContext.Current.Items != null) {
                foreach (string i in HttpContext.Current.Items.Keys) {

                }
            }
            if (HttpContext.Current.Request.Form != null) {
                foreach (string i in HttpContext.Current.Request.Form.Keys) {

                }
            }
        }
2 голосов
/ 28 января 2011

Данные трассировки находятся под покрытием стандартного набора данных. Вы не можете заполучить его официально, но вот взломщик, который может это сделать (похоже, работает на .NET 2-4):

public static DataSet GetTraceData(Page page)
{
    if (page == null)
        throw new ArgumentNullException("page");

    return (DataSet)typeof(TraceContext).GetField("_requestData",
           BindingFlags.NonPublic | BindingFlags.Instance).GetValue(page.Trace);
}

Получив DataSet, вы можете делать с ним все, что захотите, сохранять в файл XML (DataSet.WriteXml), поток и т. Д.

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

...