蛙蛙池塘  
人生价值的最好体现就是做好本职工作...
公告
  • 残荷听雨,梨花飞雪,落英缤纷时节。晓来谁染枫林醉?点点都是离人泪
    活着,就是快乐!自信,就是美丽! 有人爱,就是幸福。
    春天来了
    但愿野百合也有春天

    第三季度的计划



    木了
    晚上一个人看会儿《读者乡土人文版》,听会儿广播挺不错的,想起了三年前在石家庄没电脑的日子,时光飞逝呀,现在笔记本都用上了,以前从没想过,确实得知足常乐。
日历
<2005年7月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
统计
  • 随笔 - 248
  • 文章 - 2
  • 评论 - 2318
  • 引用 - 75

导航

与我联系

搜索

 

常用链接

留言簿

我参加的小组

我参与的团队

我的标签

随笔分类

随笔档案

相册

朋友

积分与排名

  • 积分 - 540180
  • 排名 - 49

最新评论

阅读排行榜

评论排行榜

60天内阅读排行

 
 

写一个跟踪的类库

摘要:本类库出自《asp.net电子商务高级编程》一书的源码,作者Kevin Hoffman。我们在开发程序的时候常常需要跟踪一些变量的值,系统状态等。一般我们在底层架构里提供完成这个任务的功能,我把这本书的两个类先提取出来给大家看看,看看有没有可用的价值,这个类库可以把要跟踪输出的信息输出在一个安全的位置,它把程序集的跟踪输出和asp.net的跟踪输出做了合并。并且提供了在异常抛出的时候获取系统进程信息,线程信息以及应用程序域等方面的信息。

 

/*
 * Class       : GWTrace
 * Namespace   : GW.MonitorServices
 * Assembly    : GW.MonitorServices
 * Author       : Kevin Hoffman
 * Description : Enhanced tracing functionality to consolidate system and http tracing log and
 *                provide support for trace switches.
 
*/

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Remoting.Messaging;

namespace GW.MonitorServices
{
    
/// <summary>
    
/// 跟踪类,这里可以输出一个自定义跟踪消息,
    
/// 也可以跟踪输出一个方法的执行情况,把这些
    
/// 跟踪消息存放在合适的位置,包括类库和页面跟踪
    
/// </summary>

    public sealed class GWTrace
    
{
        
private GWTrace() { } // 用私有构造函数防治实例华.

        
//从web.config来获取设置的跟踪级别
        private static readonly TraceSwitch traceSwitch =
            
new TraceSwitch("GWTrace""GW Current Tracing Level");

        
/// <summary>
        
/// 获取跟踪等级
        
/// </summary>

        public static TraceLevel CurrentTraceLevel
        
{
            
get 
            
{
                
return traceSwitch.Level;
            }

        }

        
        
/// <summary>
        
/// 默认输出信息性消息,警告和错误处理信息
        
/// </summary>
        
/// <param name="message">要显示的的消息</param>
        
/// <param name="args">一个数组参数,用来拼接成最终消息</param>

        [Conditional("TRACE")]
        
public static void Trace( string message, params Object[] args )
        
{
            Trace( TraceLevel.Info, message, args );
        }


        
/// <summary>
        
/// 指定跟踪等级来输出跟踪消息,跟踪指定的跟踪级别,在不同的地方输出跟踪消息
        
/// 如果HttpContext可用的话,就把消息输出到页面跟踪里,总之,这个方法保证跟踪
        
/// 消息始终能记录在安全的位置.
        
/// </summary>
        
/// <param name="msgLevel">跟踪等级</param>
        
/// <param name="message">跟踪消息</param>
        
/// <param name="arrData">跟踪参数</param>

        [Conditional("TRACE")]
        
public static void Trace( TraceLevel msgLevel,
            
string message,
            
params Object[] arrData )
        
{
            
//如果跟踪级别小于或者等于设置的级别时再输出跟踪信息
            if ( msgLevel <= traceSwitch.Level )
            
{
                
// 对输入的参数做一些处理,防治出错
                
// SafeFormat是把信息和对象数组拼接成一个字符串
                
//和string.Format()的功能差不多
                message = ( message == null ? string.Empty : message.Trim() );
                message 
= MonitorUtilities.SafeFormat( message, arrData );
            
                
//记录跟踪消息,如果上HttpContext可用的话
                
//把跟踪信息输出到页面里并且如果跟踪信息
                
//是Error级别的话,使用红色标识跟踪信息
                try 
                
{
                    System.Diagnostics.Trace.WriteLine( message );
                    System.Web.HttpContext httpContext 
= 
                        System.Web.HttpContext.Current;
                    
if ( httpContext != null )
                    
{
                        
if ( msgLevel == TraceLevel.Error )
                            httpContext.Trace.Warn( message );
                        
else
                            httpContext.Trace.Write( message );
                    }

                }

                
catch
                
{
                    
//什么也不用做,下面这句我不会翻译
                    
// Do nothing: do not corrupt the current error
                    
// with a failure to trace an error
                }

            }

        }


        
/// <summary>
        
/// 使用TraceLevel.Info级别跟踪一个方法
        
/// 可以跟踪当时传入方法的一些参数的值
        
/// 本方法调用它的重载方法
        
/// </summary>
        
/// <param name="method">要跟踪的方法</param>

        [Conditional("TRACE")]
        
public static void EnteringMethod( MethodBase method )
        
{
            EnteringMethod( TraceLevel.Info, method );
        }


        
        
/// <summary>
        
/// 指定级别跟踪一个方法,这里可以跟踪方法的名字
        
/// 方法的签名等,这里用了反射和中间
        
/// 语言的一些知识,构造函数在MSIL里用.ctor表示
        
/// </summary>
        
/// <param name="msgLevel">跟踪级别</param>
        
/// <param name="method">要跟踪的方法</param>

[Conditional("TRACE")]
        
public static void EnteringMethod( TraceLevel msgLevel,
            MethodBase method )
        
{
            
try 
            
{
                
if ( traceSwitch.Level >= TraceLevel.Error )
                
{
                    
string methodName =
                        ( method.Name.Equals(
".ctor"? "Constructor" : method.Name );
                    Trace ( msgLevel,
                        
"Entering {0}.{1}() [Signature: {2}]",
                        method.DeclaringType.Name, methodName, method.ToString() );
                }

            }

            
catch
            
{
                
//这里也什么都不做,因为这里出现了异常,如果处理的话会抛出一个新的
                
//异常,造成死循环
                
// Again, do nothing here. The failure to trace should not create
                
// another failure.
            }

        }


    }

}

 

/*
 * Class       : MonitorUtilities
 * Namespace   : GW.MonitorServices
 * Assembly    : GW.MonitorServices
 * Author       : Kevin Hoffman
 * Description : Utility class (static methods only) for us in logging information about important events.
 
*/

using System;
using System.Text;
using System.Runtime.Remoting.Messaging;

namespace GW.MonitorServices
{
    
/// <summary>
    
/// Summary description for MonitorUtilities.
    
/// </summary>

    public class MonitorUtilities
    
{
        
        
/// <summary>
        
/// 把一个异常的堆栈信息处理后返回一个字符串
        
/// 一个异常可能是另一个异常实例引发的,这里通过
        
/// 递归把 所有的异常消息都处理并返回信息,最后
        
/// 形成一个包含异常足够多信息的字符串
        
/// </summary>
        
/// <param name="ex">传输的异常</param>
        
/// <returns>返回的字符串</returns>

        public static string ExpandStackTrace( Exception ex )
        
{
            StringBuilder buffer 
= new StringBuilder(1024);
            
while (ex != null)
            
{
                
if (buffer.Length > 0)
                    buffer.Insert(
0, ex.StackTrace + "\nRe-Thrown (" + ex.Message + ")\n");
                
else
                    buffer.Insert(
0, ex.StackTrace + "\n");

                ex 
= ex.InnerException;
            }

            buffer.Replace(
" in ""\n\tin\n");
            
return buffer.ToString();
        }


        
/// <summary>
        
/// 返回机器名
        
/// </summary>
        
/// <returns></returns>

        public static string GetMachineName()
        
{
            
return System.Environment.MachineName;
        }


        
/// <summary>
        
/// 返回一些进程信息,默认情况下线程信息是不可以获取的,要改一下注册表,下面的
        
/// 英文告诉你怎么做,我不懂英文,就不拽了哦,总之就是返回进程ID啦,进程名称啦
        
/// 线程表示啦,应用程序域啦之类的信息
        
/// In order to use the GetProcessInfo method, the ASP.NET must have access
        
/// to the performance information registry keys. To accomplish this, 
        
/// do the following:
        
/// <pre>
        
/// Open REGEDT32.EXE
        
/// Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\PerfLib
        
/// Navigate to the Security Menu
        
/// Click Permissions
        
/// Select the local machine account under which ASP.NET is running (default is ASPNET)
        
/// Click Add
        
/// Now this application and all ASP.NET apps on the machine have access to this data.
        
/// This function should NOT EVER be called if your application is running on a third
        
/// party hosting company
        
/// </pre>
        
/// </summary>
        
/// <returns></returns>

        public static string GetProcessInfo()
        
{
            
try 
            
{
                System.Diagnostics.Process curProcess 
=
                    System.Diagnostics.Process.GetCurrentProcess();

                
return string.Format(
                    
"[Process:{0}, {1}][Thread: {2}][AppDomain:{3}",
                    curProcess.Id, curProcess.ProcessName,
                    AppDomain.GetCurrentThreadId(),
                    AppDomain.CurrentDomain.FriendlyName );
            }

            
catch
            
{
                
return "Process Information Unavailable";
            }

        }


        
/// <summary>
        
/// 这个方法用来把一个字符串和一个对象数组进行格式化
        
/// 这里调用的也是string.Format方法,但是这是一个
        
/// 不引发异常的版本,嘿嘿,因为这几个类就是做错误处理的,
        
/// 所以尽量不要引发新的异常
        
/// </summary>
        
/// <param name="format"></param>
        
/// <param name="formatArgs"></param>
        
/// <returns></returns>

        public static string SafeFormat(string format, params Object[] formatArgs )
        
{
            format 
= ( format == null ? string.Empty : format.Trim() );
            
try 
            
{
                
return string.Format(format, formatArgs );
            }

            
catch
            
{
                
return format + " (Error binding arguments)";
            }

        }

    }

}


以上两个文件是类库的组成文件,然后建立一个asp.net程序,引入上面的两个文件编译的程序集,设置一下web.config文件,如下。

<configuration>
    
<system.diagnostics>
        
<switches>
            
<add name="GWTrace" value="4" />
        
</switches>
    
</system.diagnostics>
    
<system.web>


然后新建一个default.aspx页面,在代码视图里输入以下代码,运行一下就可以看到成果了。

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using System.Reflection;
using GW.MonitorServices;


namespace WawaCMPArticles
{
    
public class _Default : System.Web.UI.Page
    
{
        
private void Page_Load(object sender, System.EventArgs e)
        
{
            
// 在此处放置用户代码以初始化页面
            GWTrace.Trace("打倒{0}","鸟大哥");
            GWTrace.Trace(System.Diagnostics.TraceLevel.Error,
"鸟大哥是{0}","坏淫");
            
this.Replace("鸟大哥是好人","好人","猪头");
            
this.ThrowNewException(0);
        }

        
public void ThrowNewException(int p)
        
{
            
try
            
{
                
int i = 5/p;
            }

            
catch(System.DivideByZeroException e)
            
{
                Response.Write(MonitorUtilities.ExpandStackTrace(e) 
+ "<br>");
                Response.Write(MonitorUtilities.GetMachineName() 
+ "<br>");
                Response.Write(MonitorUtilities.GetProcessInfo() 
+ "<br>");
            }

        }

        
public void Replace(string s1,string s2,string s3)
        
{
            GWTrace.EnteringMethod( MethodBase.GetCurrentMethod() );
//跟踪输出本方法
            Response.Write(s1.Replace(s2,s3) + "<br>");
        }

        
#region Web 窗体设计器生成的代码
        
override protected void OnInit(EventArgs e)
        
{
            InitializeComponent();
            
this.Trace.IsEnabled =true;//启用页面跟踪
            base.OnInit(e);
        }

        
        
private void InitializeComponent()
        
{    
            
this.Load += new System.EventHandler(this.Page_Load);
        }

        
#endregion

    }

}

最近我见博客园有人讨论监测跟踪和错误处理方面的内容,我也来凑凑热闹。下次再把错误处理的类提取出来,做些注释,和大家讨论一下如何改进,这样偶们个人类库里的代码就越来越多,越来越好,想什么时候用就什么时候用,嘿嘿。错误处理好像微软的Microsoft.ApplicationBlocks.ExceptionManagement挺好用的,相关信息请参考下面的文章或者微软的视频教程。

http://edobnet.cnblogs.com/archive/2004/09/10/41759.html

 

posted on 2005-07-30 17:28 蛙蛙池塘 阅读(1604) 评论(7)  编辑 收藏 网摘 所属分类: 每日随笔
评论:

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接:
 

 
Copyright © 蛙蛙池塘 Powered by: 博客园 模板提供:沪江博客