http://blog.kkbruce.net/2011/11/aspnet-mvc-log.html#.VGFhafmUdBH
ASP.NET MVC - 凡走過,必留下痕跡之LOG記錄
LOG記錄的方式
要留下Log記錄,基本方向可以有:
- System Log記錄
- File Log記錄
- Database Log記錄
- Log Server
System Log記錄指的是像IIS Log記錄就是System Log記錄。或撰寫程式碼,向Windows本身的事件檢視器來發送Log記錄。
File Log記錄指的是透過 System.IO 寫一支程式,將你要的Log記錄到一個純文字檔,例如, FileLogs.txt,因為程式自己寫,你能控制什麼是你要,什麼是你不要,與System Log記錄相比,可以免除太大、太亂的問題。檔案太大還是有可能,這部分可能要寫程式自動處理,或是手動處理。
Database Log記錄,即將Log記錄直接記錄在Database之中,與System Log記錄與File Log記錄相較,Database本來就是儲存與管理資料所在地,而且與撰寫發送Windows Log記錄事件檢視器程式碼和File Log記錄程式碼來看,資料庫 Log記錄程式碼簡單多了。。
Log Server一般而言,是當伺服器群成長到一定數量,會架一台專門處理Log記錄的硬體伺服器,例如,Linux平台的Syslog,Windows下的Kiwi Syslog Server來架設,或是買專門機架硬體式Log Server,來統一收集、分析、管理這些Server Log記錄。
真是可大可小。
以下,我會使用 ASP.NET MVC來實作一個Database Log記錄範例。
DATABASE LOG記錄 - SCHEMA準備
針對我們檔案管理系統部分,我們會有兩張 Table,一張是記錄有權限的人員做了什麼動作,一張是記錄使用者下載了那些資料。
KKBruceFileLog Schema
這是檔案下載的Log記錄表,要注意的只有 HiterIP 長度為 50,為什訂那麼長?我們事先把 IPv6 考慮進去。這樣,不管我們的 .NET Framwork 程式是抓到 IPv4 或 IPv6 ,記錄進資料庫都不會有問題。
05 | /****** Object: Table [dbo].[KKBruceFileLog] Script Date : 11/08/2011 14:31:52 ******/ |
09 | SET QUOTED_IDENTIFIER ON |
12 | CREATE TABLE [dbo].[KKBruceFileLog]( |
13 | [FilesLogId] [ int ] IDENTITY(1,1) NOT NULL , |
14 | [FileId] [ int ] NOT NULL , |
15 | [HiterIP] [nvarchar](50) NOT NULL , |
16 | [CreateTime] [datetime2](7) NOT NULL , |
17 | CONSTRAINT [PK_FilesLogs] PRIMARY KEY CLUSTERED |
20 | ) WITH (PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON ) ON [ PRIMARY ] |
31 | EXEC sys.sp_addextendedproperty @ name =N 'MS_Description' , @value=N '檔案編號' , @level0type=N 'SCHEMA' ,@level0name=N 'dbo' , @level1type=N 'TABLE' ,@level1name=N 'KKBruceFileLog' , @level2type=N 'COLUMN' ,@level2name=N 'FileId' |
34 | EXEC sys.sp_addextendedproperty @ name =N 'MS_Description' , @value=N '檔案下載Log表' , @level0type=N 'SCHEMA' ,@level0name=N 'dbo' , @level1type=N 'TABLE' ,@level1name=N 'KKBruceFileLog' |
37 | ALTER TABLE [dbo].[KKBruceFileLog] WITH CHECK ADD CONSTRAINT [FK_FilesLogs_Files] FOREIGN KEY ([FileId]) |
38 | REFERENCES [dbo].[ProductFile] ([FileId]) |
41 | ALTER TABLE [dbo].[KKBruceFileLog] CHECK CONSTRAINT [FK_FilesLogs_Files] |
44 | ALTER TABLE [dbo].[KKBruceFileLog] ADD CONSTRAINT [DF_FilesLogs_HitIPv4] DEFAULT (N '下載者IPv4' ) FOR [HiterIP] |
KKBruceEmployeeLog Schema
人員Log記錄表,記錄人員操作的任何動作,我們記錄登入人員的Id、動作、說明、IP、時間等資訊。另外補充,為了與 Entity Framework 有比較配合度,日期時間建議使用 datetime2 格式。
05 | /****** Object: Table [dbo].[KKBruceEmployeeLog] Script Date : 11/08/2011 14:44:35 ******/ |
09 | SET QUOTED_IDENTIFIER ON |
12 | CREATE TABLE [dbo].[KKBruceEmployeeLog]( |
13 | [EmployeeLogID] [ int ] IDENTITY(1,1) NOT NULL , |
14 | [EmployeeId] [ int ] NOT NULL , |
15 | [ActionName] [nvarchar](250) NOT NULL , |
16 | [Description] [nvarchar]( max ) NOT NULL , |
17 | [ClientIP] [nvarchar](50) NOT NULL , |
18 | [CreateTime] [datetime2](7) NOT NULL , |
19 | CONSTRAINT [PK_KKBruceEmployeesLogs] PRIMARY KEY CLUSTERED |
22 | ) WITH (PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON ) ON [ PRIMARY ] |
33 | EXEC sys.sp_addextendedproperty @ name =N 'MS_Description' , @value=N '人員Log記錄檔' , @level0type=N 'SCHEMA' ,@level0name=N 'dbo' , @level1type=N 'TABLE' ,@level1name=N 'KKBruceEmployeeLog' |
36 | ALTER TABLE [dbo].[KKBruceEmployeeLog] WITH CHECK ADD CONSTRAINT [FK_EmployeesLogs_Employees] FOREIGN KEY ([EmployeeId]) |
37 | REFERENCES [dbo].[KKBruceEmployee] ([EmployeeId]) |
40 | ALTER TABLE [dbo].[KKBruceEmployeeLog] CHECK CONSTRAINT [FK_EmployeesLogs_Employees] |
ASP.NET MVC實作LOG記錄
如果拿ASP.NET與ASP.NET MVC比較,要在 ASP.NET MVC裡實作Log記錄,老實說,沒有太大難度。因為ASP.NET MVC架構上非常容易實作與執行這一類程式碼。ASP.NET麻煩了些。
什麼「這一類程式碼」?即需要「大量且重覆使用的程式碼」。在ASP.NET MVC裡有個機制稱 ActionFilter,就是專門在處理這種事,透過 ActionFilter 機制,我們可以很容易且簡單的去重覆使用我們的過濾器。因為我們要寫Log記錄,我們可以稱我們寫的為 Log ActionFilter、Log過濾器。
實作人員Log記錄
- 新增一目錄「ActionFilters」→ 新增一類別「EmployeeLogAttribute.vb」→ 繼承「ActionFilterAttribute 屬性類別」→ 覆寫「OnActionExecuting 副程式」。
EmployeeLogAttribute.vb
01 | Public Class EmployeeLogAttribute |
02 | Inherits ActionFilterAttribute |
05 | Public Property Description() As String |
10 | Public Overrides Sub OnActionExecuting(filterContext As ActionExecutingContext) |
12 | If filterContext.HttpContext.User IsNot Nothing Then |
13 | Using db As New KKBruceEntities |
16 | Dim log As New KKBruceEmployeeLog() With |
18 | .EmployeeId = (From e In db.KKBruceEmployee |
19 | Where e.Account = filterContext.HttpContext.User.Identity.Name |
20 | Select e.EmployeeId).First(), |
21 | .ActionName = filterContext.RouteData.Values( "controller" ) & "/" & _ |
22 | filterContext.RouteData.Values( "action" ), |
23 | .Description = Me .Description, |
24 | .ClientIP = filterContext.HttpContext.Request.UserHostAddress, |
25 | .CreateTime = DateTime.Now.ToString() |
29 | db.KKBruceEmployeeLog.Add(log) |
42 | Dim DeleteLogs = From logs In db.KKBruceEmployeeLog |
43 | Where logs.CreateTime <= DateTime.Now.AddMonths(-6) |
50 | For Each DelLog In DeleteLogs |
51 | db.Entry(DelLog).State = EntityState.Deleted |
如果你想測試這一段程式碼,你還必須建立會員登入相關資料表及程式碼才會運作。你可以先
- 註解第12 ( filterContext.HttpContext.User )、18 ( EmployeeId )、55 ( End If )行;
- 還有 KKBruceEmployeeLog Schema 裡的 EmployeeId 也必須把 NOT NULL 關鍵字移除。
先不進行會員相關資料的取得及寫入,即可測試。
使用Log ActionFilter
針對我們寫好的Log ActionFilter,使用有非常簡單,開啟你要設定的 Controller,然後在Action上設定 Log ActionFilter屬性。
上傳檔案Log ActionFilter設定
04 | Function Create(upfile As HttpPostedFileBase) As ActionResult |
11 | Function CreateMultiFile(form As FormCollection) As ActionResult |
有進到 HttpPost 代表有Submit,我們只需一一為相關Action設定好EmployeeLog及說明,然後測試一下相關動作,再到資料庫或另寫一頁顯示Log記錄的頁面查詢,應該就能看到如下Log記錄:
EmployeeLogID EmployeeId ActionName Description ClientIP CreateTime
1 1 Account/LogOff 登出系統 ::1 2011-06-30 11:22:49.0000000
2 1 Account/Index 查看員工資料 ::1 2011-06-30 11:23:56.0000000
3 1 Account/Edit 修改人員資料 ::1 2011-06-30 11:24:16.0000000
4 1 Account/Index 查看員工資料 ::1 2011-06-30 11:24:16.0000000
5 1 Account/Edit 修改人員資料 ::1 2011-06-30 11:24:28.0000000
檔案下載的LOG ACTIONFILTER
一般檔案下載是匿名的,當我們把 EmployeeLogAttribute.vb 裡取得會員資料相關程式碼註解後,就差不多是檔案下載的 Log ActionFilter,把「設定Log相關資訊」及Entity Framework對應的「資料表名稱」改一改即可。然後,設定到檔案下載相關 Controller/Action 去,即可。
就算是採會員制,上面那個Log ActionFilter一樣寫好了,就拿去用吧!
一樣的東西,留給你去做。^_^
LOG記錄結論
System Log或IIS Log說真的,要看也沒幾個人看得懂,就算看得懂,要從數萬、數十萬、數百萬行裡找出問題點,那本身就是一件高難度任務。透過ASP.NET MVC裡的ActionFilter幫忙,讓我們很簡單且快速就完成有效的Log記錄,不論是稽核、分析、統計、舉證…都更有力,且存放於Database,不論是透過 SSMS 或網頁,我們都能快速的查詢我們所需的資訊。
http://www.dotblogs.com.tw/shinyo.her/archive/2012/02/14/69206.aspx
使用Asp.Net MVC打造Web Api (17) - 使用Nlog記錄系統訊息
http://ithelp.ithome.com.tw/question/10138479
沒有留言:
張貼留言