同事報案,用Visual Studio跑自動測試發現NLog沒作用。
前陣子整理過NLog問題偵錯技巧,熟門熟路啟動SOP:
- 先在NLog.config加入<nlog throwExceptions="true>,未發現執行錯誤
- 使用NLog.LogManager.Configuration.FindTargetByName("f")測試得到null,比對其他可正常運作NLog.config,確認<target xsi:type="File" name="f" …>寫法無誤
詢問案發經過,得知問題NLog.config今天才被手動加入專案。靈機一動,檢查NLog.config的項目屬性,犯人現形:
「Copy to Output Directory」(複製到輸出目錄)被設定成Do not copy,編譯時不會複製到bin目錄,故測試程式一直處於沒有NLog.config的狀態,就能合理解釋FindTargetByName("f")為何傳回null。
經過實驗,透過Add /New Item或Existing Item新増.config檔,Copy to Output Directory屬性預設值都是Do not copy。此一行為不致影響Web專案測試,但一遇上Console、Windows Form或測試專案,.config沒有複製到exe或dll目錄,設定無效。
將Do not copy改為Copy if newer重跑測試,NLog運作即告正常。
不過留下一個疑問,為什麼透過NuGet安裝的NLog.config就沒這問題?答案在 \packages\NLog.Config.4.3.3\tools\Install.ps1 裡:
param($installPath, $toolsPath, $package, $project)
$configItem = $project.ProjectItems.Item("NLog.config")
# set 'Copy To Output Directory' to 'Copy if newer'
$copyToOutput = $configItem.Properties.Item("CopyToOutputDirectory")
$copyToOutput.Value = 1
# set 'Build Action' to 'Content'
$buildAction = $configItem.Properties.Item("BuildAction")
$buildAction.Value = 2
全案宣告偵破,收隊!