• 第十七章 调试及安全性(In .net4.5) 之 程序诊断


    1. 概述

      生产环境中的程序,也是不能保证没有问题的。为了能方便的找出问题,.net提供了一些特性来进行程序诊断。

      这些特性包括:logging、tracing 、程序性能分析(profiling) 和 性能计数器(performance counters).

    2. 主要内容

      2.1 Tracing  Logging

        Tracing 是 一种监控程序执行的操作。可以用于显示程序运行过程中各个细节。

        Logging 主要用于错误报告。可以配置Logging集中收集信息,通过e-mail发送或者直接记录到文件或数据库中。

        .net提供了一些相关的类(System.Diagnostics下):

        ① Debug:只能用于Debug编译模式下,可用于显示基本的日志信息和执行判定。

    Debug.WriteLine(“Starting application”); 
    Debug.Indent(); 
    int i = 1 + 2; 
    Debug.Assert(i == 3); 
    Debug.WriteLineIf(i 0, “i is greater than 0”);

        ② TraceSource

    TraceSource traceSource = new TraceSource(“myTraceSource”, 
        SourceLevels.All); 
     
    traceSource.TraceInformation(“Tracing application..”); 
    traceSource.TraceEvent(TraceEventType.Critical, 0, “Critical trace”); 
    traceSource.TraceData(TraceEventType.Information, 1,  
        new object[] { “a”, “b”, “c” }); 
     
    traceSource.Flush(); 
    traceSource.Close(); 
     
    // Outputs: 
    // myTraceSource Information: 0 : Tracing application.. 
    // myTraceSource Critical: 0 : Critical trace 
    // myTraceSource Information: 1 : a, b, c

        上述都是输出信息到输出窗口,生产环境中是看不到的。.net还提供了几种TraceListener,可以实现输出信息到各个介质。

        

    Stream outputFile = File.Create(“tracefile.txt”); 
    TextWriterTraceListener textListener = 
        new TextWriterTraceListener(outputFile); 
     
    TraceSource traceSource new TraceSource(“myTraceSource”, 
        SourceLevels.All); 
     
    traceSource.Listeners.Clear(); 
    traceSource.Listeners.Add(textListener); 
     
    traceSource.TraceInformation(“Trace output”); 
     
    traceSource.Flush(); 
    traceSource.Close();

        还可以使用配置文件来配置跟踪信息

    <?xml version=”1.0” encoding=”utf-8” ?> 
    <configuration> 
      <system.diagnostics> 
        <sources> 
          <source name=”myTraceSource” switchName=”defaultSwitch”> 
            <listeners> 
              <add initializeData=”output.txt”  
                   type=”System.Diagnostics.TextWriterTraceListeer”             
                   name=”myLocalListener”> 
                   <filter type=”System.Diagnostics.EventTypeFilter”  
                    initializeData=”Warning”/> 
              </add> 
              <add name=”consoleListener” /> 
              <remove name=”Default”/> 
            </listeners> 
          </source> 
        </sources> 
        <sharedListeners> 
          <add initializeData=”output.xml” type=”System.Diagnostics.XmlWriterTraceListener” 
             name=”xmlListener” traceOutputOptions=”None” /> 
          <add type=”System.Diagnostics.ConsoleTraceListener” name=”consoleListener” 
              traceOutputOptions=”None” /> 
        </sharedListeners> 
        <switches> 
          <add name=”defaultSwitch” value=”All” /> 
        </switches> 
      </system.diagnostics> 
    </configuration>

        使用EventLog可以写入日志到系统日志中。还可以从系统日志获取日志或者订阅日志变更事件。

    class EventLogSample 
    { 
        public static void Main() 
        { 
            EventLog applicationLog new EventLog(“Application”, “.”, “testEventLogEvent”); 
            applicationLog.EntryWritten += (sender, e) => 
            {
                Console.WriteLine(e.Entry.Message); 
            }; 
            applicationLog.EnableRaisingEvents true; 
            applicationLog.WriteEntry(“Test message”, EventLogEntryType.Information); 
             
            Console.ReadKey();
        } 
    }

      2.2 程序性能分析(Profiling)

        Profiling 是权衡程序对特定资源的占用情况的过程。

        ① 可以使用StopWatch类来监测指定代码的执行时间。

     class Program 
     { 
         const int numberOfIterations = 100000; 
         static void Main(string[] args) 
         {
             Stopwatch sw new Stopwatch(); 
             sw.Start(); 
             Algorithm1(); 
             sw.Stop(); 
             Console.WriteLine(sw.Elapsed); 
              
             sw.Reset(); 
             sw.Start(); 
             Algorithm2(); 
             sw.Stop(); 
                    Console.WriteLine(sw.Elapsed); 
          Console.WriteLine(“Ready…”); 
          Console.ReadLine();        
       } 
      private static void Algorithm2() 
      { 
          string result = “”; 
          for (int x = 0; x < numberOfIterations; x++) 
          { 
              result += ‘a’; 
          } 
      } 
      private static void Algorithm1() 
      { 
          StringBuilder sb new StringBuilder(); 
          for (int x = 0; x < numberOfIterations; x++) 
          { 
              sb.Append(‘a’);
          } 
          string result = sb.ToString(); 
      } 
    }

        ② Visual Studio 2012 包含了一个性能分析工具,可以以四种模式来分析程序性能:

          CPU sampling :最轻量级选项。对程序只有轻微影响,主要用于对程序问题做初级的查找定位工作。

          Instrumentation :该选项会植入一些代码到编译文件中,可以监测各个方法的执行。

          .NET memory allocation :使用该选项,程序给新对象分配内存或者旧对象被垃圾回收时,都会中断程序。用于监测内存的使用情况。

          Resource contention data:该选项用于多线程环境,用于查找指定方法访问指定资源前必须等待其他方法返回的原因。

      2.3 创建和监测性能计数器

        windows提供了性能监测器(Perfmon.exe),用于监测性能计数器。

        通过PerformanceCounter类,可以使用代码读取性能计数器信息。

      class Program 
      { 
          static void Main(string[] args) 
          { 
              Console.WriteLine(“Press escape key to stop”); 
              using (PerformanceCounter pc =  
                           new PerformanceCounter(“Memory”, “Available Bytes”)) 
              { 
                  string text = “Available memory: “; 
                  Console.Write(text); 
                  do 
                  {                 
                    while (!Console.KeyAvailable) 
                    { 
                        Console.Write(pc.RawValue); 
                        Console.SetCursorPosition(text.Length, Console.CursorTop); 
                    } 
                } while (Console.ReadKey(true).Key != ConsoleKey.Escape); 
            } 
        } 
    }     

        性能计数器(Performance counters)的几种有用的类型:

        ① NumberOfItems32/NumberOfItems64:用于统计操作或者数据项的数量。

        ② RateOfCountsPerSecond32/RateOfCountsPerSecond64:用于计算操作或数据项每秒的数量。

        ③ AvergateTimer32: 计算完成一个过程或操作一个数据项的平均时间。

        还可以创建和使用自定义的性能计数器(Performance counters)

        class Program 
        {
            static void Main(string[] args) 
            { 
                if (CreatePerformanceCounters()) 
                { 
                    Console.WriteLine(“Created performance counters”); 
                    Console.WriteLine(“Please restart application”); 
                    Console.ReadKey(); 
                    return; 
                } 
                var totalOperationsCounter = new PerformanceCounter( 
                    “MyCategory”, 
                    “# operations executed”, 
                    “”,                 
                    false); 
                var operationsPerSecondCounter = new PerformanceCounter( 
                    “MyCategory”, 
                    “# operations / sec”, 
                    “”, 
                   false); 
     
                totalOperationsCounter.Increment(); 
                operationsPerSecondCounter.Increment(); 
            } 
        private static bool CreatePerformanceCounters() 
        { 
            if (!PerformanceCounterCategory.Exists(“MyCategory”)) 
            { 
                CounterCreationDataCollection counters =  
                    new CounterCreationDataCollection 
                { 
                    new CounterCreationData( 
                        “# operations executed”, 
                        “Total number of operations executed”, 
                        PerformanceCounterType.NumberOfItems32), 
                    new CounterCreationData( 
                        “# operations / sec”, 
                        “Number of operations executed per second”, 
                        PerformanceCounterType.RateOfCountsPerSecond32) 
                }; 
                PerformanceCounterCategory.Create(“MyCategory”, 
                        “Sample category for Codeproject”, counters); 
                return true; 
            } 
              return false; 
          } 
      } 

    3. 总结

      ① Logging 和 Tracing 是在生产环境监控程序的重要手段,应该从项目的开始阶段就考虑实现。

      ② 可以使用Debug和TraceSource类去记录和跟踪程序信息。还可以通过配置不同的监听器,来实现将跟踪到的信息发送到各个位置。

      ③ 通过程序性能监测工具,可以定位程序中的问题位置,从而更好的解决问题。

  • 相关阅读:
    python之map,filter
    python函数的闭包
    Hibernate查询对象的方法浅析
    底部浮动
    DataGrid-自定义排序
    DataGrid-1
    Alert
    2014-01-04 SQL练习
    proguard-gui 混淆代码简要笔记
    vim利用coc补全的配置过程
  • 原文地址:https://www.cnblogs.com/stone_lv/p/4390295.html
Copyright © 2020-2023  润新知