记处理线上记录垃圾日志 The view 'Error' or its master was not found

最近监控线上日志,网站是ASP.NET MVC 开发的,发现不少错误日志都记录同样的内容:

The view ‘Error‘ or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Search/Error.aspx
~/Views/Search/Error.ascx
~/Views/Shared/Error.aspx
~/Views/Shared/Error.ascx
~/Views/Search/Error.cshtml
~/Views/Search/Error.vbhtml
~/Views/Shared/Error.cshtml
~/Views/Shared/Error.vbhtml
System.Web.Mvc
   at System.Web.Mvc.ViewResult.FindView(ControllerContext context)

本地调试下不会发现,通过排查发现本地和线上配置的差异在于 customErrors mode="On",将本地改后单点调试发现确实是将这样的错误记录,而本身我在action里面 throw 出来的异常已经抓取不到了。也就是说真的异常并未抓取到,而记录的是一个无关紧要莫名其妙的日志,因为我并没有任何代码去返回”Error“这个view。

先说下目前我抓取异常的方式:在Global.asax文件中增加

        protected void Application_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();
            //Write Log
        }

假如在Controller里面去override OnException方法进行写日志则不会出现这样的问题,但是在Controller里记日志可能会使在View里面出错的日志记录不到。

烦了很久,最后不经意发现MVC里面会默认注册一个Filter,代码如下

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

注册掉可以解决上述问题,但是我不太服气,于是在codeplex翻了mvc的源代码,HandleErrorAttribute的代码如下:

using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web.Mvc.Properties;

namespace System.Web.Mvc
{
    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        private const string DefaultView = "Error";

        private readonly object _typeId = new object();

        private Type _exceptionType = typeof(Exception);
        private string _master;
        private string _view;

        public Type ExceptionType
        {
            get { return _exceptionType; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }
                if (!typeof(Exception).IsAssignableFrom(value))
                {
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                                                              MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName));
                }

                _exceptionType = value;
            }
        }

        public string Master
        {
            get { return _master ?? String.Empty; }
            set { _master = value; }
        }

        public override object TypeId
        {
            get { return _typeId; }
        }

        public string View
        {
            get { return (!String.IsNullOrEmpty(_view)) ? _view : DefaultView; }
            set { _view = value; }
        }

        public virtual void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            if (filterContext.IsChildAction)
            {
                return;
            }

            // If custom errors are disabled, we need to let the normal ASP.NET exception handler
            // execute so that the user can see useful debugging information.
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }

            Exception exception = filterContext.Exception;

            // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
            // ignore it.
            if (new HttpException(null, exception).GetHttpCode() != 500)
            {
                return;
            }

            if (!ExceptionType.IsInstanceOfType(exception))
            {
                return;
            }

            string controllerName = (string)filterContext.RouteData.Values["controller"];
            string actionName = (string)filterContext.RouteData.Values["action"];
            HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
            filterContext.Result = new ViewResult
            {
                ViewName = View,
                MasterName = Master,
                ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                TempData = filterContext.Controller.TempData
            };
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;

            // Certain versions of IIS will sometimes use their own error page when
            // they detect a server error. Setting this property indicates that we
            // want it to try to render ASP.NET MVC‘s error page instead.
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

HandleErrorAttribute

坑爹,他mvc里面会默认返回error视图,看来以后新开发时还是创建空项目好了。

至于为啥设置了customErrors mode="On"后才会出现这种垃圾日志,则要归咎于HandleErrorAttribute类的OnException方法里面了

        // If custom errors are disabled, we need to let the normal ASP.NET exception handler
            // execute so that the user can see useful debugging information.
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }

解决方案是删掉默认注册的这个filter或者新增类去override相应的方法。

记处理线上记录垃圾日志 The view 'Error' or its master was not found

时间: 2024-10-14 20:24:46

记处理线上记录垃圾日志 The view 'Error' or its master was not found的相关文章

如何快速处理线上故障

概述 线上故障通常是指大规模的影响线上服务可用性的问题或者事件,通俗点讲就是:掉'坑'里了,这个'坑'就是线上故障!线上故障的处理过程可以形象地表达为:'踩坑'.'跳坑'.'填坑'.'避坑'. 线上故障的处理不仅是一项技术活,更是对技术人员/技术团队反应能力.决策能力.判定能力.组织能力的考验.面对突发的生产故障,需要快速定位问题,找到解决方案,快速实施解决方案并不是一件容易的事情.本文主要包括如下内容:线上故障处理的目标.思路.步骤.基础设施.本文是依据平时经历的生产故障排查和处理,总结一些肤

本地Git仓库和远程仓库的创建和关联及github上传(git push)时出现error: src refspec master does not match any解决办法

github上传项目方法: 在你的电脑上装好git Git Bash Here 本地Git仓库和远程仓库的创建及关联大致流程是: 1.初始化这个本地的文件夹为一个Git可以管理的仓库 git init 注意:Git会自动为我们创建唯一一个master分支我们能够发现在当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了. 2.将本地的仓库和远程的仓库进行关联 git remote add origin [em

记录一次通过反编译处理线上问题

问题: 研发公司单独做了控制关停接口,因为他们域名未备案缘故导致接口无法正常调用,游戏不能正常登陆.但是对方因为合作终止暂时不能积极的处理.只能自己尝试编译处理 解决办法:找对对应的接口文件,尝试重新编译解决 1.一开始不知道游戏里为什么卡在登陆上,尝试抓包看信息手机登陆通过fiddler抓包工具在,可以看到一个登陆链接报错500------->问题引起的原因是用户验证登陆返回500,由于调用SDK不能请求到接口返回,这个SDK被研发那边私自接了控制SDK的代码.http://www.test.

记录异常日志的7条规则

最近一直在帮忙调试一些让人头大的bug问题,这才意识到如何记录异常日志对于简化调试的重要性,我总结了几点记录异常日志的最佳实践发表在此. 1.记录技术性异常而不是用户异常 用户异常(如:“登录用户名已经存在”)除了显示给用户,要么什么都别管,要么根本就不是异常(“用户尚未认证”).技术性异常(如:“文件存储不够,没法订阅此产品”)才是你需要调试而为此做出反应的,如果你记录所有事情很有可能因日志实体太长而不能真正有意义的反映到你所记录异常日志中.你应该查明日志文件中的每个异常找到其原因(“是bug

Nginx日志过滤 使用ngx_log_if不记录特定日志

ngx_log_if是Nginx的一个第三方模块.它在Github上的描述是这样介绍的:ngx_log_if是一个独立的模块,允许您控制不要写的访问日志,类似于Apache的"CustomLog env = XXX" 第一步: 先到Github下载ngx_log_if地址https://github.com/cfsego/ngx_log_if/ 第二步: 安装第三方模块到Nginx.第三方模块的安装可以参考http://wiki.nginx.org/3rdPartyModules 使用

集合差集 哈希表 比较数据库中的图片和服务器上的图片,将服务器上的垃圾图片删除

SSH 框架下code: public String deleRubbishAd(){ int deleADcount = 0; rubbishADtp = configDao.rubbishADtp(); //数据库中的广告图片集合 Map<Object,Object> shujuku= new HashMap<Object,Object>(); File adfile = new File("C://Program Files//Apache Software Fou

记录php日志

1.记录PHP错误日志 display_errors与log_errors的区别 display_errors 错误回显,一般常用于开发模式,但是很多应用在正式环境中也忘记了关闭此选项.错误回显可以暴露出非常多的敏感信息,为攻击者下一步攻击提供便利.推荐关闭此选项. display_errors = On 开启状态下,若出现错误,则报错,出现错误提示 dispaly_errors = Off 关闭状态下,若出现错误,则提示:服务器错误.但是不会出现错误提示 log_errors 在正式环境下用这

ASP.NET记录错误日志的方式

程序记录错误日志是一种看起来对一般用户没什么作用,但对程序开发者用处很大的东西,它能查出错误或异常的程序马迹.那么,常用的记录错误日志的方式有哪些呢? 大多数情况下使用的是 1.直接记录为txt/xml文件 2.Windows Event Log 其他记录错误日志的方式 1.当前进程的本地队列 没有简单高效的持久化机制实现,单次调用效率会降低 2.MSMQ (1).非进程内消息队列,单次调用速度上,没有进程内部本地队列速度快 (2).内建持久化机制,即便down机,信息也不会丢失 (3).能简单

记录到日志中的异常栈缺失

项目中有这样一个场景: 使用反射处理所有业务调用,在反射调用点使用try-catch集中处理异常,并将异常信息记录到日志.其中日志记录是异步的. 问题: 记录到日志中的异常的StackTrace和有时候和Debug时抛出的异常的StackTrace不一样. 原因: 由于记录日志是异步的,如果记录日志发生在throw之前,记录到日志中的异常的StackTrace就是正确的(异常真正发生点到throw点的所有StackTrace):如果记录日志发生在throw之后,记录到日志中的异常的StackTr