1.1安装Nolg
新建一个winform 项目选中引用右键管理Nuget程序包,安装以下2 个dll。
注意安装一定要第二个,不然待会运行程序,你会惊呼,fuck 我的日志呢?安装完毕之后你的程序文件架构应该如下:
1.2 修改配置文件
有特殊需求的小伙伴可以对配置档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 throwExceptions="false" 7 internalLogLevel="Off" internalLogFile="${basedir}/temp/nlog-internal.log"> 8 <targets> 9 <target name="Trace_file" xsi:type="File" fileName="${basedir}/Logs/Trace${date:format=yyyyMMdd}.LOG" 10 layout="${date:format=yyyy}-${date:format=MM}-${date:format=dd} ${date:format=HH}:${date:format=mm}:${date:format=ss}:|${level}| ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> 11 12 <target name="MxForPLC_file" xsi:type="File" fileName="${basedir}/Logs/MxForPLC${date:format=yyyyMMdd}.LOG" 13 layout="${date:format=yyyy}-${date:format=MM}-${date:format=dd} ${date:format=HH}:${date:format=mm}:${date:format=ss}:|${level}| ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> 14 15 <target name="SqlForDB_file" xsi:type="File" fileName="${basedir}/Logs/SqlForDB${date:format=yyyyMMdd}.LOG" 16 layout="${date:format=yyyy}-${date:format=MM}-${date:format=dd} ${date:format=HH}:${date:format=mm}:${date:format=ss}:|${level}| ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> 17 18 <target name="Mat_file" xsi:type="File" fileName="${basedir}/Logs/Mat${date:format=yyyyMMdd}.LOG" 19 layout="${date:format=yyyy}-${date:format=MM}-${date:format=dd} ${date:format=HH}:${date:format=mm}:${date:format=ss}:|${level}| ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> 20 21 <target name="Secs_file" xsi:type="File" fileName="${basedir}/Logs/Secs${date:format=yyyyMMdd}.LOG" 22 layout="${date:format=yyyy}-${date:format=MM}-${date:format=dd} ${date:format=HH}:${date:format=mm}:${date:format=ss}:|${level}| ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> 23 24 </targets> 25 26 <rules> 27 <logger name="Trace" level="Trace" writeTo="Trace_file" /> 28 <logger name="TraceErr" level="Error" writeTo="Trace_file" /> 29 30 <logger name="MxForPLC" level="Trace" writeTo="MxForPLC_file" /> 31 <logger name="MxForPLCErr" level="Error" writeTo="MxForPLC_file" /> 32 33 <logger name="SqlForDB" level="Trace" writeTo="SqlForDB_file" /> 34 <logger name="SqlForDBErr" level="Error" writeTo="SqlForDB_file" /> 35 36 <logger name="Mat" level="Trace" writeTo="Mat_file" /> 37 <logger name="MatErr" level="Error" writeTo="Mat_file" /> 38 39 <logger name="Secs" level="Trace" writeTo="Secs_file" /> 40 <logger name="SecsErr" level="Error" writeTo="Secs_file" /> 41 42 43 </rules> 44 </nlog>
2.1 Nlog的简单加工
其实到此Nlog已经可以记录日志了,Nlog提供了广泛的方法可以使用去记录日志,但是总有奇葩的人提出奇葩的需求:比如希望某些日志记录的时候要显示到界面上,某些日志又不能再界面上显示,这就要对合理的对Nlog提供的最基本的几个方法进行一下二次加工。
新建一个LogHelper类
1 using NLog; 2 using System; 3 4 namespace NLOG 5 { 6 public enum LogLevel 7 { 8 Info = 1,//正常的記錄 對應日誌中的 9 Error = 2//異常的記錄 10 } 11 12 public enum LogType 13 { 14 Trace = 1,//記錄執行信息 15 SqlForDB = 2,//記錄SQL語句 16 MxForPLC = 3,//記錄寫入寫出PLC的原始數據 17 Mat = 4,//記錄物料的信息 18 Secs = 5//記錄Sece原始日誌 19 } 20 21 public class LogHelper 22 { 23 public static void SaveLog(string message, LogLevel logLevel, LogType logType) 24 { 25 try 26 { 27 switch (logType) 28 { 29 case LogType.Trace: 30 if (LogLevel.Info == logLevel) 31 { 32 Logger loggerTrace = LogManager.GetLogger("Trace"); 33 loggerTrace.Trace(message); 34 } 35 else 36 { 37 Logger loggerTraceErr = LogManager.GetLogger("TraceErr"); 38 loggerTraceErr.Error(message); 39 } 40 break; 41 42 case LogType.MxForPLC: 43 if (LogLevel.Info == logLevel) 44 { 45 Logger loggerMxForPLC = LogManager.GetLogger("MxForPLC"); 46 loggerMxForPLC.Trace(message); 47 } 48 else 49 { 50 Logger loggerMxForPLCErr = LogManager.GetLogger("MxForPLCErr"); 51 loggerMxForPLCErr.Error(message); 52 } 53 break; 54 55 case LogType.SqlForDB: 56 if (LogLevel.Info == logLevel) 57 { 58 Logger loggerSqlForDB = LogManager.GetLogger("SqlForDB"); 59 loggerSqlForDB.Trace(message); 60 } 61 else 62 { 63 Logger loggerSqlForDBErr = LogManager.GetLogger("SqlForDBErr"); 64 loggerSqlForDBErr.Error(message); 65 } 66 break; 67 68 case LogType.Mat: 69 if (LogLevel.Info == logLevel) 70 { 71 Logger loggerMat = LogManager.GetLogger("Mat"); 72 loggerMat.Trace(message); 73 } 74 else 75 { 76 Logger loggerMatErr = LogManager.GetLogger("MatErr"); 77 loggerMatErr.Error(message); 78 } 79 break; 80 81 case LogType.Secs: 82 if (LogLevel.Info == logLevel) 83 { 84 Logger loggerSecs = LogManager.GetLogger("Secs"); 85 loggerSecs.Trace(message); 86 } 87 else 88 { 89 Logger loggerSecsErr = LogManager.GetLogger("SecsErr"); 90 loggerSecsErr.Error(message); 91 } 92 break; 93 94 default: 95 if (LogLevel.Info == logLevel) 96 { 97 Logger logger = LogManager.GetLogger("Trace"); 98 logger.Trace(message); 99 } 100 else 101 { 102 Logger logger = LogManager.GetLogger("TraceErr"); 103 logger.Error(message); 104 } 105 break; 106 } 107 } 108 catch (Exception) 109 { 110 throw new Exception("Save Log Error Exception"); 111 } 112 } 113 } 114 }
对于不用显示到界面的日志我们只需要使用一个方法saveLog()就好了,能够实现日志按类型生成,并区分正确和错误的日志。项目中自己去花时间写日志帮助类真的是得不偿失,这将面临多个进程同时写文件程序卡死等一系列麻烦,有很多强大的日志框架供我们使用,除此之外还有Log4NET等。要想在界面输出的话,还要新建一个委托。在界面cs上添加一个listview,点击listview右上角的三角形,选择新加一列。
注意你的listView的视图一定要选择details。
添加以下代码到你的Form1.cs里面去。其中窗体加载事件里面是测试代码。好了这样就实现了部分日志在界面上显示还能记录到日志里面去了。
1 using System; 2 using System.Drawing; 3 using System.Windows.Forms; 4 5 namespace NLOG 6 { 7 public partial class Form1 : Form 8 { 9 public ListViewItem item; 10 11 public Form1() 12 { 13 InitializeComponent(); 14 } 15 16 private void Form1_Load(object sender, EventArgs e) 17 { 18 19 LogHelper.SaveLog("text",LogLevel.Info,LogType.Trace); 20 LogHelper.SaveLog("text", LogLevel.Error, LogType.Trace); 21 LogHelper.SaveLog("text", LogLevel.Info, LogType.SqlForDB); 22 LogHelper.SaveLog("text", LogLevel.Error, LogType.SqlForDB); 23 LogHelper.SaveLog("text", LogLevel.Info, LogType.Secs); 24 LogHelper.SaveLog("text", LogLevel.Error, LogType.Secs); 25 LogHelper.SaveLog("text", LogLevel.Info, LogType.MxForPLC); 26 LogHelper.SaveLog("text", LogLevel.Error, LogType.MxForPLC); 27 LogHelper.SaveLog("text", LogLevel.Info, LogType.Mat); 28 LogHelper.SaveLog("text", LogLevel.Error, LogType.Mat); 29 30 31 FrmWriteLog("123456", LogLevel.Info, LogType.Trace); 32 FrmWriteLog("123456", LogLevel.Error, LogType.Trace); 33 } 34 35 36 37 public void FrmWriteLog(string message, LogLevel logLevel, LogType logType) { 38 39 myUI(message, logLevel, logType, listView1); 40 } 41 42 43 44 45 public delegate void myUICallBack(string myStr, LogLevel level, LogType type, Control ctl); 46 47 public void myUI(string myStr, LogLevel level, LogType type, Control ctl) 48 { 49 if (this.InvokeRequired) 50 { 51 myUICallBack myUpdate = new myUICallBack(myUI); 52 this.Invoke(myUpdate, myStr, level, type, ctl); 53 } 54 else 55 { 56 string nowTime = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]:"); 57 item = new ListViewItem(nowTime + myStr); 58 switch (level) 59 { 60 case LogLevel.Info: 61 item.BackColor = Color.White; 62 break; 63 64 case LogLevel.Error: 65 item.BackColor = Color.Red; 66 break; 67 68 default: 69 item.BackColor = Color.White; 70 break; 71 } 72 switch (type) 73 { 74 case LogType.Trace: 75 LogHelper.SaveLog(myStr, level, LogType.Trace); 76 this.listView1.Items.Add(item); 77 break; 78 79 case LogType.SqlForDB: 80 LogHelper.SaveLog(myStr, level, LogType.SqlForDB); 81 this.listView1.Items.Add(item); 82 break; 83 84 case LogType.MxForPLC: 85 LogHelper.SaveLog(myStr, level, LogType.MxForPLC); 86 this.listView1.Items.Add(item); 87 break; 88 89 case LogType.Mat: 90 LogHelper.SaveLog(myStr, level, LogType.Mat); 91 this.listView1.Items.Add(item); 92 break; 93 94 case LogType.Secs: 95 LogHelper.SaveLog(myStr, level, LogType.Secs); 96 this.listView1.Items.Add(item); 97 break; 98 99 default: 100 LogHelper.SaveLog(myStr, level, LogType.Trace); 101 this.listView1.Items.Add(item); 102 break; 103 } 104 if (this.listView1.Items.Count > 50) 105 { 106 this.listView1.Items.RemoveAt(0); 107 } 108 //滾動到最後一行 109 listView1.Items[listView1.Items.Count - 1].EnsureVisible(); 110 } 111 } 112 } 113 }
效果如下:
错误日志的底色还能显示成不同的颜色。以上代码已经在我多个需要记日志的项目中使用,非常稳定,搭建新项目的时候只要把这部分代码引入就行了!如果你的日志主要输出到界面可以安装最顶部图中的Nlog for WindowsForms的dll,使用起来也很方便。
实例源代码:
链接:https://pan.baidu.com/s/1sVDYaWsZUM1ehn5fGonQqg 密码:wp3u