在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. Java 继承内部类

    大家有没有想过内部类究竟能不能被继承呢? public class Main { public static void main(String[] args){ Outer outer = new O ...

  2. 验证码无法显示:Could not initialize class sun.awt.X11GraphicsEnvironment 解决方案

    一.原因现象:图下图 二.原因导致: 经过Google发现很多人也出现同样的问题.从了解了X11GraphicEnvironment这个类的功能入手,一个Java服务器来处理图片的API基本上是需要运 ...

  3. JS模拟PHP的sleep

    function sleep(n) { var start = new Date().getTime(); while(true) { if(new Date().getTime() - start ...

  4. 【四边形不等式】POJ1160[IOI2000]-Post Office

    [题目大意] v个村庄p个邮局,邮局在村庄里,给出村庄的位置,求每个村庄到最近邮局距离之和的最小值. [思路] 四边形不等式,虽然我并不会证明:( dp[i][j]表示前i个村庄建j个邮局的最小值,w ...

  5. OpenAPI安全防护

    1,开放API可能存在的数据安全问题 (1)数据窃取 通常体现为:钓鱼网站,拦截,伪装,截包 (2)数据篡改 中间被拦截,以代理的方式拦截数据,修改数据 (3)数据泄露 爬虫抓取核心数据 2,解决数据 ...

  6. VK Cup 2016 - Round 1 (Div. 2 Edition) E. Bear and Contribution 单调队列

    E. Bear and Contribution 题目连接: http://www.codeforces.com/contest/658/problem/E Description Codeforce ...

  7. 厄拉多塞筛法和普通方法求素数表(python实现)

    厄拉多赛筛法(sieve of Eratosthenes): 想要得到一个不大于N的数所有素数,可以先找到不超过根号N的所有素数,设2 = p1 < p2 < ......<pk ≤ ...

  8. Qt on android 蓝牙开发(控制小车)

    因为要做一个用蓝牙控制小车的app,就用着QT搞了下,网上关于QT蓝牙开发的资料比较少,我在这里记录下过程希望对看到了人有所帮助 首先在项目文件里添加 QT += bluetooth 这样就可以用QT ...

  9. NHibernate 3 Beginner's Guide

    前言 这一章是一个完整的NHibernate的Simple,原文中用Fluent NHibernate做映射,但我使用NHibernate3.2版本,所以3.2的Conformist代替Fluent ...

  10. 【多线程】java多线程Completablefuture 详解【在spring cloud微服务之间调用,防止接口超时的应用】【未完成】

    参考地址:https://www.jianshu.com/p/6f3ee90ab7d3 示例: public static void main(String[] args) throws Interr ...