客户端

客户端的作用就是捕获未处理异常, 发送异常到服务端。 关于捕获未处理异常的方法参考 http://www.cnblogs.com/youring2/archive/2012/04/25/2469974.html  http://www.cnblogs.com/eaglet/archive/2009/02/17/1392191.html 这两篇博客。
总结下来对于web程序来说, 捕获未处理异常有两种方式:
1. 定义一个HttpModule, 在这个module的context_Error方法中来捕获未处理的异常。 
2. 在Global.asax中有一个Application_Error的方法, 当程序发生未处理异常的时候, 会调用这个方法。 
对于以上两种方式, 以上两篇博客也做了对比, 对异常的捕获, HttpModule会优于Global,同时从编程的角度来说, 如果使用Global, 那就意味着代码侵入。 所以最后决定采用了HttpModule的方式。
public class ErrorLogModule : IHttpModule
{ #region IHttpModule Members public void Dispose()
{
} public void Init(HttpApplication context)
{
context.Error += context_Error;
} #endregion private void context_Error(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication) sender;
ClientErrorEntity errorMessage = new ClientErrorEntity(application.Server.GetLastError().GetBaseException(),
application.Context);
SendErrorEntity.SendError(errorMessage);
}
}
异常信息组装。 
 public ClientErrorEntity(Exception exception, HttpContext httpContext)
{
Id = Guid.NewGuid().ToString("N"); MachineName = Environment.MachineName;
Ip = Common.GetLocalIp();
ExceptionType = exception.GetType().FullName;
ExceptionMessage = exception.Message;
ExceptionSource = exception.Source;
ExceptionDetail = exception.ToString();
DateTime = DateTime.Now;
HttpException httpException = exception as HttpException;
if (httpException != null)
{
HttpStatusCode = httpException.GetHttpCode();
} if (httpContext != null)
{
HttpRequest request = httpContext.Request;
RequestUrl = request.Url.AbsoluteUri;
ServerVariables = Common.ConvertCollectionToDictionary(request.ServerVariables);
QueryString = Common.ConvertCollectionToDictionary(request.QueryString);
Form = Common.ConvertCollectionToDictionary(request.Form);
Cookies = Common.ConvertCollectionToDictionary(request.Cookies);
}
Type = ;
}
这里实现了异常信息的发送,为了避免影响主逻辑, 采用了异步的方式。 注意一个问题, 对于API的地址, 我们采用的硬编码的方式, 当然正式环境为了避免单点, 应该采用域名的方式, 然后通过负载均衡在在多台服务器中选择。 如果仅仅有一台服务器, 那我们要将这个地址放在配置文件中, 一旦地址发生了变化,可以方便我们更改。  
  public static void SendError(ClientErrorEntity errorMessage)
{
try
{
string jsonstr = JsonConvert.SerializeObject(errorMessage);
//异步, 确保不会影响主逻辑
sendPostdelegate.BeginInvoke("http://192.168.16.39:90/api/Error", jsonstr, ContentType.Json, ,
Encoding.UTF8,
Encoding.UTF8, Response, sendPostdelegate); //这里请求地址 建议改为域名的方式, 如果没有域名,建议请求地址和webtoken类似为可配置
}
catch (Exception exception)
{
Common.Log("错误信息上传失败:" + exception.Message);
}
}
为了标示异常是从哪个网站发出的, 我们会对每个网站分配一个token,token会随异常信息一起发送到服务端。 
 <configSections>
<section name="WebWarningSetting" type="System.Configuration.SingleTagSectionHandler"/>
</configSections>
<WebWarningSetting WebToken="1E8C46FC74DC41569EFF63C92A7A4087"/>

服务端API

服务端API主要功能是接收异常信息,考虑到性能问题, 并没有将异常信息直接入库,而是将异常信息放入到Redis的List中,  因为提供的驱动中Redis的List的Value并不支持对象, 所以这里采用分开存放的方法, 将ErrorEntity.Id放入到队列中, ErrorEntity则以普通的方式set到Redis中, 在获取数据的时候,从队列中获取到ErrorEntity.Id , 这样取出来的Id确保顺序不会变, 再根据这个Id, 通过get取出实体。这种方法其实还有待考虑, 虽然List不支持复杂Value, 但是通过json序列化,我们还是可以直接将ErrorEntity放入到List中。
  public HttpResponseMessage Post([FromBody]ErrorEntityDto errorEntity)
{
if (errorEntity != null && !string.IsNullOrWhiteSpace(errorEntity.Id))
{
if (RedisHelper.EnqueueItemOnList("ErrorEntityQueue", errorEntity.Id)) //先将ErrorEntity.Id放入到队列中,确保顺序不会变
{
if (RedisHelper.Set(errorEntity.Id, errorEntity)) //将实体添加到Redis中
{
return ReturnPlainText("ok");
}
return ReturnPlainText("set error");
}
return ReturnPlainText("add item to list error");
}
return ReturnPlainText("modle error");
}

.Net分布式异常报警系统-客户端及服务端API的更多相关文章

  1. WCF客户端获取服务端异常[自定义异常]

    引言 经过不断的摸索,询问/调试,终于学会了关于WCF客户端与服务端之间异常的处理机制,在此来记录自己的成果,用于记录与分享给需要的伙伴们. 首先感谢[.NET技术群]里群主[轩]的大力帮助,如有需要 ...

  2. .Net分布式异常报警系统-简介

    系统简介 分布式异常报警系统就是收集系统运行过程中产生的未处理异常,检查系统运行的状态,并将异常信息统一发送到服务端,由服务端将信息通知到相关的责任人.  问题 我们在项目开发中可能遇到以下几个问题: ...

  3. 客户端与服务端的事件watcher源码阅读

    watcher存在的必要性 举个特容易懂的例子: 假如我的项目是基于dubbo+zookeeper搭建的分布式项目, 我有三个功能相同的服务提供者,用zookeeper当成注册中心,我的三个项目得注册 ...

  4. C# TCP实现多个客户端与服务端 数据 与 文件的传输

    C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜--- 下面是我用C#写的 一个简单的TCP通信,主要的功能有: (1) 多个客户端与服务器间的数据交流 (2)可以实现群发的功能 (3)客户端 ...

  5. Android客户端与服务端交互之登陆示例

    Android客户端与服务端交互之登陆示例 今天了解了一下android客户端与服务端是怎样交互的,发现其实跟web有点类似吧,然后网上找了大神的登陆示例,是基于IntentService的 1.后台 ...

  6. java客户端与服务端交互通用处理 框架解析

    一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...

  7. Oracle Tuxedo工作站客户端与服务端的样例程序

    服务端代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <cty ...

  8. Socket通信客户端和服务端代码

    这两天研究了下Socket通信,简单实现的客户端和服务端代码 先上winfrom图片,客户端和服务端一样 服务端代码: using System; using System.Collections.G ...

  9. java在线聊天项目1.1版 ——开启多个客户端,分别实现注册和登录功能,使用客户端与服务端信息request机制,重构线程,将单独的登录和注册线程合并

    实现效果图: eclipse项目中初步整合之前的各个客户端和服务端的窗口与工具类,效果如下图: 已将注册服务器线程RegServer功能放到LoginServer中,使用客户端与服务端的request ...

随机推荐

  1. 按要求编写Java应用程序。 (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。

    package zuoye; public class Cat { String name="妮妮"; String color="灰色"; int age=1 ...

  2. 表单和iframe的使用

    图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果.示例: 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容.示例: 网页的拼接: 在一个网络页面 ...

  3. .NET领域驱动设计—实践(穿过迷雾走向光明)

    阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...

  4. DateTime , DateTime2 ,DateTimeOffset 之间的小区别

    闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭   DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...

  5. SQL Server锁定【2015.12.17】

    锁定的体系分类   1.表级锁 保证数据在逻辑上的一致性. 包含:行级锁.分页锁.表.数据分页.LOB分页以及索引叶子级锁. 2.闩 保证数据在物理上的一致性,系统采用,比锁少耗资源,对用户不可见. ...

  6. 知方可补不足~sqlserver中对xml类型字段的操作

    回到目录 在sqlserver中有很多种数据类型,而XML数据类型是比较新奇怪的一种格式,我们平常接触的可能比较少,用的也少,而在某些场合,使用XML类型可能会使我们的开发变简单,下面就是一种情况: ...

  7. 微信公众平台开发(三) 订阅事件(subscribe)处理

    一.简介 新用户关注微信公众平台,将产生一个订阅事件,即subscribe事件,默认代码中没有对这一事件进行相应回复处理. 在新用户关注公众平台后,可能想知道该平台提供了哪些功能,以及怎样使用该平台, ...

  8. 烂泥:通过binlog恢复mysql数据库

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在上一篇文章,我们讲解了有关mysql的binlog日志的基础知识.这篇文章,我们来讲解如何通过mysql的binlog日志来恢复数据库. 在使用bin ...

  9. 关于/etc/hosts文件

    1,/etc/hosts,主机名何ip配置文件.hosts---The static table lookup for host name(主机名查询静态表) linux 的/etc/hosts是配置 ...

  10. MyEclipse 启动 tomcate 失败 解决方法

    MyEclipse中启动tomcate失败 十月 20, 2015 9:53:04 下午 org.apache.catalina.startup.VersionLoggerListener log信息 ...