2011年10月17日 星期一

使用NLog - Advanced .NET Logging (3)


解決NLog 2.0使用Layout ${aspnet-request}所出現的錯誤

在NLog中可以透過${aspnet-request}的layout來取得用戶端所送出的資料,包含有:

cookie, serverVariable, queryString, item, form

參考連結:NLog Documentation - Aspnet-request layout renderer

而其中最常用到的是serverVariable,這是用來取得Web伺服器的環境變數,而伺服器環境變數有相當多,

如以下所示:

ALL_HTTP:傳送到客戶端的所有HTTP header資料
 
ALL_RAW:傳送到客戶端的所有資料(以raw的資料格式)
 
APPL_MD_PATH:傳回伺服端的metabase路徑
 
APPL_PHYSICAL_PATH:將APPL_MD_PATH轉換成為實際的路徑傳回
 
AUTH_PASSWORD:傳回客戶端使用者在確認對話框中所輸入的密碼
 
AUTH_TYPE:傳回客戶端認證的方法
 
AUTH_USER:傳回客戶端確認在確認對話框中所輸入的使用者名稱
 
CONTENT_LENGTH:傳回content的資料長度
 
CONTENT_TYPE:傳回客戶端文件傳送的型態,如GET或POST等...
 
GATEWAY_INTERFACE:傳回伺服端的CGI版本
 
HTTP_:傳回使用者自建的HTTP Header資料
 
LOCAL_ADDR:傳回伺服端電腦的IP位址
 
LOGON_USER:傳回登錄Windows NT的使用者資訊
 
PATH_INFO:取得目前網頁的虛擬路徑
 
PATH_TRANSLATED: 目前執行的ASP程式,位於伺服端的真實路徑
 
QUERY_STRING:傳回在HTTP://後以?所傳遞的參數資料
 
REMOTE_ADDR:遠端主機的IP位址
 
REMOTE_HOST:遠端主機的名稱
 
REMOTE_USER:遠端的使用者名稱
 
REQUEST_METHOD:傳回HTTP的請求方式,如GET或POST等...
 
SCRIPT_NAME:被執行的ASP檔案完整的虛擬路徑
 
SERVER_NAME:傳回網頁伺服端的電腦名稱,DNS或IP位址
 
SERVER_PORT:伺服端HTTP的埠(Port)
 
SERVER_PORT_SECURE:傳回客戶端是否指定安全的埠,是則為1,否為0
 
SERVER_PROTOCOL:取得HTTP的版本
 
SERVER_SOFTWARE:取得網頁伺服器的名稱與版本
 
URL:取得目前網頁虛擬路徑的儲存位址

參考連結:MSDN - IIS Server Variables

然而我在NLog.Config中去指定取得一個serverVariable,指定取得目前網頁的網址:

<parameter name="@url" layout="${aspnet-request:serverVariable=url}" />

所出現的錯誤:

嘗試建立型別 'Test.Web.Controllers.HomeController' 的控制器時發生錯誤。請確認此控制器是否有無參數公用建構函式。

再來看看ELMAH所記錄到的詳細錯誤資訊:

type="System.ArgumentException" 
message="LayoutRenderer cannot be found: 'aspnet-request'" 
source="NLog" 
detail="System.InvalidOperationException: 嘗試建立型別 'Test.Web.Controllers.HomeController' 的控制器時發生錯誤。請確認此控制器是否有無參數公用建構函式。

看來這是NLog設定發生問題而出現的錯誤…


加入參考

其實會發生這樣的錯誤是因為NLog 2.0有把幾種的layout renderers給移到 NLog.Extended.dll

從NeGet安裝NLog後並不會將NLog.Extended.dll給加入參考到專案中,此時我們必須先手動去加入參考,

image

image

 

修改NLog.Config

基本上加入的 NLog.Entended.dll 的參考後就可以正確記錄到 Request.ServerVariable的資訊,以下步驟為多加一份保險。

加入參考只是第一步,接下來還必須要在NLog.Config去加入extensions的區段,如下:

<nlog>
  <extensions>
    <add assembly="NLog.Extended" />
  </extensions>
  ...
</nlog>

執行過上面兩個動作之後重新執行網站,就不會出現錯誤並且可以正確記錄到 ${aspnet-request:serverVariable=url} 的資訊,

image

 

注意,還有其他的Layout Renderers也一樣

我們使用物件瀏覽器來看看 NLog.Extended.dll

image

可以發現到,除了 ${aspnet-request} 外還有以下幾種layout renderers的使用是必須加入 NLog.Extended.dll 參考:

 

參考連結:

NLog Documentation - Layout renderers

NLog Documentation – Simplifying NLog.Extended.dll usage

NLog Fourm -  LayoutRenderer cannot be found: 'aspnet-request' (NLog 2.0 beta 1)

NLog Fourm - Problem with NLOG and ASP.NET

Andy Gibson - LayoutRenderer cannot be found: ‘aspnet-request’ (NLog 2.0 beta 1) – Fixed!

StackOverflow - Log current page url with NLog

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。