1

我已经实现了几个“股票”微软代码分析规则。然而,他们缺乏一个领域,即他们没有在捕获中检测到是否实施了日志记录。

所以我的测试项目有这两种方法。我希望看到其中一个引发我的自定义错误,而另一个通过。

public void CatchTestNoLogging()
{
   try
   { string A = "adsf"; }
   catch (Exception ex)
   { throw; }
 }

 public void CatchTestLogging()
 {
    try
    { string A = "adsf"; }
    catch (Exception ex)
    { 
       log.Error("Test Error");
       throw;
     }
  }

我的自定义规则能够检测是否有问题,但我看不到如何检测是否使用了日志记录?

这是自定义规则的 SNIP:

if (iList[i].OpCode == OpCode._Catch)
{
   isCatchExists = true; //this gets hit as I want
   //so the question is what can I do to detect if logging is implemented in the catch?
}

只是一个关于我如何访问的快速指针会很棒。谢谢你

4

1 回答 1

0

出色地,

它并不完美,但这是我得到的。我知道 / 有一个来自谷歌的框架,关于如何寻找一个 catch 块......嗯,这就是我需要的一半,所以我从那里开始,代码看起来像这样:

if (item.OpCode == OpCode._Catch)
{
   isCatchExists = true;
}

因此,我在调试器中逐步查看了与没有日志记录相比,日志记录(log4net)的捕获情况,并查看是否有一些有形的东西跳出来。好吧,我确实找到了这个:

并排

探索 log4net 对象我看到了这个:

在此处输入图像描述

所以我没有看到一种方法来确定 log.error 是否在捕获中,但我可以确定是否存在一个。所以我写了这个:

public override ProblemCollection Check(Member member)
{
   Method method = member as Method;

   bool isCatchExists = false;
   bool isLogError = false;

   if(method != null)
   {
      //Get all the instrections of the method.
      InstructionCollection iList = method.Instructions;

      foreach (Instruction item in iList)
      {
         #region Check For Catch

         if (item.OpCode == OpCode._Catch)
         {
            isCatchExists = true;
         }

         #endregion

         #region Check for Error Logging (log4net)

         if (item.Value != null)
         {

             if (item.OpCode == OpCode.Callvirt && item.Value.ToString() == "log4net.ILog.Error")
             {
               isLogError = true;
             }
         }

         #endregion

      }


      if (isCatchExists && !isLogError)
      {
        Problems.Add(new Problem(this.GetNamedResolution("AddLogging", member.FullName)));
      }
    }
        return this.Problems;
 }

这可行,但有一些警告。

  1. 这被硬编码为 log4net。一个。我不喜欢硬代码,但无论如何我可能会为其他日志记录方法添加不同的规则。

  2. 我无法确定 log.error 是否在 catch 块中。一个。所以一个人可能在 try 块中有一个 log.error 并且我的规则会通过它。

于 2015-05-05T19:50:21.247 回答