zoukankan      html  css  js  c++  java
  • 蛙蛙推荐:设计一个Tracing组件

    蛙蛙推荐:设计一个Tracing组件
    【需求】
    wawaKM的数据访问,性能计数器,主键生成的公共组件都做好了,为了便于以后排查问题的方便,还得做一个Tracing的公共组件,罗列需求如下:
    1、能把跟踪信息记录到各种记录器里,默认要实现文本和数据库的记录;
    2、要有一个能记录EventLog的接口,以便记录重要的系统级别的跟踪信息;
    3、记录器可以扩展,比如实现一个UDP记录器,以便可以在其它机器实时查看trace;
    4、Tracing组件不能影响主业务性能;
    5、跟踪信息可以分级别,Info,Warn,Error
    6、可以单独给不同级别的跟踪信息配置记录器,比如所有Error的日志记录到一个SMTP的记录器里发到指定的收件箱
    7、跟踪信息可以分类别,便于以后查找某类别的跟踪信息
    8、跟踪信息要默认把当前所在的机器IP,所属类,进程、线程、AppDomain,时间等信息记录下来。
    9、修改跟踪相关配置后即时生效,无需重启应用
    【配置】
    根据需求,指定配置文件大约如下
    <WawaTrace
      
    category="login;sync"
      enabled
    ="true"
      enabled_system_trace
    ="false"
      enabled_web_trace
    ="true">
      
    <TextAppender enabled="true" level_filter="*" cate_filter="*"   console="true" trace_path=""></TextAppender>
      
    <DbAppender enabled="true" Level_filter="error" cate_filter="login" connstr=""></DbAppender>
      
    <UDPAppender enabled="true" enable_ip_filter="true">
        
    <Observer ip="192.168.0.250" user="大碗豆浆" pwd="@_@-_-"/>
        
    <Observer ip="192.168.0.111" user="千山一鸟" pwd="-_-@_@"/>
      
    </UDPAppender>
    </WawaTrace>

    解释一下,
    WawaTrace节点:category表示跟踪类别,多个分类用英文半角分号隔开;enabled表示是否启用跟踪,可取true和false。enabled_system_trace是否捕获System.Diagnostics.Trace的跟踪信息;enabled_web_trace写日志的时候是否同时也写入web的跟踪里。
    TextAppender节点:enabled表示是否启用文本记录器,level_filter表示跟踪级别过滤器,如选*表示记录所有级别trace,如选error即只记录error级别的日志,可取*,error,warn,debug,info;cate_filter表示跟踪类别过滤器,可以取WawaTrace的category属性的值和*值,多个值用英文半角分号隔开,表示本记录器只记录某些类别的跟踪信息;console表示在输出到文本的时候是否同时输出到标注控制台输出;trace_path表示文本日志保存的目录。
    DbAppender节点:enabled,Level_filter,cate_filter同TextAppender,connstr表示日志记录的数据库连接字符串,其中表名和字段名都应该是事先约定好的。
    UDPAppender节点:enabled,Level_filter,cate_filter同TextAppender,enable_ip_filter属性表示是否启用IP过滤,如果不启用IP过滤,跟踪观察者只要有用户名和密码就可以查看跟踪信息。
    UDPAppender/Observer节点:ip表示观察者所在的机器IP,当启用了enable_ip_filter的时候才起作用,user和pwd分别表示该ip上所允许的观察者的用户名和密码。
    【接口设计】
    要开发一个组件或者类库,要先要从使用者的角度去考虑,想想他们怎么去用你的组件感觉比较舒服,所以要先设计好用户的使用接口,考虑有哪些用户使用的场景。
    1、获取一个默认跟踪器实例
    static ITraceing _tracer = TracerFactory.GetTracer(typeof(MyClass));
    其中MyClass是使用Tracer的类名
    2、获取一个带类别的跟踪器实例
    static ITraceing _tracer = TracerFactory.GetTracer(typeof(MyClass), MyTraceCate.Login);
    其中MyTraceCate是一个保存所有类别信息的类,里面只有一些常量。
    3、记录跟踪信息
    _trace.Info("this is a test trace"); //记录一条日志
    _trace.Info("{0}是个大坏蛋", name); //用string.Format记录日志
    _trace.Error(ex,"here has a error"); //记录一个异常信息,其中ex是一个异常
    4、记录一条系统日志
    SystemEventLog.Info(GlobalUiti.ApplicationName, "application ia start"); //记录一条消息级别的系统日志
    SystemEventLog.Wran(ex,GlobalUiti.ApplicationName, "application has an error"); //记录一条警告级别的系统日志,其中ex是一个异常
    其中GlobalUiti.ApplicationName充当eventlog的事件源,SystemEventLog做成一个静态类
    用户接口设计要尽量简单直观,方便使用,好的组件就应该是使用简单,配置灵活,好了,下一步,设计大框架。
    【概要设计】
    一般概要设计可以用文字描述,UML图,伪代码等来表达,其中伪代码最有表达力,不用像UML还要生成代码,也不用像文字描述那样有二义性,我们先用伪代码表达一下概要设计,然后再详细说一说每个类,代码如下
    user interface and imp

    enum and entity class

    TraceAppender

    Config

    SystemTrace

    Utilities

    说明:
    1、ITracer是用户使用的接口类,用户用它来进行日志记录,里面写了几个原型方法,当然还不全,每个方法应该都有一系列的重再方法。TracerImp是ITracer的实现,里面调用各种TraceWriter来写日志,这里面要用一个队列来缓存要记录的跟踪信息,然后用一个线程来论询扫描队列进行日志记录,这样可以防止直接对硬盘、数据库、网络的集中写操作。TracerFactory里有两个工厂方法,用来方便用户使用日志记录器,该类可以声明为静态类。
    2、TracingLevel是跟踪级别,这里用枚举来表示,真实情况下应该用一个实现IComparable接口的类(有待推敲)。TraceItem表示一条跟踪消息,包含了一条跟踪消息所有的信息。
    3、ITraceWriter是一个抽象类(命名成一个接口了,回头再改),它表示一个日志记录器,用它来把跟踪消息记录到各种存储器上,分别有跟踪级别,跟踪类别,是否启用几个属性,以及记录日志的方法。TextTraceWriter,DbTraceWriter,UDPTraceWriter分别是ITraceWriter的三个实现,分别实现文本,数据库和UDP的记录。
    4、TraceConfig用来读取和缓存配置信息,对应于上面的XML配置,这里用了好多嵌套类,再详细设计的时候最好不要这样用。
    5、SystemEventLog封装了EventLog的操作,让用户可以轻松访问系统日志。
    6、MonitorUtilities是一个帮助类,用来把一个异常的详细信息,包括内部异常的信息,获取本机IP,当前线程,进程,应用程序域等信息,以及以安全的方式(不像string.format会抛出异常)格式化一个字符串。

    【小节】
    概要设计和伪代码有了,就要写测试用例和实现具体逻辑的代码了,测试用例就针对用户接口编写就行了。具体类的编码上就要考虑算法的细节,性能这些了,写的时候我再把细节整理一下,先写到这儿。
    不用劝我有entlib.loger,log4net,nlog啥的这些东西,没必要自己实现一个,我就是闲着没事写着玩儿,自己写的是自己的,而且灵活,简单,自己懂,出错了自己好查。
    本文主要写一个组件或者类库从需求到设计的这么一个过程,不涉及详细的技术细节,我接下来会实现这个设计。
  • 相关阅读:
    lambda续集——1
    c++之—— lambda表达式(有个未能解决的问题等待大佬解答)——(在stack overflow找到了答案)
    交换两个变量,只使用2个变量——权当面试了解使用
    移位实现正负数原码输出
    算法导论之——插入排序
    类模板的实现与定义相分离
    类模板
    当函数模板遇到普通函数
    c++之——template模板函数
    字符转数字,数字转字符
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/948844.html
Copyright © 2011-2022 走看看