Dynamics crm 2011 Dynamics CRM插件登录生产的策略

Dynamics crm 2011 Dynamics CRM插件登录生产的策略,dynamics-crm-2011,dynamics-crm,Dynamics Crm 2011,Dynamics Crm,CRM 2011内部部署 我有一个用C#编写的插件。它可能抛出异常或在生产中表现不好 当这种情况发生时,我希望捕获有关状态和最近代码执行的信息,以帮助我分析问题 理想情况下,我希望: 如果代码决定我应该知道一个问题,那么我希望它能够尽快告诉我有一个问题,而不需要我查看是否发生了问题 我希望有关这个问题的信息对我来说很容易获得。我不想必须RDP到另一台机器并搜索文件 我不希望日志记录对性能有太大影响 我想我在找这样的东西: 在内存中保留最后n行日志 向日志中添加行的单个函数调用 导致记录错误的单

CRM 2011内部部署

我有一个用C#编写的插件。它可能抛出异常或在生产中表现不好

当这种情况发生时,我希望捕获有关状态和最近代码执行的信息,以帮助我分析问题

理想情况下,我希望:

  • 如果代码决定我应该知道一个问题,那么我希望它能够尽快告诉我有一个问题,而不需要我查看是否发生了问题

  • 我希望有关这个问题的信息对我来说很容易获得。我不想必须RDP到另一台机器并搜索文件

  • 我不希望日志记录对性能有太大影响

  • 我想我在找这样的东西:

    • 在内存中保留最后n行日志
    • 向日志中添加行的单个函数调用
    • 导致记录错误的单个函数调用
    • 当出现错误时,给我发电子邮件说有问题。这包含摘要信息
    • 该电子邮件包含指向网页的链接,其中显示了完整的错误详细信息。堆栈跟踪、错误消息、日期、时间、用户等,最后n行日志
    • 如果在某个地方有一个网页可以显示所有的错误,包括过滤、排序等等,那就太好了

    我对CRM相当陌生,但我以前也开发过类似的系统。由于CRM已经存在多年,我希望它可以使用它。

    为了支持您的愿望列表,我将创建以下实体:

    插件日志

    • 包含您希望为成功完成的插件调用保留的任何信息
    • 与插件异常类相关。这样你就可以查到以前发生的事情 发生异常
    插件隔离

    • 包含有关异常的任何特殊信息(用户、上下文、堆栈跟踪)
    现在让我们看看你的愿望清单:

    • 在内存中保留最后n行日志。
      • 不确定是否要记录特定插件类或DLL中定义的所有插件类,我将假定一个特定插件类:
      • 为插件创建一个静态ConcurrentQueue
    • 向日志中添加行的单个函数调用。
      • 创建一个函数,在内存中创建PluginLog实体(不在CRM数据库中创建),并将其添加到队列中
      • 如果长度>n,则退出队列
    • 导致记录错误的单个函数调用。
      • 同样,这是你需要创造的东西。基本上,我会在CRM中创建一个PLuginException实体,然后将所有项目从队列中移出,填充插件异常Id,并将其保存到CRM
    • 出现错误时,给我发电子邮件说有问题。其中包含摘要信息。
      • 只要执行插件的应用程序域上下文具有所需的权限(不确定是否在CRM Online中具有),这应该是微不足道的
    • 该电子邮件包含指向网页的链接,其中显示了完整的错误详细信息。堆栈跟踪、错误消息、日期、时间、用户等,最后n行日志。
      • 您可以创建指向所创建的PluginException实体的链接,并将其与所有其他相关信息一起包含在电子邮件中
    • 如果在某个地方有一个网页可以显示所有错误,包括过滤、排序等,那就太好了。
      • 高级搜救人员
    编辑 为了帮助您入门,我目前使用以下内容从插件上下文检索所有信息,并将其转换为插入到异常中的文本:

    #地区GetPluginInfo
    私有异常GetPluginExecutionInforforLog(IServiceProvider服务提供程序,异常ex)
    {
    if(ex.GetType()==typeof(InvalidPluginExecutionException)){return ex;}
    尝试
    {
    var context=serviceProvider.GetContext();
    ex=新的无效LuginExecutionException(
    Format(“插件执行期间出错:{0}****上下文值****{0}{1}”,
    Environment.NewLine,GetPluginExecutionInfo(context)),ex);
    }
    catch(异常childEx)
    {
    OnError(childEx);
    }
    退换货;
    }
    受保护的字符串GetPluginExecutionInfo(IPluginExecutionContext上下文)
    {
    变量行=新列表();
    var target=GetTarget(上下文);
    添加(“MessageName:+context.MessageName”);
    添加(“PrimaryEntityName:+context.PrimaryEntityName”);
    添加(“PrimaryEntityId:+context.PrimaryEntityId”);
    添加(“BusinessUnitId:+context.BusinessUnitId”);
    添加(“CorrelationId:+context.CorrelationId”);
    添加(“深度:+context.Depth”);
    Add(“具有父上下文:”+(Context.ParentContext!=null));
    添加(“InitiatingUserId:+context.InitiatingUserId”);
    AddParameters(行,context.InputParameters,“输入参数”);
    添加(“IsInTransaction:+context.IsInTransaction”);
    添加(“IsolationMode:+context.IsolationMode”);
    添加(“模式:+context.Mode”);
    添加(“OperationCreatedOn:+context.OperationCreatedOn”);
    添加(“OperationId:+context.OperationId”);
    添加(“组织:“+context.OrganizationName+”(“+context.OrganizationId+”));
    AddParameters(行,context.OutputParameters,“输出参数”);
    AddEntityReference(行,context.OwningExtension,“OwningExtension”);
    AddEntityImages(行、context.PostEntityImages、“Post实体图像”);
    AddEntityImages(行,上下文。PreEntityImages,“预实体图像”
    
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (tracingService == null)
                throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");
            tracingService.Trace("CRMSTClasses.Main_Code.Execute - testing tracing");
    
            throw new InvalidPluginExecutionException("Test exception");
    
    [CRMSTClasses: CRMSTClasses.Main_Code.Receiver]
    [cb42fcb0-0717-e311-9097-0050569274a2: CRMSTClasses.Main_Code.Receiver: Create of incident]
    CRMSTClasses.Main_Code.Execute - testing tracing