在ap.net Web项目中一直使用Elmah进行日志记录,

但一直有一个问题困扰我很久,那就是我如何自己生成一个错误并记录到Elmah里去。

你知道有时你需要在项目中生成一个错误用于一些特殊的需求

最开始之前我是这样处理的。

使用Sql语句自定义错误信息添加到Elmah的Sqlite数据库中,但这样做有一个问题,

如果Elmah更改存储方式非Sqlite(如Xml,txt,Mysql等)那么下面的方式就无效啦(错误信息无法在Elmah中显示)

public class CustomErrorSqlite{
static string UrlDecodeUtf( string _val)
{
return HttpUtility .UrlDecode(_val, System.Text. Encoding .UTF8);
}
static string StrDecode(string str)
{
return UrlDecodeUtf(str).Replace("&", "&").Replace("<br />", " ").Replace("<br>", " ").Replace("<", "<").Replace(">", ">").Replace("\"", """).Replace("\'", "'").Replace(")", ")").Replace("(", "(").Replace("{", "{").Replace("}", "}").Replace("/", "/");
}
static string GetServerVariables
{
get
{
StringBuilder sb = new StringBuilder("<serverVariables>");
foreach (string str in HttpContext.Current.Request.ServerVariables)
{
sb.Append(string.Format("<item name='{0}'><value string='{1}'/></item>", str, StrDecode(HttpContext.Current.Request.ServerVariables[str])));
}
sb.Append("</serverVariables>");
return sb.ToString();
}
}
/// <summary>
/// 错误信息,错误地址,错误详细信息
/// AllXml列需要将@#等特殊字符进行处理,否则在查看Elmah详情时会出现
/// </summary>
/// <param name="message">错误信息</param>
/// <param name="source">错误来源</param>
/// <param name="detailmessage">详细的错误信息</param>
public static void AddLog(string message, string source, string detailmessage)
{
detailmessage = StrDecode(UrlDecodeUtf(detailmessage));
message = StrDecode(UrlDecodeUtf(message));
source = StrDecode(UrlDecodeUtf(source)); //使用Elmah的Sqlite数据库
//如果在配置文件中更改sqlite数据库位置或更改为其他存储方式
//下面的处理方式无效(数据无法在Elmah中显示和查看)
string ConnectionString = string.Empty;
foreach (ConnectionStringSettings str in ConfigurationManager.ConnectionStrings)
{
if (!str.Name.Contains("Elmah_SQLiteErrorLog"))
continue;
ConnectionString = str.ConnectionString;
break;
}
using (SQLiteConnection sQLiteConnection = new SQLiteConnection(ConnectionString))
{
using (SQLiteCommand sQLiteCommand = new SQLiteCommand("INSERT INTO Error (Application, Host, Type, Source, Message, User, StatusCode, TimeUtc, AllXml)VALUES (@Application, @Host, @Type, @Source, @Message, @User, @StatusCode, @TimeUtc, @AllXml);SELECT last_insert_rowid();", sQLiteConnection))
{
SQLiteParameterCollection parameters = sQLiteCommand.Parameters;
parameters.Add("@Application", DbType.String, ).Value = "/";
parameters.Add("@Host", DbType.String, ).Value = Environment.UserName;
parameters.Add("@Type", DbType.String, ).Value = "UserType";
parameters.Add("@Source", DbType.String, ).Value = "UserType";
parameters.Add("@Message", DbType.String, ).Value = message;
parameters.Add("@User", DbType.String, ).Value = Environment.UserName;
parameters.Add("@StatusCode", DbType.Int64).Value = ;
parameters.Add("@TimeUtc", DbType.DateTime).Value = DateTime.Now;
parameters.Add("@AllXml", DbType.String).Value = string.Format("<error type=\"UserType\" message=\"{0}\" source=\"{1}\" detail=\"\r\n{2}\r\nSource:{3} \">{4}</error>", message, source, detailmessage + "\r\ndatetime:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ms"), source, GetServerVariables); try
{
sQLiteConnection.Open();
sQLiteCommand.ExecuteScalar();
}
catch (Exception)
{ }
finally
{
sQLiteCommand.Clone();
}
}
}
}
}

  

经过搜索 发现一个更好的解决方案使用Elmah内部对象来添加错误信息,但可能性能上会有损耗,每次都会创建Error或Exception对象

 
using System;
using System.Web;
using Elmah;
namespace CustomErrorElmah
{
public partial class Default : System.Web.UI.Page
{ protected void Page_Load(object sender, EventArgs e)
{ string querystr = "\r\n";
if (!string.IsNullOrEmpty(Request.QueryString.ToString()))
querystr += Request.QueryString; //自定义错误
CustomErrorSqlite.AddLog("THIS IS TEST ,自定义Sql添加到Elmah的Sqlit数据库中", "Page_Load()", "自定义错误 自定义Sql添加到Elmah的Sqlit数据库中" + querystr); #region
//创建一个Elmah的Error对象并写错误日志 Error error = new Error();
error.Message = "THIS IS TEST 使用Elmah的Error对象";
error.HostName = Request.Url.Host;
error.StatusCode = ;
error.Time = DateTime.Now;
error.User = Environment.UserName;
error.Type = "Elmah 自定义类型";
error.Detail = "THIS IS TEST ,创建一个Elmah的Error对象并写错误日志 但没有Server Variables,cookie等信息" + querystr;
error.Source = "Page_Load"; Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(error);
#endregion //创建一个异常并写入错误日志,无法自定义错误的类型
Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("创建一个异常并写入错误日志" + querystr));
}
}
}

Web.config配置Elmah 

<?xml version="1.0" encoding="utf-8"?>

<configuration>
<configSections>
<!--监控应用程序-->
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah"/>
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
</sectionGroup>
</configSections> <!--Elmah连接数据库-->
<elmah>
<security allowRemoteAccess="yes"/>
<errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="Elmah_SQLiteErrorLog"/> </elmah>
<connectionStrings>
<!--监控应用程序 数据存储位置-->
<add name="Elmah_SQLiteErrorLog" connectionString="Data Source=|DataDirectory|Error.db3"/>
</connectionStrings>
<system.web> <!--出现错误时的处理模块-->
<httpHandlers>
<add verb="POST,GET,HEAD" path="Elmah/Error.aspx" type="Elmah.ErrorLogPageFactory, Elmah"/>
</httpHandlers>
<httpModules>
<!--出错时的处理模块-->
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
<!--发送Email-->
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/>
</httpModules>
<customErrors defaultRedirect="/404.html" mode="Off"/>
</system.web>
</configuration>

有图有真相:

1.

2.

.

3.

之前一直想解决完全自定义错误信息的问题,但上面三个方法总不能让我完全满意(我需要Request的完整信息)

但第二个最接近我想要的效果,只是生成的错误信息没有Request信息见图2

在Bing.com和stackoverflow.com上搜索了半天也没有解决,无奈只好下载源码自己来处理

通过源码发现实现方法完全可以实现我要的效果(自动添加Request信息)

只需要将当前的HttpContext指向“Error ”对象既可

  //创建一个Elmah的Error对象并写错误日志
//没有Request信息
Error error = new Elmah. Error ( );
//当前的HttpContext指向“Error ”,在生成的错误信息时会自动添加Request信息
Error error = new Elmah. Error ( new Exception (), HttpContext .Current);
error.Message = "THIS IS TEST 使用Elmah的Error对象" ;
error.HostName = Request.Url.Host;
error.StatusCode = ;
error.Time = DateTime.Now;
error.User = Environment.UserName;
error.Type = "Elmah 自定义类型" ;
error.Detail = "THIS IS TEST ,创建一个Elmah的Error对象并写错误日志 但没有Server Variables,cookie等信息" + querystr;
error.Source = "Page_Load" ;

Elmah:http://code.google.com/p/elmah/

http://asp.net.bigresource.com/Logging-username-with-Elmah-for-WCF-Webservices--Wp1ghgwYB.html#TwdsRSkL9

http://stackoverflow.com/questions/2108404/elmah-exceptions-without-httpcontext

http://stackoverflow.com/questions/3812538/elmah-add-message-to-error-logged-through-call-to-raisee

http://stackoverflow.com/questions/7441062/how-to-use-elmah-to-manually-log-errors

自定义错误信息并写入到Elmah的更多相关文章

  1. SpringBoot自定义错误信息,SpringBoot适配Ajax请求

    SpringBoot自定义错误信息,SpringBoot自定义异常处理类, SpringBoot异常结果处理适配页面及Ajax请求, SpringBoot适配Ajax请求 ============== ...

  2. 自定义 ocelot 中间件输出自定义错误信息

    自定义 ocelot 中间件输出自定义错误信息 Intro ocelot 中默认的 Response 中间件在出错的时候只会设置 StatusCode 没有具体的信息,想要展示自己定义的错误信息的时候 ...

  3. jquery.validate使用 - 自定义错误信息

    自定义错误消息的显示方式 默认情况下,验证提示信息用label元素来显示, 并且会添加css class, 通过css可以很方便设置出错控件以及错误信息的显示方式. /* 输入控件验证出错*/form ...

  4. Java异常封装(自定义错误信息和描述)

    一.checked异常和unchecked异常 checked异常: unchecked异常: 二.异常封装示例 2.1.添加一个枚举LuoErrorCode.java如下: 2.2.创建一个异常类B ...

  5. jQuery.validate.js 自定义错误信息

    var validate = $("form").validate({....})validate.showError({"username":"us ...

  6. jQuery Validate自定义错误信息,自定义方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. asp.net mvc3 数据验证(二)——错误信息的自定义及其本地化

    原文:asp.net mvc3 数据验证(二)--错误信息的自定义及其本地化 一.自定义错误信息         在上一篇文章中所做的验证,在界面上提示的信息都是系统自带的,有些读起来比较生硬.比如: ...

  8. strut2 自定义文件上传错误信息

    在文件上传过程中我们可以指定拦截器对文件类型.后缀名.大小进行设定,action中的配置: <interceptor-ref name="fileUpload"> &l ...

  9. MVC验证06-自定义错误信息

    原文:MVC验证06-自定义错误信息 本文体验自定义错误信息.   系统默认的错误信息 在"MVC验证02-自定义验证规则.邮件验证"中,我们自定义了一个验证Email的类.如果输 ...

随机推荐

  1. shell kill session

    ps -ef | grep java kill -9 pid

  2. openstack多region配置

    实验 A机器 10.64.8.171     RegionOne B机器 10.64.8.142     RegionTwo         Keytson(这个组件随便放在哪台都可以) openst ...

  3. BeautifulSoup解析库

    解析库 解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(html, 'html.parser') 速度适中,容错能力强 老版本python容错能力差 lxml HTML解 ...

  4. luogu P1011 车站

    题目描述 火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上.下车,但上.下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人.从第3站起( ...

  5. 「SCOI2016」美味

    「SCOI2016」美味 题目描述 一家餐厅有 \(n\) 道菜,编号 \(1 \ldots n\) ,大家对第 \(i\) 道菜的评价值为 \(a_i \:( 1 \leq i \leq n )\) ...

  6. luoguP3830 [SHOI2012]随机树 期望概率 + 动态规划 + 结论

    题意非常的复杂,考虑转化一下: 每次选择一个叶节点,删除本叶节点(深度为$dep$)的同时,加入两个深度为$dep + 1$的叶节点,重复$n$轮 首先考虑第$1$问,(你看我这种人相信数据绝对是最大 ...

  7. [BZOJ4627][BeiJing2016]回转寿司(线段树)

    从左到右处理,设到当前数R的前缀和为cnt[i],则以i为右端点的合法的区间左端点j必然是L<=cnt[i]-cnt[j-1]<=R,即cnt[i]-R<=cnt[j-1]<= ...

  8. 【推导】【线段树】hdu5929 Basic Data Structure

    题意: 维护一个栈,支持以下操作: 从当前栈顶加入一个0或者1: 从当前栈顶弹掉一个数: 将栈顶指针和栈底指针交换: 询问a[top] nand a[top-1] nand ... nand a[bo ...

  9. JavaScript学习笔记 isPrototypeOf和hasOwnProperty使用区别

    1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false. 格式如下: object ...

  10. redis实现简单延时队列(转)

    继之前用rabbitMQ实现延时队列,Redis由于其自身的Zset数据结构,也同样可以实现延时的操作 Zset本质就是Set结构上加了个排序的功能,除了添加数据value之外,还提供另一属性scor ...