1. 程式人生 > >C#將執行異常寫成日誌檔案

C#將執行異常寫成日誌檔案

我們在程式編寫中,一些尚未測試出來的錯誤很可能在使用者使用的過程中報異常,讓使用者來面向異常這是不友好的。將異常寫成日誌既不給使用者造成壓力又方便維護人員調改程式碼

思維導圖


顯示並忽略

        這個是最簡單的用一個try。。。catch。。。finally即可,這也是身為一個專業的程式設計師最不靠譜的

寫成日誌檔案

1)EventLog類

格式

using System.Diagnostics;//引用空間名稱
EventLog errLog = new EventLog();
errLog.Source =”事件的源名稱";
errLog.WriteEntry("寫入日誌檔案失敗,原因:" + ex.Message);

Demo
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1//引入名稱空間
{
    class Program
    {
        static void Main(string[] args)
        {
            EventLog log = new EventLog();
            try
            {
                log.Source = "系統2";  //在檢視系統日誌能夠迅速找到有問題的軟體源頭
                log.WriteEntry("處理資訊1", EventLogEntryType.Information);
                log.WriteEntry("處理資訊2", EventLogEntryType.Information);
                throw new System.IO.FileNotFoundException("readme.txt檔案未找到");
            }
            catch (System.IO.FileNotFoundException exception)
            {
                log.WriteEntry("處理資訊2", EventLogEntryType.Error);
            }

        }
    }
}
效果圖

在Windows日誌中檢視系統自帶的,具體開啟控制面板——工具管理——事件檢視器——Windows日誌——應用程式

雙擊進去即可看見錯誤了

需要注意的:

1)一定要引入名稱空間diagnostics

2)source屬性一定要寫且命名規範方便查詢

3)一定要用管理員許可權執行,不然會報下面的錯誤

2)自定義類

模板

/// <summary>
/// 將異常列印到LOG檔案
/// </summary>
/// <param name="ex">異常</param>
/// <param name="LogAddress">日誌檔案地址</param>
public static void WriteLog(Exception ex, string LogAddress = "")
{
    //如果日誌檔案為空,則預設在Debug目錄下新建 YYYY-mm-dd_Log.log檔案
    if (LogAddress == "")
    {
        LogAddress = Environment.CurrentDirectory + '\\' +
            DateTime.Now.Year + '-' +
            DateTime.Now.Month + '-' +
            DateTime.Now.Day + "_Log.log";
    }
    //把異常資訊輸出到檔案
    StreamWriter fs = new StreamWriter(LogAddress, true);
    fs.WriteLine("當前時間:" + DateTime.Now.ToString());
    fs.WriteLine("異常資訊:" + ex.Message);
    fs.WriteLine("異常物件:" + ex.Source);
    fs.WriteLine("呼叫堆疊:\n" + ex.StackTrace.Trim());
    fs.WriteLine("觸發方法:" + ex.TargetSite);
    fs.WriteLine();
    fs.Close();
}
Demo
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            int i;
            int j;

            try//隨意寫了一個有錯誤的小程式,錯誤是除數為零
            {

                i = 0;
                j = 2 / i;

            }
            catch (Exception ex)
            {

                WriteLog(ex); //呼叫自己寫的方法,需要傳參,如果第二個為空則預設到debug下,引數的具體格式參照下面的註釋



            }
            finally //不受錯誤影響繼續執行
            {
                j = 2 / 1;
                Console.Write(j);
                Console.ReadLine();
            }
           
        }

        /// <summary>
        /// 將異常列印到LOG檔案
        /// </summary>
        /// <param name="ex">異常</param>
        /// <param name="LogAddress">日誌檔案地址</param>
        public static void WriteLog(Exception ex, string LogAddress = "")
        {
            //如果日誌檔案為空,則預設在Debug目錄下新建 YYYY-mm-dd_Log.log檔案
            if (LogAddress == "")
            {
                LogAddress = Environment.CurrentDirectory + '\\' +
                    DateTime.Now.Year + '-' +
                    DateTime.Now.Month + '-' +
                    DateTime.Now.Day + "_Log.log";
            }
            //把異常資訊輸出到檔案,因為異常檔案由這幾部分組成,這樣就不用我們自己複製到文件中了
            StreamWriter fs = new StreamWriter(LogAddress, true);
            fs.WriteLine("當前時間:" + DateTime.Now.ToString());
            fs.WriteLine("異常資訊:" + ex.Message);
            fs.WriteLine("異常物件:" + ex.Source);
            fs.WriteLine("呼叫堆疊:\n" + ex.StackTrace.Trim());
            fs.WriteLine("觸發方法:" + ex.TargetSite);
            fs.WriteLine();
            fs.Close();
        }

    }
}

效果圖

        看起來是不是很爽

二者的比較

        首先兩個都是比較好用方便的,但是相對於靈活性而言自定義類略勝一籌