首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 錯誤日誌記錄完整實作:Global.asax 捕獲、每日分檔、友善錯誤頁面

     編輯:ASP.NET 基礎

架構概覽

建立健全的錯誤記錄機制包含三大支柱:

  1. 統一擷取:Global.asax Application_Error 攔截所有未處理例外。
  2. 結構化記錄:靜態輔助類別寫入每日分檔文字日誌,含 IP、URL、堆疊追蹤。
  3. 使用者友善:web.config <customErrors> 導向自訂錯誤頁,避免暴露敏感資訊。

核心程式碼實作

1. 日誌寫入器 (App_Code/Logger.cs 或獨立類別庫)

using System;
using System.IO;
using System.Web;
using System.Globalization;

public static class Logger
{
    public static void WriteError(string errorMessage)
    {
        try
        {
            // 每日一檔:yyMMdd.txt (如 240115.txt)
            var fileName = DateTime.Today.ToString("yyMMdd") + ".txt";
            var virtualPath = "~/Error/" + fileName;
            var physicalPath = HttpContext.Current.Server.MapPath(virtualPath);

            // 確保目錄存在
            var dir = Path.GetDirectoryName(physicalPath);
            if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);

            // 追加寫入,自動建立檔案
            using (var sw = File.AppendText(physicalPath))
            {
                sw.WriteLine("\r\n--- Log Entry ---");
                sw.WriteLine(DateTime.Now.ToString(CultureInfo.InvariantCulture));
                sw.WriteLine(errorMessage);
                sw.WriteLine(new string('_', 60));
            }
        }
        catch (Exception ex)
        {
            // 寫入失敗最後防線:輸出到系統診斷追蹤,避免遞迴
            System.Diagnostics.Trace.TraceError($"Logger.WriteError 失敗: {ex}");
        }
    }
}

2. Global.asax 統一錯誤處理

void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError().GetBaseException(); // 取得根本原因
    var ip = Request.UserHostAddress;
    var url = Request.Url.ToString();
    var msg = ex.Message;

    var logEntry = $"IP【{ip}】{Environment.NewLine}" +
                   $"URL【{url}】{Environment.NewLine}" +
                   $"Message【{msg}】{Environment.NewLine}" +
                   $"StackTrace【{ex.StackTrace}】";

    Logger.WriteError(logEntry);

    // 可選:發送郵件通知管理員、記錄到資料庫等
    // 清除錯誤,避免 ASP.NET 預設黃色死機畫面 (由 customErrors 接管導向)
    Server.ClearError();
}

3. Web.config 設定自訂錯誤頁面

<system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/Error/GenericErrorPage.htm">
        <!-- 可針對特定狀態碼客製化 -->
        <error statusCode="404" redirect="~/Error/404.htm" />
        <error statusCode="500" redirect="~/Error/500.htm" />
    </customErrors>
    <!-- 開發時期建議 Off 以看詳細錯誤,上線改 RemoteOnly 或 On -->
</system.web>

4. 友善錯誤頁面範例 (Error/GenericErrorPage.htm)

<!DOCTYPE html>
<html><head><title>系統發生錯誤</title>
<style>body{font-family:sans-serif;max-width:600px;margin:3rem auto;padding:1rem;text-align:center;} .code{font-family:monospace;background:#f4f4f4;padding:.2rem .5rem;border-radius:4px;}</style></head><body>
    <h1>😞 系統暫時無法處理您的請求</h1>
    <p>我們已記錄此錯誤 (參考代碼: <%= DateTime.Now.Ticks %>) 並通知技術團隊儘快處理。</p>
    <p><a href="javascript:history.back()">返回上一頁</a> | <a href="/>回首頁</a></p>
</body></html>

進階強化建議

維度建議做法工具/套件
結構化查詢改寫 JSON 格式或直接寫入資料庫 (SQL/Elasticsearch)Serilog, NLog, log4net
即時告警整合 Email/Slack/DingTalk Webhook 於 WriteError 例外處理中FluentEmail, WebhookClient
效能與非阻塞使用非同步寫入或背景佇列 (Channel/BlockingCollection)System.Threading.Channels
敏感資料過濾記錄前移除密碼、Token、信用卡號等 (GDPR/個資法遵循)自訂 Scrubber / Serilog Enrichers
雲端部署輸出到 stdout/stderr,由容器日誌驅動程式收集 (Docker/K8s)Serilog.Sinks.Console

常見坑點提醒

  • 遞迴寫入:WriteError 內部拋出例外再呼叫自己 → StackOverflow。務必用 Trace.TraceError 或寫入 Windows Event Log 作為最後防線。
  • 權限不足:IIS 應用程式集區身分需具備 ~/Error/ 目錄寫入權限。
  • 大量錯誤洪水:考慮加入速率限制或取樣記錄,避免磁碟塞滿。

這套機制輕量、零依賴、易部署,適合中小型專案快速落地;大型系統建議直接採用成熟記錄框架 (Serilog/NLog) 並整合集中式日誌平台。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved