现在的位置: 首页 > 综合 > 正文

Sharepoint学习笔记—Debug&TroubleShooting–Developer Dashboard的使用(2.与SPMonitoredScope的结合)

2012年07月16日 ⁄ 综合 ⁄ 共 5064字 ⁄ 字号 评论关闭

    上一篇我们总结了开启Developer Dashboard的方法,有了Developer Dashboard,我们可以获取到许多信息,这些信息对我们Sharepoint管理人员和开发人员很有帮助,如:
            •哪些控件被加载
            •加载每个控件的时间
            •数据库查询以及执行时间
            •加载页面所触发的事件
            •加载页面各个阶段的时间

 一、何时使用 SPMonitoredScope
    开发人员可以在以下情形中使用 SPMonitoredScope : 
           • 确定资源过度使用情况。
           •确定性能瓶颈。
           •确定某些组件与其他组件的交互方式。

二、SPMonitoredScop使用的局限性
   应注意,在使用 SPMonitoredScope 时存在一些限制: 
         •仅捕获对 SharePoint 数据库的调用。
         •只有用 SPMonitoredScope 包装且位于前端 Web 服务器上的代码会出现在开发人员仪表板上。在应用程序服务器上执行的代码仅在运行该代码的计算机上的 ULS 日志中显示 SPMonitoredScope 信息。 
         •对SandSolution中的Code无效,你只能在Full trust的Solution中使用SPMonitorScope。

三、如何使用 SPMonitorScope
  1、通常的用法
    SPMonitoredScope 类驻留在 Microsoft.SharePoint.Utilities 命名空间中。
    SPMonitoredScope 使用起来很简单。开发人员只需“包装”要监视的代码段即可。然后,在执行代码时,系统会将测量的统计信息写入 ULS 日志及Developer Dashboard中。这样,开发人员和系统管理员便可立即使用有关组件以及组件所在页面的信息。当然,这种"包装"是可以嵌套的。
   下面我们就创建了一个WebPart,在它的PageLoad事件中使用了SPMonitoredScope来嵌套了两个方法FastMethod与SlowMethod(这两个方法又各自使用了SPMonitoredScope),这里所谓通常的用法就是:我们使用了SPMonitorScope类的第一种Constructor,此Constructor只传入一个String类型的参数(即你给Scope取的名字),如:

using (new SPMonitoredScope(“My Scope Name”))
{
   doSomeWork(); 
}

 WebPart中的执行代码如下:

       protected void Page_Load(object sender, EventArgs e)
        {

            using (SPMonitoredScope scope = new SPMonitoredScope("CallTwoMethods"))
            {
                SlowMethod();
                FastMethod();
            }
        }

        private void SlowMethod()
        {
            using (SPMonitoredScope scope =new SPMonitoredScope("SlowMethod"))
            {
                System.Threading.Thread.Sleep(1200);
            }
        }
        private void FastMethod()
        {
            using (SPMonitoredScope scope = new SPMonitoredScope("FastMethod"))
            {
                System.Threading.Thread.SpinWait(10);
            }
        }

 

 执行效果如下图

 

 2、其他使用方法(监视其他资源使用情况,使用性能阈值)
  此用法我们需要SPMonitoredScope类的第二种Constructor来实现,此Constructor有三个参数

SPMonitoredScope(String, UInt32, ISPScopedPerformanceMonitor[])
public SPMonitoredScope(
 string name,
 uint maximumExecutionTime,
 params ISPScopedPerformanceMonitor[] monitors
)

  第一个参数同上(我们为Scope取的名字)

  第二个参数是我们为监控的操作设定的最大性能阈值(毫秒级)

  第三个参数是一组实现了ISPScopedPerformanceMonitor接口的数组对象,下面这张表列举了几个实现了这个接口的类 

 

  当然有了这个接口,我们不但能使用上表中列举的相关类来添加到SPMonitoredScope Constructor的第三个参数数组中,我们还可以创建若干个我们用户自定义的Monitors(让它继承并实现这此接口),用它来监控我们感兴趣的相关资源,并把这此Customer Monitor添加到当前的SPMonitoredScope中来。所以第三个参数在这个层面上,也可以是我们用户自定义Monitor对象的列表。
下面这段代码使用了我们上表列举的类来构造我们的SPMonitoredScope对象

using(
 SPMonitoredScope("My Scope Name",1000,
 new SPRequestUsageCounter(3),
 new SPSqlQueryCounter()))
{
 Thread.Sleep(5000);
}

当我们的监控Code的执行时间超过了我们设定的阈值(1000)时,Developer Dashboard的边框会变红,并提高trace的Level。如下图 3

  

      有时候你需要做的不仅仅是把监控的Scope记录到Developer Dashboard,你还想知道你所Monitor的Scope Code到底被执行了多少次。例如你的系统使用到了第三方公司提供的Web service服务,此服务按访问的次数收费,你可以记录你使用此Webservice的次数,一旦访问次数超过了你设定的阀值,你就可以设置相关的返回值(ValueIsExcessive)。在每一个Scope结束,SPMonitoredScope对象释放(disposed)前,它会检查所有的Monitors(即:第三个参数中的Monitor列表中的每个Monitor对象),看它们的ValueIsExcessive值,如果此值为true,则会log到ULS中去。
      这里,就需要我们编写用户自定义的Monitor对象了,它继承自接口ISPScopedPerformanceMonitor,其代码如下:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.Utilities;

namespace CopyListContent
{
    public class CustomerMonitor : ISPScopedPerformanceMonitor
    {
        static int s_times; //定义一个静态变量来存放使用次数
        static CustomerMonitor()
        {
            s_times = 0;
        }
        public CustomerMonitor()
        {
            s_times++; //累积使用次数,每次调用此构造函数时就加一
        }
        public void Dispose() { }
       //出于thread-safe的原因,Description与RenderValueForWeb只能被Sharepoint managed monitors使用,它们不能被custom application代码使用。
        public string Description
        {
            get { return "The Monitor"; }
        }

     //Name属性在logging into到Trace Log的时候使用
        public string Name
        {
            get { return "TheMonitor"; }
        }
   
        public string RenderValueForWeb()
        {
            return string.Format("MONITOR: {0}", s_times);
        }
    //Value用于返回当前的s_times记录值
        public object Value
        {
            get { return s_times; } //返回实际使用的次数
        }
   //ValueIsExcessive用于反映s_times 是否已经超过规定的限度
        public bool ValueIsExcessive
        {
            get { return s_times > 5; } //检查是否超过设定的使用次数
        }
    }
}

   调用它的代码如下:

using (SPMonitoredScope scope =
new SPMonitoredScope("Custom scope"100new CustomMonitor())) 
{
// ...
}

如果你运行上述方法,当你的用户自定义Monitor监控到访问次数超过5次时,它就会立即启动log记录,把日志记录写入ULS logs中,你就可以到ULS中找到关于它的日志记录了。否则,它不会记录到ULS日志中,也即:你无需关心它,因为它没有超过你设置的限度。
     这里还需要注意的是,如果你在SharePoint Foundation > Monitoring category 项设置为Verbose,那么即使你的用户自定义Monitor监控到访问次数"没有"超过5次时,系统还是会启动Log记录,也就是说,系统会记录所有的Monitor内的所有行为,不论此行为是否超出你设定的限度值。
     在 Developer Dashboard的configuration中,还包含一个属性叫AutoLaunch. 如果你设置dashboard 模式为On Demand并且 Auto Launch为 true, 那么Developer Dashboard会在任何关键性事件(在Shaerpoint中定义)被写入ULS日志时都会自动显示出来。
    还有一个有意思的地方是在网上有人发现,SPMonitorScope按微软的说法是不能用于sandboxed solutions的,但是根据MSDN的说明,ISPScopedPerformanceMonitor 接口却可以在sandboxed solutions 中使用,这种情况不知道谁能给个说明。

四、最佳操作建议
 根据微软的建议,我们应使用 SPMonitoredScope 来包装对外部组件(如自定义数据库、外部 Web 服务等)进行的所有调用。这使得管理员能够轻松将这些组件识别为故障点,并快速找出问题。

抱歉!评论已关闭.