iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
1
Modern Web

打net core肉飯系列 第 13

[2020鐵人賽] Day13 - NLog設定(2/2)

  • 分享至 

  • xImage
  •  

在上一篇中講解如何做基本的nlog設定檔與建立共用的BaseLog類別,用以處理各種log的寫入。這邊就要來講如何跟.net core MVC互相配合,在甚麼時機點去紀錄log,以快速trace、解決問題。

主要會記錄下列幾項資訊:

  • 使用者的行為:哪個使用者執行了甚麼Controller/Action
  • 發生了錯誤:哪個使用者碰到了甚麼exception
  • SQL語法:哪個使用者執行了哪些SQL指令

使用者的行為
由於現在是使用.net core的Controller類別,跟以前.net framework MVC不太一樣,我們要建立一個BaseCotroller繼承Controller,並且複寫OnActionExecuting與OnActionExecuted方法,執行完再執行底層方法,以下參考官方文件。

public class Test2Controller : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        WriteLog(string.Format("進入點執行了甚麼:{0}",context.HttpContext.Request.Path));
        //執行底層方法
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        WriteLog(string.Format("進入點結束:{0}",context.HttpContext.Request.Path));
        //執行底層方法
        base.OnActionExecuted(context);
    }
}

發生了錯誤
以前.net framework MVC有一個方法叫做OnException,但.net core Controller類別沒有這個方法,必須寫在StartUp中設定,會使用Lambda,以下參考官方文件。

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
   app.UseExceptionHandler(errorApp =>
   {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = 500;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("發生錯誤!<br><br>\r\n");

            var exceptionHandlerPathFeature = 
                context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
               WriteLog(string.Format("發生錯誤訊息!:{0}",ex.ToString()));
            }

            await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n");
            await context.Response.WriteAsync(new string(' ', 512)); // IE padding
        });
    });
    app.UseHsts();
}

SQL語法
還記得在Model的第三個部分有建立底層的資料處理方法,執行Dapper前先執行Execute與Query方法,這邊就直接把WriteLog程式寫在這兩個方法就可以記錄執行過的SQL指令!

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
using Dapper;

namespace IronMan
{
    public class DataControl : IDisposable
    {
        private IDbConnection db = null;
        private string _connectStr;
        
        //建構子初始化連線字串/DB連接
        public DataControl()
        {
            string connectionStr = @"放上你的資料庫連線字串";
            _connectStr = connectionStr;
            db = new SqlConnection(_connectStr);
        }

        //共用查詢方法
        public IEnumerable<T> Query<T>(string sql,object param)
        {
        //這邊寫下Log紀錄,param參數可使用reflection.PropertyInfo來解析出來
        WriteLog(string.Format("執行了:{0}",sql));
            return db.Query<T>(sql, param).ToList();
        }

        //共用新增刪除修改方法
        public int Execute(string sql, object param)
        {
        //這邊寫下Log紀錄,param參數可使用reflection.PropertyInfo來解析出來
        WriteLog(string.Format("執行了:{0}",sql));
            return db.Execute(sql, param);
        }

        //釋放連接
        public void Dispose()
        {
            db.Dispose();
        }
    }
}

參考資料
https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1
https://docs.microsoft.com/zh-tw/aspnet/core/mvc/controllers/filters?view=aspnetcore-3.1


上一篇
[2020鐵人賽] Day12 - NLog設定(1/2)
下一篇
[2020鐵人賽] Day14 - 使用Razor語法
系列文
打net core肉飯30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言