닷넷관련/ASP.NET MVC 🍕

asp.net mvc 5.0 환경에서 오류를 실시간으로 모니터링

재우니 2020. 10. 27. 02:16

 

asp.net mvc 5.0 환경에서 sentry 를 사용하기 위해서는 nuget 에서 아래 목록 3가지를 다운받습니다.

 

 

 

 

sentry.io/ 사이트를 가입하셔서 key 값을 아래의 SentryDsn 에 할당합니다.

 

 

Application Monitoring and Error Tracking Software

Self-hosted and cloud-based error monitoring that helps software teams discover, triage, and prioritize errors in real-time.

sentry.io

 

<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <!-- Sentry DSN, replace this with your own -->
    <add key="SentryDsn" value="https://f648f0653ad64xxxxxxxxx@o467342.ingest.sentry.io/xxxxxxx" />
  </appSettings>

 

global.asax 에서 sentry 를 사용하기 위해서 SentrySdk.Init() 함수를 Application_Start() 함수에 할당하며, 어플리케이션에서 오류가 발생하면 실행되는 Application_Error() 함수에 SentrySdk.CaptureException(exception); 을 사용하여 Exceiption 을 전송합니다.

 

using System;
using Sentry;

//using Sentry.EntityFramework;
using System.Configuration;
using System.Web.Mvc;
using System.Web.Routing;

namespace AspNetMvc5Ef6
{
    public class MvcApplication : System.Web.HttpApplication
    {
        private IDisposable _sentry;

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            // We add the query logging here so multiple DbContexts in the same project are supported
            //SentryDatabaseLogging.UseBreadcrumbs();

            // Set up the sentry SDK
            _sentry = SentrySdk.Init(o =>
            {
                // We store the DSN inside Web.config; make sure to use your own DSN!
                o.Dsn = new Dsn(ConfigurationManager.AppSettings["SentryDsn"]);

                // Get Entity Framework integration
                //o.AddEntityFramework();
            });
        }

        // Global error catcher
        protected void Application_Error()
        {
            var exception = Server.GetLastError();

            // Capture unhandled exceptions
            SentrySdk.CaptureException(exception);
        }

        protected void Application_End()
        {
            // Close the Sentry SDK (flushes queued events to Sentry)
            _sentry?.Dispose();
        }
    }
}

 

controller 에서 오류가 발생하면 전송하는 방법을 여러가지 제시하는데요. 파라미터가 없어서 오류 발생시키는 ArgumentNullException() 함수 그리고 강제로 오류를 발생시키는 throw new Exception() 함수를 사용하기도 합니다.

 

if (@params == null)
{
	throw new ArgumentNullException(nameof(@params), "Param is null!!!..999");
}

throw new Exception();

 

사용자가 직접 오류를 기재해서 전송하는 방법도 제공하는데요. model 을 만들어서 아래와 같이 사용하기도 합니다.

 

catch (Exception e)
{
    var ioe = new InvalidOperationException("Bad POST! See Inner exception for details...99.", e);

    ioe.Data.Add("inventory",
    // The following object gets serialized:
    new Extra
    {
      SmallPotion = 9,
      BigPotion = 0,
      CheeseWheels = 512
    });

	throw ioe;
}

 

전체코드는 아래와 같습니다.

 

using System;
using System.Web.Mvc;
using AspNetMvc5Ef6.Models;

namespace AspNetMvc5Ef6.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        // Example: An exception that goes unhandled by the app will be captured by Sentry:
        [HttpPost]
        public ActionResult PostIndex(string @params)
        {
            try
            {
                if (@params == null)
                {
                    throw new ArgumentNullException(nameof(@params), "Param is null!!!..999");
                }

                throw new Exception();
            }
            catch (Exception e)
            {
                var ioe = new InvalidOperationException("Bad POST! See Inner exception for details...99.", e);

                ioe.Data.Add("inventory",
                    // The following object gets serialized:
                    new Extra
                    {
                        SmallPotion = 9,
                        BigPotion = 0,
                        CheeseWheels = 512
                    });

                throw ioe;
            }
        }

        // Example: An entity validation exception that goes unhandled by the app will be captured by Sentry:
        [HttpPost]
        public ActionResult ThrowEntityFramework()
        {
            using (var db = new ApplicationDbContext())
            {
                var user = new ApplicationUser();
                db.Users.Add(user);

                // This will throw a DbEntityValidationException
                db.SaveChanges();
            }

            // This never gets called
            return View("Index");
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

        [Serializable]
        public class Extra
        {
            public int SmallPotion { get; set; }
            public int BigPotion { get; set; }
            public int CheeseWheels { get; set; }
        }
    }
}

 

오류 로그는 issues 메뉴에서 확인이 가능하며, 오류를 그룹핑해서 목록을 보여줍니다.

 

 

그룹핑 내부에 오류 이벤트가 9개 발생되어 있는것을 보여주며, 오류 상세 내역을 여기서 볼 수 있습니다. 오류 코드 라인이나 model 로 보낸 데이터 까지 로그내용이 보입니다. 

 

 

 

 

무료 경우는 한달 기준 5천건을 제공하며, 그 이상이 필요하면 유료로 전환하여 사용하셔야 할듯 싶습니다.