##やりたかったこと
Controller以外で発生した例外を
Global.asax.csのApplication_Errorイベントに集約させて
エラー内容(厳密にはServer.GetLastError()のMessage)をNLogでログ出力をしたかった。
##試したこと
ソースファイルのエンコーディングおよびリクエスト、レスポンス、レスポンスヘッダをUTF-8として見なすようWeb.configに次の記述を追加
<configuration>
<system.web>
<globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" responseHeaderEncoding="utf-8" />
</system.web>
・・・
NLogが出力するファイルのエンコーディングもUTF-8にした
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="errorlog"
xsi:type="File"
layout="${longdate} [${threadid:padding=8}] [${uppercase:${level:padding=-5}}] ${callsite}() ${message} ${exception:format=tostring}"
fileName="${basedir}/APP_Data/nlog/ErrorLog.txt"
archiveFileName="${basedir}/App_Data/nlog/ErrorLog.{#####}.txt"
maxArchiveFiles="100"
archiveAboveSize="102400"
archiveNumbering="Sequence"
archiveEvery="Day"
concurrentWrites="true"
keepFileOpen="false"
encoding="UTF-8" />
</targets>
<rules>
<logger name="ExceptionHandler" minlevel="Debug" writeTo="errorlog" />
</rules>
</nlog>
これで行けるかと思いGlobal.asax.csで次のような処理を作りログを吐かせてみた
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using NLog;
namespace Hoge
{
public class MvcApplication : System.Web.HttpApplication
{
private static Logger logger = NLog.LogManager.GetLogger("ExceptionHandler");
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_Error(object sender, EventArgs e)
{
if (Server != null)
{
var ex = Server.GetLastError();
logger.Fatal(ex);
}
}
}
}
###結果
2018-11-20 18:49:37.6676 [ 6] [FATAL] Hoge.MvcApplication.Application_Error() System.Web.HttpException (0x80004005): !baRrz!A public action method 'Fuga' was not found on controller 'Hoge.Controllers.HogeController'. 表©鷗字㌍ 表!
場所 System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
場所 System.Web.Mvc.Controller.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState)
(以下スタックトレース)
うん。エラー内容が化けている!
##これは困った
とりあえず安直に文字化けをコピペしGoogle先生に聞いてみると、
Qiitaで関連した記事が見つかった!
どうやらライブラリの問題っぽい。
##実際に確認してみる
説明が既にバグってやがります。
説明文のバグり具合から、バージョンは3.2.4と3.2.5がNGに見えます。
3.2.6は正常に見える。
Microsoft.AspNet.Mvc.jaを現在の最新安定版(3.2.6)にアップデートしてみたら
Razor.jaとWebpages.jaも勝手にアップデートされた。
###結果
2018-11-20 18:55:40.0646 [ 8] [FATAL] Hoge.MvcApplication.Application_Error() System.Web.HttpException (0x80004005): コントローラー 'Hoge.Controllers.HogeController' にパブリック アクション メソッド 'Fuga' が見つかりませんでした。
場所 System.Web.Mvc.Controller.HandleUnknownAction(String actionName)
場所 System.Web.Mvc.Controller.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState)
これで、文字化けせずにログが出力されたので無事解決。