Dynamic CRM插件中记录日志-Nlog记录到文本

王柳  金牌会员 | 2022-9-16 17:24:17 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 896|帖子 896|积分 2688

Dynamic CRM插件中记录日志的方式有多种 通常情况下分为ITracingService记录、单独日志表插入记录、文本记录三种。之前整理过ITracingService记录的方式,但这种记录有限制,只有存在异常时才会在插件跟踪日志中查到,异常报错时排查问题到可以,但插件详细的日志记录查看就不很方便,并且插件跟踪日志中记录到最上层的插件,直接通过插件名查询不方便。 单独日志表的方式,也很简单,自定义一个日志表,在插件中调用封装好的日志插入方法即可,但这个存在一个致命的问题,像是普通的信息记录没问题,若存在异常,插入操作会回滚,所以无法通过这种记录排查异常。 第三种文本记录,需要引用第三方组件,比如Nlog或者Lognet4,我使用的NlogNlog日志记录单例类早就有封装,可以在插件程序集中直接引用过来,最核心的地方就是Nlog的config文件,在插件程序集中不需要单独放置一份NLog.config,只需要在CRM的应用服务的Dynamics 365\CRMWeb\bin文件夹中放置好即可,并且保证CRMWeb里bin中的NLog.dll与插件程序集中引用的版本一致提示:1.通常服务器上CRMWeb路径为:C:\Program Files\Dynamics 365\CRMWeb\bin2.NLog.config中具体指明一下文件存放的路径  
 
附上NLog帮助类和服务器上NLog.config配置:
  1.   1     /// <summary>
  2.   2     /// Nlog日志帮助类
  3.   3     /// </summary>
  4.   4     public class LoggerHelper
  5.   5     {
  6.   6         #region 单例模式
  7.   7         private LoggerHelper()
  8.   8         {
  9.   9         }
  10. 10         private static readonly object LockObj = new object();
  11. 11         private static LoggerHelper _instance;
  12. 12
  13. 13         /// <summary>
  14. 14         /// 获得对象实例
  15. 15         /// </summary>
  16. 16         public static LoggerHelper Instance
  17. 17         {
  18. 18             get
  19. 19             {
  20. 20                 lock (LockObj)
  21. 21                 {
  22. 22                     if (_instance == null)
  23. 23                     {
  24. 24                         _instance = new LoggerHelper();
  25. 25                     }
  26. 26                     return _instance;
  27. 27                 }
  28. 28             }
  29. 29         }
  30. 30
  31. 31         #endregion 单例模式
  32. 32
  33. 33         #region 属性
  34. 34
  35. 35         private Logger _log;
  36. 36         /// <summary>
  37. 37         /// 日志实例
  38. 38         /// </summary>
  39. 39         public Logger Log
  40. 40         {
  41. 41             get
  42. 42             {
  43. 43                 if (_log == null) _log = LogManager.GetCurrentClassLogger();
  44. 44                 return _log;
  45. 45             }
  46. 46             private set { _log = value; }
  47. 47         }
  48. 48         #endregion 属性
  49. 49
  50. 50         #region 方法
  51. 51
  52. 52         #region 普通方式
  53. 53         public void Debug(string msg)
  54. 54         {
  55. 55             Log.Debug(msg);
  56. 56         }
  57. 57         public void Debug(string msg, params object[] args)
  58. 58         {
  59. 59             Log.Debug(msg, args);
  60. 60         }
  61. 61         public void Debug(string msg, Exception ex)
  62. 62         {
  63. 63             Log.Debug(ex, msg);
  64. 64         }
  65. 65         public void Warn(string msg)
  66. 66         {
  67. 67             Log.Warn(msg);
  68. 68         }
  69. 69         public void Warn(string msg, params object[] args)
  70. 70         {
  71. 71             Log.Warn(msg, args);
  72. 72         }
  73. 73         public void Warn(string msg, Exception ex)
  74. 74         {
  75. 75             Log.Warn(ex, msg);
  76. 76         }
  77. 77         public void Trace(string msg)
  78. 78         {
  79. 79             Log.Trace(msg);
  80. 80         }
  81. 81         public void Trace(string msg, params object[] args)
  82. 82         {
  83. 83             Log.Trace(msg, args);
  84. 84         }
  85. 85         public void Trace(string msg, Exception ex)
  86. 86         {
  87. 87             Log.Trace(ex, msg);
  88. 88         }
  89. 89         public void Fatal(string msg, params object[] args)
  90. 90         {
  91. 91             Log.Fatal(msg, args);
  92. 92         }
  93. 93
  94. 94         public void Fatal(string msg, Exception ex)
  95. 95         {
  96. 96             Log.Fatal(ex, msg);
  97. 97         }
  98. 98         #endregion 普通方式
  99. 99
  100. 100         #region 运行时日志
  101. 101         /// <summary>
  102. 102         /// 运行时日志
  103. 103         /// </summary>
  104. 104         /// <param name="msg">记录的信息</param>
  105. 105         public void Info(string msg)
  106. 106         {
  107. 107             LogEventInfo logInfo = SetCustomInfo(LogLevel.Info, "Runlog", msg);
  108. 108             Log.Log(LogLevel.Info, logInfo);
  109. 109         }
  110. 110         #endregion 运行时日志
  111. 111
  112. 112         #region 错误日志
  113. 113         /// <summary>
  114. 114         /// 错误记录
  115. 115         /// </summary>
  116. 116         /// <param name="msg">方法名</param>
  117. 117         /// <param name="ex">异常</param>
  118. 118         public void Error(string msg)
  119. 119         {
  120. 120             LogEventInfo logInfo = SetCustomInfo(LogLevel.Error, "ExceptionLogger", msg);
  121. 121             logInfo.Properties["ErrorHead"] = "程序发生错误:";
  122. 122             Log.Log(LogLevel.Error, logInfo);
  123. 123         }
  124. 124         /// <summary>
  125. 125         /// 错误记录
  126. 126         /// </summary>
  127. 127         /// <param name="msg">方法名</param>
  128. 128         /// <param name="ex">异常</param>
  129. 129         public void Error(string msg, Exception ex)
  130. 130         {
  131. 131             LogEventInfo logInfo = SetCustomInfo(LogLevel.Error, "ExceptionLogger", msg);
  132. 132             logInfo.Properties["ErrorHead"] = "程序发生错误:";
  133. 133             logInfo.Exception = ex;
  134. 134             Log.Log(LogLevel.Error, logInfo);
  135. 135         }
  136. 136         #endregion 错误日志
  137. 137
  138. 138         #region 私有方法
  139. 139         /// <summary>
  140. 140         /// 设置自定义日志事件
  141. 141         /// </summary>
  142. 142         /// <param name="level"></param>
  143. 143         /// <param name="loggerName"></param>
  144. 144         /// <param name="message"></param>
  145. 145         /// <param name="customPropertie"></param>
  146. 146         /// <param name="customPropertieValue"></param>
  147. 147         /// <returns></returns>
  148. 148         private LogEventInfo SetCustomInfo(LogLevel level, string loggerName, string message, string customPropertie = "", string customPropertieValue = "")
  149. 149         {
  150. 150             LogEventInfo ei = new LogEventInfo(level, loggerName, message); //也可以用LogEventInfo.Create(level, loggerName, message);
  151. 151             if (!string.IsNullOrEmpty(customPropertie) && !string.IsNullOrEmpty(customPropertieValue))
  152. 152                 ei.Properties[customPropertie] = customPropertieValue;
  153. 153             return ei;
  154. 154
  155. 155         }
  156. 156         #endregion 私有方法
  157. 157
  158. 158         #endregion 方法
复制代码
NLog.config配置:
  1. 1 <?xml version="1.0" encoding="utf-8" ?>
  2. 2 <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. 3       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. 4       xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
  5. 5       autoReload="true">
  6. 6
  7. 7   
  8. 8   
  9. 15
  10. 16   <extensions>
  11. 17     <add assembly="Microsoft.Xrm.Log"/>
  12. 18   </extensions>
  13. 19   
  14. 20   <variable name="floderInfo" value="Info"/>
  15. 21   <variable name="floderError" value="Error"/>
  16. 22   
  17. 23   <targets>
  18. 24     <target name="XrmTraceETWTarget" xsi:type="XrmTraceETWTarget" />
  19. 25
  20. 26     <target name="DataProviderExecutionETWTarget" xsi:type="DataProviderExecutionETWTarget" />
  21. 27     
  22. 28     <target name="XrmTraceFileTarget" xsi:type="File"
  23. 29         layout="${longdate}|${logger}|${level:uppercase=true}|${message}|${all-event-properties}|${exception:format=tostring}"
  24. 30         fileName="D:/CrmLog/logs/logfile.txt"
  25. 31         archiveFileName="D:/CrmLog/archives/log.{#####}.txt"
  26. 32         archiveAboveSize="1024000"
  27. 33         archiveNumbering="Sequence"
  28. 34         concurrentWrites="true"
  29. 35         keepFileOpen="false"
  30. 36         encoding="utf-8" />
  31. 37     
  32. 38     <target name="debug_info_file" xsi:type="File"
  33. 39         layout="${longdate}|${logger}|${level:uppercase=true}|${message}|${all-event-properties}|${exception:format=tostring}"
  34. 40         fileName="D:/CrmLog/logs/${floderInfo}/${shortdate}.txt"
  35. 41         archiveFileName="D:/CrmLog/archives/${shortdate}.{#####}.txt"
  36. 42         archiveAboveSize="1024000"
  37. 43         archiveNumbering="Sequence"
  38. 44         concurrentWrites="true"
  39. 45         keepFileOpen="false"
  40. 46         encoding="utf-8" />
  41. 47     
  42. 48     <target name="error_file" xsi:type="File"
  43. 49         layout="${newline}${longdate} ${level:uppercase=true} ${event-context:item=ErrorHead}${newline} ${message} 发生异常: ${onexception:${exception:format=tostring} ${newline} 堆栈信息为: ${stacktrace} ${newline}------------------------------------ "
  44. 50         fileName="D:/CrmLog/Logs/${floderError}/${shortdate}.txt"
  45. 51         archiveFileName="D:/CrmLog/archives/${floderError}/${shortdate}.{#####}.txt"
  46. 52         archiveAboveSize="1024000"
  47. 53         archiveNumbering="Sequence"
  48. 54         concurrentWrites="true"
  49. 55         keepFileOpen="false"
  50. 56         encoding="utf-8"/>
  51. 57     
  52. 58   </targets>
  53. 59
  54. 60
  55. 61
  56. 62   <rules>
  57. 63     
  58. 64     <logger name="Microsoft.Xrm.DataProvider*" minLevel="Debug" writeTo="DataProviderExecutionETWTarget" final="true"/>
  59. 65     <logger name="Microsoft.Xrm.DataPipeline" minLevel="Debug" writeTo="DataProviderExecutionETWTarget" final="true"/>
  60. 66     <logger name="*" minLevel="Debug" writeTo="debug_info_file" />
  61. 67     <logger name="*" levels="Error" writeTo="error_file" />
  62. 68
  63. 69     
  64. 70
  65. 71   </rules>
  66. 72 </nlog>
复制代码
 
      
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表