前些日子測試時發現以 debug mode 環境建置後發佈到 dev 環境時,一切都正常無誤,然而要發佈至 prd 環境時,卻發現 log 不會照著 nlog.config 裡的 rules 所設定準則去記 log
當下先檢查了寫入的目錄是不是有權限的問題,然而該設定的權限都有設定了
把 Nlog internalLogLevel 設為 trace, 並把 throwExceptions 設成 true 看看是不是寫入資料有問題,然而也沒看到有什麼問題
於是回頭檢查了一下 Nlog.config 是否有什麼特別的地方,在 rules 中我是以 logger filter 的方式去決定要寫到哪個 target
<targets>
<target name="InOutLog" xsi:type="File"
fileName="${basedir}/InOut/log.txt"
layout="${longdate} | ${level:uppercase=true} | ${logger:shortName=true} | ${message} ${newline}" encoding="utf-8" keepFileOpen="false" />
</targets>
<rules>
<logger name="ApiSite.Handler.*" minlevel="Info" writeTo="InOutLog" />
</rules>
在 prd 環境中把 rules 修改為任何 logger 都要寫入,結果就成功了!?
<rules>
<logger name="*" minlevel="Info" writeTo="InOutLog" />
</rules>
所以很明顯就是 logger filter 的問題了,在 debug 與 release mode 所產生的 logger 可能是不同的?
於是我把 dev 的 rules 改成跟 prd 一樣,結果發現 logger 果然是不一樣的!!!
為了澄清 prd 環境並不影響,所以我把 dev 環境的直接佈到 prd 環境中,果然就正常運作了
所以問題並不在於 prd server 上
仔細檢視了一下 Jenkins 發佈的 profile,dev 是用 debug config 去發佈, prd 是用 release 去發佈
唯一的線索就是 debug mode 跟 release mode 輸出不同!!!
release mode 會做一些優化的編譯,但這也許是導致 Nlog 執行結果不同的原因
於專案按右鍵 => properties => build 中分別檢視 debug/release
果然發現在 Define DEBUG constant 與 optimize code 中有所不同
ApiSite.Handler
public class WebApiMessageLogHandler : DelegatingHandler
namespace ApiSite
{
public class FilterConfig
{
public static void RegisterGlobalFilters(HttpConfiguration config)
{
config.MessageHandlers.Add(new WebApiMessageLogHandler());
}
}
}
在 debug 中記到的是完整的 ApiSite.Handler.WebApiMessageLogHandler
然而在 release 中記到的是上層 caller 的資料 ApiSite.FilterConfig
推論也許跟 optimize code 是有關的
在 VS2019 中 Build => Configuration Manager 新增一組 config 給 prd 使用,並從 debug 複製出來
接著在發佈的部份改為由 prd 的設定檔去發佈,這樣就能解決掉 logger debug/release 不一致的問題了
如果 applicationSetting 或是 connectionString 也有切 config 的話,記得要再重新產生新的 config (右鍵Add config Transforms)
會自動產出 connectionString.prd.config
另一種比較麻煩的解決方案會是根據不同的 debug/release 去設定 nlog.config 的檔案
像是 web.debug.config 與 web.release.config 的方式去決定要寫到哪個
並客製化 nlog.release.config 裡的 target 與 rules 的規則
然而這樣 debug 跟 release mode 的 nlog.config 就會不同,反而導致追查上的困難,一但增加了新的 rules 就得再去同步另一端的 config rules