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 /// <summary>
- 2 /// Nlog日志帮助类
- 3 /// </summary>
- 4 public class LoggerHelper
- 5 {
- 6 #region 单例模式
- 7 private LoggerHelper()
- 8 {
- 9 }
- 10 private static readonly object LockObj = new object();
- 11 private static LoggerHelper _instance;
- 12
- 13 /// <summary>
- 14 /// 获得对象实例
- 15 /// </summary>
- 16 public static LoggerHelper Instance
- 17 {
- 18 get
- 19 {
- 20 lock (LockObj)
- 21 {
- 22 if (_instance == null)
- 23 {
- 24 _instance = new LoggerHelper();
- 25 }
- 26 return _instance;
- 27 }
- 28 }
- 29 }
- 30
- 31 #endregion 单例模式
- 32
- 33 #region 属性
- 34
- 35 private Logger _log;
- 36 /// <summary>
- 37 /// 日志实例
- 38 /// </summary>
- 39 public Logger Log
- 40 {
- 41 get
- 42 {
- 43 if (_log == null) _log = LogManager.GetCurrentClassLogger();
- 44 return _log;
- 45 }
- 46 private set { _log = value; }
- 47 }
- 48 #endregion 属性
- 49
- 50 #region 方法
- 51
- 52 #region 普通方式
- 53 public void Debug(string msg)
- 54 {
- 55 Log.Debug(msg);
- 56 }
- 57 public void Debug(string msg, params object[] args)
- 58 {
- 59 Log.Debug(msg, args);
- 60 }
- 61 public void Debug(string msg, Exception ex)
- 62 {
- 63 Log.Debug(ex, msg);
- 64 }
- 65 public void Warn(string msg)
- 66 {
- 67 Log.Warn(msg);
- 68 }
- 69 public void Warn(string msg, params object[] args)
- 70 {
- 71 Log.Warn(msg, args);
- 72 }
- 73 public void Warn(string msg, Exception ex)
- 74 {
- 75 Log.Warn(ex, msg);
- 76 }
- 77 public void Trace(string msg)
- 78 {
- 79 Log.Trace(msg);
- 80 }
- 81 public void Trace(string msg, params object[] args)
- 82 {
- 83 Log.Trace(msg, args);
- 84 }
- 85 public void Trace(string msg, Exception ex)
- 86 {
- 87 Log.Trace(ex, msg);
- 88 }
- 89 public void Fatal(string msg, params object[] args)
- 90 {
- 91 Log.Fatal(msg, args);
- 92 }
- 93
- 94 public void Fatal(string msg, Exception ex)
- 95 {
- 96 Log.Fatal(ex, msg);
- 97 }
- 98 #endregion 普通方式
- 99
- 100 #region 运行时日志
- 101 /// <summary>
- 102 /// 运行时日志
- 103 /// </summary>
- 104 /// <param name="msg">记录的信息</param>
- 105 public void Info(string msg)
- 106 {
- 107 LogEventInfo logInfo = SetCustomInfo(LogLevel.Info, "Runlog", msg);
- 108 Log.Log(LogLevel.Info, logInfo);
- 109 }
- 110 #endregion 运行时日志
- 111
- 112 #region 错误日志
- 113 /// <summary>
- 114 /// 错误记录
- 115 /// </summary>
- 116 /// <param name="msg">方法名</param>
- 117 /// <param name="ex">异常</param>
- 118 public void Error(string msg)
- 119 {
- 120 LogEventInfo logInfo = SetCustomInfo(LogLevel.Error, "ExceptionLogger", msg);
- 121 logInfo.Properties["ErrorHead"] = "程序发生错误:";
- 122 Log.Log(LogLevel.Error, logInfo);
- 123 }
- 124 /// <summary>
- 125 /// 错误记录
- 126 /// </summary>
- 127 /// <param name="msg">方法名</param>
- 128 /// <param name="ex">异常</param>
- 129 public void Error(string msg, Exception ex)
- 130 {
- 131 LogEventInfo logInfo = SetCustomInfo(LogLevel.Error, "ExceptionLogger", msg);
- 132 logInfo.Properties["ErrorHead"] = "程序发生错误:";
- 133 logInfo.Exception = ex;
- 134 Log.Log(LogLevel.Error, logInfo);
- 135 }
- 136 #endregion 错误日志
- 137
- 138 #region 私有方法
- 139 /// <summary>
- 140 /// 设置自定义日志事件
- 141 /// </summary>
- 142 /// <param name="level"></param>
- 143 /// <param name="loggerName"></param>
- 144 /// <param name="message"></param>
- 145 /// <param name="customPropertie"></param>
- 146 /// <param name="customPropertieValue"></param>
- 147 /// <returns></returns>
- 148 private LogEventInfo SetCustomInfo(LogLevel level, string loggerName, string message, string customPropertie = "", string customPropertieValue = "")
- 149 {
- 150 LogEventInfo ei = new LogEventInfo(level, loggerName, message); //也可以用LogEventInfo.Create(level, loggerName, message);
- 151 if (!string.IsNullOrEmpty(customPropertie) && !string.IsNullOrEmpty(customPropertieValue))
- 152 ei.Properties[customPropertie] = customPropertieValue;
- 153 return ei;
- 154
- 155 }
- 156 #endregion 私有方法
- 157
- 158 #endregion 方法
复制代码 NLog.config配置:- 1 <?xml version="1.0" encoding="utf-8" ?>
- 2 <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
- 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 4 xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
- 5 autoReload="true">
- 6
- 7
- 8
- 15
- 16 <extensions>
- 17 <add assembly="Microsoft.Xrm.Log"/>
- 18 </extensions>
- 19
- 20 <variable name="floderInfo" value="Info"/>
- 21 <variable name="floderError" value="Error"/>
- 22
- 23 <targets>
- 24 <target name="XrmTraceETWTarget" xsi:type="XrmTraceETWTarget" />
- 25
- 26 <target name="DataProviderExecutionETWTarget" xsi:type="DataProviderExecutionETWTarget" />
- 27
- 28 <target name="XrmTraceFileTarget" xsi:type="File"
- 29 layout="${longdate}|${logger}|${level:uppercase=true}|${message}|${all-event-properties}|${exception:format=tostring}"
- 30 fileName="D:/CrmLog/logs/logfile.txt"
- 31 archiveFileName="D:/CrmLog/archives/log.{#####}.txt"
- 32 archiveAboveSize="1024000"
- 33 archiveNumbering="Sequence"
- 34 concurrentWrites="true"
- 35 keepFileOpen="false"
- 36 encoding="utf-8" />
- 37
- 38 <target name="debug_info_file" xsi:type="File"
- 39 layout="${longdate}|${logger}|${level:uppercase=true}|${message}|${all-event-properties}|${exception:format=tostring}"
- 40 fileName="D:/CrmLog/logs/${floderInfo}/${shortdate}.txt"
- 41 archiveFileName="D:/CrmLog/archives/${shortdate}.{#####}.txt"
- 42 archiveAboveSize="1024000"
- 43 archiveNumbering="Sequence"
- 44 concurrentWrites="true"
- 45 keepFileOpen="false"
- 46 encoding="utf-8" />
- 47
- 48 <target name="error_file" xsi:type="File"
- 49 layout="${newline}${longdate} ${level:uppercase=true} ${event-context:item=ErrorHead}${newline} ${message} 发生异常: ${onexception:${exception:format=tostring} ${newline} 堆栈信息为: ${stacktrace} ${newline}------------------------------------ "
- 50 fileName="D:/CrmLog/Logs/${floderError}/${shortdate}.txt"
- 51 archiveFileName="D:/CrmLog/archives/${floderError}/${shortdate}.{#####}.txt"
- 52 archiveAboveSize="1024000"
- 53 archiveNumbering="Sequence"
- 54 concurrentWrites="true"
- 55 keepFileOpen="false"
- 56 encoding="utf-8"/>
- 57
- 58 </targets>
- 59
- 60
- 61
- 62 <rules>
- 63
- 64 <logger name="Microsoft.Xrm.DataProvider*" minLevel="Debug" writeTo="DataProviderExecutionETWTarget" final="true"/>
- 65 <logger name="Microsoft.Xrm.DataPipeline" minLevel="Debug" writeTo="DataProviderExecutionETWTarget" final="true"/>
- 66 <logger name="*" minLevel="Debug" writeTo="debug_info_file" />
- 67 <logger name="*" levels="Error" writeTo="error_file" />
- 68
- 69
- 70
- 71 </rules>
- 72 </nlog>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |