异常日志—— ESFramework 4.0 快速上手(03)

   ESFramework框架(包括ESPlus、ESPlatform)实现时就内置了相对完整的日志功能,几乎所有的异常(Exception)和错误信息都会被记录到日志。通过查看日志记录,我们可以了解到程序在运行的过程中出现了哪些非正常的状况,并且,详细的日志记录可以帮我们迅速定位问题,并解决问题。(关于我对日志记录的更多认识,可以参看我的博文我的架构经验小结(五)-- 日志记录

一.IAgileLogger接口

    首先,ESFramework框架使用ESBasic.Loggers.IAgileLogger接口来记录日志:

    public interface IAgileLogger
    {
       
 void Log(Exception ee, string location, ErrorLevel level);
        
void Log(string errorType, string msg, string location, ErrorLevel level);            
    }

    注意,我们规定实现IAgileLogger接口的类不允许再抛出异常,也就是说ESFramework框架在调用IAgileLogger接口的Log方法时,是安全的,是不需要再try...Catch的。

二.EsfLogger属性

    ESFramework框架内部有条隐藏的规则,即,所有需要用到日志记录的组件或类,必须暴露类型为IAgileLogger且名为"EsfLogger"的可写属性(setter),以表示该组件/类需要日志记录的支持。如:

        #region EsfLogger
        
private IAgileLogger esfLogger = new EmptyAgileLogger();
        
public IAgileLogger EsfLogger
        {
            
set
            {
                
if (value != null)
                {
                    
this.esfLogger = value ?? new EmptyAgileLogger();
                }
            }
        }
        
#endregion

    EmptyAgileLogger是采用nullobject模式的IAgileLogger接口实现,使用它,即表示不需要记录日志。

    如果我们使用类似Spring这样的IOC容器来装配ESFramework的组件,那么就可以利用ESFramework框架的这条规则来快速的一次性为所有组件的EsfLogger属性赋值,而不是手动地去一个组件一个组件的赋值。像下面这样:

        private static void ConfigEsbLogger()
        {
            
IList<object> objList = new List<object>();
            
string[] names = SpringContext.GetObjectDefinitionNames();
            
foreach (string name in names)
            {
                objList.Add(SpringContext.GetObject(name));
            }

            //从容器中找出用于日志记录的IAgileLogger对象 
            
IAgileLogger logger = (IAgileLogger)SpringContext.GetObject("esfLogger");
            
//遍历集合中的每个组件实例,如果其有EsfLogger属性,则将日志记录对象赋值给它。
            ESBasic.Helpers.ReflectionHelper.SetProperty(objList, "EsfLogger", logger);
        }

三.ESFramework中用到日志记录的重要组件

    ESFramework框架中有很多组件都用到了日志记录器,其中最重要的有如下几个组件:网络引擎组件(包括服务端引擎、客户端引擎、TCP引擎、UDP引擎、二进制引擎、文本引擎)、消息分派器组件、用户管理器组件。我们一一做简单解释。

1、网络引擎组件

    所有的网络引擎都继承自INetEngine接口,而该接口中就定义了"EsfLogger"的可读写属性:

  IAgileLogger EsfLogger { getset; }

   网络引擎主要在什么情况下使用日志记录器了?

(1)当接收到格式不正确的消息时。

      比如,当使用文本协议时,接收到的消息的起始标识符不正确。这种情况下,网络引擎就认为收到了错误或恶意的消息,将记录消息来源IP、消息的内容到日志中。如果是TCP引擎,引擎还会断开对应的TCP连接。

(2)当从网络读数据或往网络写数据发声异常时。通常有两种情况:一是正在读写数据的时候网络断开;二是网络状况不好,写数据超时。

2.消息分派器组件 MessageDispatcher

    当网络引擎接收到正确的消息后,会交给消息分派器去分派消息。

(1)当消息分派器根据消息的类型找不到对应的消息处理器(IMessageProcesser)时,将会记录日志。

      我们可以根据日志发现哪些类型的消息没有被处理。这种情况很少出现,因为通常在消息协议的设计阶段,我们就为每种类型的消息设定了正确的消息处理器。除非,是消息的类型配置出错了。

(2)当消息分派器调用消息处理器处理消息时,消息处理器的方法抛出了异常,这个异常会被消息分派器记录到日志。

      消息处理器是由应用实现的,交由框架回调。消息处理器抛出异常,通常说明我们的业务逻辑处理有bug,这样的日志需要引起我们的高度重视,找到bug并解决bug。

3.用户管理器组件 IUserManager

    用户管理器使用日志记录器记录用户的上下线、超时掉线、被挤掉线等事件。并且其提供了AppLogEnabled属性用于控制是否记录这些日志,对于大型系统来说,这个属性通常是关闭的。

四.快速引擎的日志记录

  如果你使用的是ESFramework 4.0 快速上手一文中介绍的RapidServerEngineRapidPassiveEngine,那么这两个引擎的内部在组装各组件时,已经为重要的组件实例装配了日志记录器(使用ESBasic.Loggers.FileAgileLogger类),这些日志记录器都是将日志内容记录到运行目录下的EsfLog.txt文件。

    IAgileLogger logger = new FileAgileLogger(AppDomain.CurrentDomain.BaseDirectory + "EsfLog.txt");

    你不需要在运行目录下手动创建EsfLog.txt,因为当框架需要记录日志时,是会自动创建这个文件的。你可以定期检查EsfLog.txt文件的内容,以了解程序现在的运行状态,以便及时发现异常情况。

ESFramework 4.0 概述 (文末包含最新版本的ESFramework4.0以及相关demo、帮助文档下载)

《ESFramework 4.0 快速上手》系列所有文章

《ESFramework 4.0 高级进阶》系列所有文章

原文地址:https://www.cnblogs.com/zhuweisky/p/1968048.html