0
Dynamic CRM插件中记录日志-Nlog记录到文本 - 流浪阿丁
source link: https://www.cnblogs.com/adingfirstlove/p/16637754.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Dynamic CRM插件中记录日志-Nlog记录到文本
Dynamic CRM插件中记录日志的方式有多种 通常情况下分为ITracingService记录、单独日志表插入记录、文本记录三种。
之前整理过ITracingService记录的方式,但这种记录有限制,只有存在异常时才会在插件跟踪日志中查到,异常报错时排查问题到可以,但插件详细的日志记录查看就不很方便,并且插件跟踪日志中记录到最上层的插件,直接通过插件名查询不方便。
单独日志表的方式,也很简单,自定义一个日志表,在插件中调用封装好的日志插入方法即可,但这个存在一个致命的问题,像是普通的信息记录没问题,若存在异常,插入操作会回滚,所以无法通过这种记录排查异常。
第三种文本记录,需要引用第三方组件,比如Nlog或者Lognet4,我使用的Nlog
Nlog日志记录单例类早就有封装,可以在插件程序集中直接引用过来,最核心的地方就是Nlog的config文件,在插件程序集中不需要单独放置一份NLog.config,只需要在CRM的应用服务的Dynamics 365\CRMWeb\bin文件夹中放置好即可,并且保证CRMWeb里bin中的NLog.dll与插件程序集中引用的版本一致
提示:
1.通常服务器上CRMWeb路径为:C:\Program Files\Dynamics 365\CRMWeb\bin
2.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 <!-- Use below one for debugging--> 8 <!--nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 9 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 10 xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" 11 autoReload="true" 12 throwExceptions="true" 13 internalLogLevel="Trace" 14 internalLogFile="c:\temp\nlog-internal.log"--> 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 <!-- ${basedir} --> 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 <!-- ${basedir} --> 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 <!-- Add custom rule here --> 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 <!-- Add default XrmTrace logging rule "*" here if you want to override in production--> 70 71 </rules> 72 </nlog>
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK