zoukankan      html  css  js  c++  java
  • 写一个跟踪的类库

     

    写一个跟踪的类库

    摘要:本类库出自《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

     

  • 相关阅读:
    CodeSmith中SchemaExplorer类详解
    配置 TransactSQL 调试器
    获取SQL所有数据库名、所有表名、所有字段名、表字段长度
    SQL SERVER数据类型与C#数据类型对照表
    C# orm linq 真的不错
    游戏外挂教程
    RDLC钻取式报表开发
    脚本整理
    访问Exchange Mail
    本人开发的带提示的TextBox控件
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/203649.html
Copyright © 2011-2022 走看看