惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - lovecherry

Java避坑宝典《Java业务开发常见错误100例》上线了 招聘前端、Java后端开发、测试、Mysql DBA 我的另一个博客 一个MVC框架的原型 有关网站UI实现的几种方式的讨论 httpmodule和httphandler配合的又一应用——合并脚本样式 - lovecherry - 博客园 .NET 4.0改进(一) 到底怎么样的面试才是最公平的才能找到合适的人又不产生误判 最近项目的一些心得(纯贴代码) 有关CPU占用和缓存的一些见解,希望给大家一些启发 没有linq让我怎么活 ADO.NET EF不方便之处(BUG)收集帖 2005-2008年度个人总结和写书计划? SOA概念误解实施要点 我对SOA的认识以及心得 MCTS Self-Paced Training Kit (Exam 70-503) Microsoft® .NET Framework 3.5—Windows® Communication Foundation 书评 【翻译】微软应用程序架构指南:如何组织应用程序的结构 代朋友发招聘信息,C++程序员 有关写书。。。。。。。。。。。
如何把ASP.NET TRACE HANDLER的信息持久化保存
lovecherry · 2010-02-26 · via 博客园 - lovecherry

ASP.NET TRACE是一个不错的功能可以收集下列信息

Request Details

The Request Details section displays general information about the current request and response.

ValueDescription

Session ID

The session identification for the specified request.

Time of Request

The time the request was made.

Request Encoding

The character encoding for the request.

Request Type

The HTTP method used (GET or POST).

Status Code

The status-code value associated with the response. For more information, see RFC 2616 at the World Wide Web Consortium (W3C) Web site.

Response Encoding

The character encoding for the response.

Trace Information

The Trace Information section displays the flow of page-level events. If you have created custom trace messages, the messages are displayed in the Trace Information section also.

ValueDescription

Category

The custom trace category specified in a Warn or Write method call, if any.

Message

The custom trace message specified in a Warn or Write method, if any.

From First (s)

The elapsed time in seconds since the first trace message was processed. The first trace message appears at the top of the list.

From Last (s)

The elapsed time in seconds between the processing of the current trace message and the preceding trace message.

Control Tree

The Control Tree section displays information about ASP.NET server controls created in the page.

ValueDescription

Control ID

The identification for the control. If you have not specified an ID property for the control, ASP.NET generates an ID using the UniqueID property.

Type

The fully qualified type of the control.

Render Size bytes

The size in bytes of the rendered control (including child controls). This is the size of the actual HTML, XML, or other format that is sent to the browser.

ViewState Size bytes

The size in bytes of the control's view state (excluding child controls). For more information, seeASP.NET State Management.

ControlState Size bytes

The size in bytes of the control's control state (excluding child controls). For more information, seeASP.NET State Management.

Session State

The Session State section displays information about values stored in Session state, if any. For more information, see ASP.NET Session State.

ValueDescription

Session Key

The key for data stored in session state, if any.

Type

The fully qualified type of the object that stores the data.

Value

A string representation of the data stored in session state, if any.

Application State

The Application State section displays information about values stored in Application state, if any. For more information, seeASP.NET Application State.

ValueDescription

Application Key

The key for data stored in application state, if any.

Type

The fully qualified type of the object that stores the data.

Value

A string representation of the data stored in application state, if any.

Cookies Collection

The Request Cookies and Response Cookies sections display information about the cookies passed between the browser and the server on each request and response. The section displays both persistent and session cookies. ASP.NET creates some cookies automatically, such as those for cookie-based Session state and forms authentication. For more information, seeASP.NET Cookies.

ValueDescription

Name

The name of the cookie.

Value

The value of the cookie, or subkeys and values if the cookie is multivalued.

Size

The size in bytes of the cookie.

Headers Collection

The Headers Collection section displays information about request and response message header name/value pairs, which provide information about the message body or requested resource. Header information is used to control how request messages are processed and response messages are created. For more information on HTTP headers, see RFC 2616 at theWorld Wide Web Consortium (W3C) Web site.

ValueDescription

Name

The name of the header.

Value

The value of the header.

Form Collection

The Form Collection section displays name/value pairs that show the form element values (control values) submitted in a request during a POST (postback).

ValueDescription

Name

The name of the form variable.

Value

The value of the form variable.

Querystring Collection

The Querystring Collection section shows the values passed in the URL. In a URL, query string information is separated from the path information by a question mark (?); multiple query string elements are separated by an ampersand (&). Query string name/value pairs are separated by an equals sign (=). The QueryString property of the HttpRequest object returns aNameValueCollection of query string variables.

ValueDescription

Name

The name of the query string variable.

Value

The value of the query string variable.

Server Variables

The Server Variables section displays a collection of server-related environment variables and request header information. The ServerVariables property of the HttpRequest object returns a NameValueCollection of server variables.

ValueDescription

Name

The name of the server variable.

Value

The value of the server variable.

有两种使用方式,一种是页面级的TRACE,一种是应用程序级。前者打开后直接在页面上输出TRACE信息,显然在生产环境中不适合。

后者可以配置不直接在页面输出而是通过TraceHandler(也就是Trace.axd)来查看:

 <trace pageOutput="false" enabled="true"  requestLimit="1"  mostRecent="true"/>

 

 我们可以配置内存中维护的队列长度也就是Trace的请求总数,也可以选择超过队列之后放弃最后的请求还是放弃最先的请求

这个Handler可以查看所有记录的请求也可以查看每一个请求的细节,也可以清空历史数据。

观察一下TraceHandler的源代码可以论证:

代码

void IHttpHandler.ProcessRequest(HttpContext context)
{
    
if (DeploymentSection.RetailInternal || (!context.Request.IsLocal && HttpRuntime.Profile.LocalOnly))
    {
        HttpException exception = new HttpException(0x193null);
        exception.SetFormatter(new TraceHandlerErrorFormatter(!DeploymentSection.RetailInternal));
        
throw exception;
    }
    
this._context = context;
    
this._response = this._context.Response;
    
this._request = this._context.Request;
    
this._writer = Page.CreateHtmlTextWriterInternal(this._response.Output, this._request);
    
if (context.WorkerRequest is IIS7WorkerRequest)
    {
        
this._response.ContentType = this._request.Browser.PreferredRenderingMime;
    }
    
if (this._writer != null)
    {
        
this._context.Trace.IsEnabled = false;
        
this._request.ValidateInput();
        
this._writer.Write("<html>\r\n");
        
this._writer.Write("<head>\r\n");
        
this._writer.Write(StyleSheet);
        
this._writer.Write("</head>\r\n");
        
this._writer.Write("<body>\r\n");
        
this._writer.Write("<span class=\"tracecontent\">\r\n");
        
if (!HttpRuntime.Profile.IsConfigEnabled)
        {
            HttpException exception2 = new HttpException();
            exception2.SetFormatter(new TraceHandlerErrorFormatter(false));
            
throw exception2;
        }
        IList data = HttpRuntime.Profile.GetData();
        
if (this._request.QueryString["clear"!= null)
        {
            HttpRuntime.Profile.Reset();
            
string rawUrl = this._request.RawUrl;
            
this._response.Redirect(rawUrl.Substring(0, rawUrl.IndexOf("?", StringComparison.Ordinal)));
        }
        
string s = this._request.QueryString["id"];
        
if (s != null)
        {
            
int num = int.Parse(s, CultureInfo.InvariantCulture);
            
if ((num >= 0&& (num < data.Count))
            {
                
this.ShowDetails((DataSet) data[num]);
                
this.ShowVersionDetails();
                
this._writer.Write("</span>\r\n</body>\r\n</html>\r\n");
                
return;
            }
        }
        
this.ShowRequests(data);
        
this.ShowVersionDetails();
        
this._writer.Write("</span>\r\n</body>\r\n</html>\r\n");
    }
}

但是怎么做才能禁止直接查看这个页面并把这些信息保存到文件中,或者是数据库中呢?

您可能会想到各种TraceListener,但是使用后可以发现并不能把TraceHandler中所有的信息都输出。

代码

<configuration>
  
<system.diagnostics>
    
<trace autoflush="true">
      
<listeners>
        
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\TextWriterOutput.log" />
        
<remove name="Default" />
      
</listeners>
    
</trace>
  
</system.diagnostics>
  
<system.web>
    
<trace pageOutput="false" enabled="true"  requestLimit="1"  mostRecent="true"  writeToDiagnosticsTrace="true"/>
        
<compilation debug="true">
        
</compilation>
    
</system.web>
</configuration>

得到的日志文件如下:

代码

aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
aspx.page: End Load
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
: asdasd
aspx.page: End Load
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render
aspx.page: Begin PreInit
aspx.page: End PreInit
aspx.page: Begin Init
aspx.page: End Init
aspx.page: Begin InitComplete
aspx.page: End InitComplete
aspx.page: Begin PreLoad
aspx.page: End PreLoad
aspx.page: Begin Load
asdasd: asdasd
aspx.page: End Load
aspx.page: Begin LoadComplete
aspx.page: End LoadComplete
aspx.page: Begin PreRender
aspx.page: End PreRender
aspx.page: Begin PreRenderComplete
aspx.page: End PreRenderComplete
aspx.page: Begin SaveState
aspx.page: End SaveState
aspx.page: Begin SaveStateComplete
aspx.page: End SaveStateComplete
aspx.page: Begin Render
aspx.page: End Render

TraceHandler通过调用System.Web.Util.Profile的GetData()来获取所有历史请求的Trace信息,那么有没有办法获取当前请求的一条信息呢?

通过查看TraceContext的代码可以发现其实每一个当前请求的Trace信息保存在DataSet中,但其中的GetData方法是internal的(.NET框架中有许多internal的类型和成员比较恶心),我们尝试反射来调用:

 代码

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Items[
"id"= Guid.NewGuid().ToString();
            TraceContext tc 
= HttpContext.Current.Trace;
            MethodInfo mi 
= tc.GetType().GetMethod("GetData", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
            DataSet ds 
= mi.Invoke(tc, nullas DataSet;
            
if (ds != null)
            {
                
for (int i = 0; i < ds.Tables.Count; i++)
                {
                    GridView gv 
= new GridView();
                    gv.DataSource 
= ds.Tables[i];
                    gv.DataBind();
                    StringWriter t 
= new StringWriter();
                    HtmlTextWriter tw 
= new HtmlTextWriter(t);
                    gv.RenderControl(tw);
                    
if (!Directory.Exists("c:\\trace"))
                        Directory.CreateDirectory(
"c:\\trace");
                    
string filename = string.Format("c:\\trace\\{0}_{1}_{2}.html", HttpContext.Current.Request.Url.AbsolutePath.TrimStart('/'), DateTime.Now.ToString("yyyyMMddss"), HttpContext.Current.Items["id"]);
                    File.AppendAllText(filename, t.ToString());
                }
               
            }

        }

不管是TraceContext还是TraceHandler都做了大量格式化操作把DataSet数据转化为HTML代码,我们在这里为了方便直接使用GridView来转换,然后把信息保存在文件中,运行几次页面可以发现多了很多日志:

 

查看一个日志,也记录到了所有信息: 

 

通过配置<trace pageOutput="false" enabled="true"  requestLimit="1"  mostRecent="true"/>

可以让队列数为1并且也只保存当前请求的数据,在这里为了简单并没有日志保存到数据库中可以自己实现。

如果要禁止Trace.axd其实也很简单:

 代码

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            
if (HttpContext.Current.Request.Url.ToString().Contains("trace.axd"))
                HttpContext.Current.Response.StatusCode 
= 404;
     
        }

补充几点:

1) 我们可以把这些操作都封装在HttpModule中,还可以实现异步的HttpModule来提高记录日志的性能。

2) 扩展阅读 http://msdn.microsoft.com/en-us/magazine/cc163927.aspx  自定义Trace的界面。