zoukankan      html  css  js  c++  java
  • MSN Direct 日志系统浅析

    对一个复杂的需要24小时连续运行的系统来说,日志系统必不可少,它为系统调试、错误定位提供最有力的支持。MSN Direct就是一个这样的系统,不仅24小时连续运行,还会不断地从不同的Web Server获取诸如交通、天气、新闻、股价等信息,并把获得数据进一步处理后,存入到数据库,最后MSN Direct调度程序再根据不同的策略从数据库提取数据,并把它们通过广播转发出去,以上任一个环节出问题,就会导致信息发送失败,而详尽的日志文件便能为此类问题的定位提供第一手信息,其重要性不言而喻。

    MSN Direct输出的信息分为5类:成功(Success)、错误(Error)、警告(Warning)、信息(Info)、调试(Debug);

    相关示例代码如下(相关接口函数我进行了调整和简化,去掉了EventCode参数):

    private void btnTest_Click(object sender, EventArgs e)
    {
        Logger.Success(
    "Success");
        
    try
        {
            
    int a = 10,b=0;
            a 
    /=  b;
        }
        
    catch (Exception ee)
        {
            Logger.Error(ee, 
    "error");
            Logger.Error(ee);
            Logger.Warning(ee, 
    "Warning");
            Logger.Warning(ee);
            Logger.Warning(
    "Warning1");
        }
        Logger.Info(
    "info");
        Logger.Debug(
    "Debug");
    }

     

    其输出方式也有4种之多,这4种方式分别为:

    1VS2005/VS2008 输出对话框。  

    2、控制台信息输出

    3、系统事件输出(可通过事件查看器浏览)

    4log文件输出

    MSN Direct的日志系统,每小时便输出一个文件(因为对MSN Direct系统来说,一小时便能产生近10M数据),并且可设定日志文件保存的天数(默认2天),为了方便查阅我编写了一个日志浏览器(参见上图),不仅可分类查看,还可以进行关键字搜索。

    在开发这个日志浏览器过程中,有一个技术问题困扰了我一段时间。对MSN Direct的日志系统,有两种写日志文件方式,一是文件句柄一直打开(直到一小时结束换另一个日志文件为止),二是输出一条便即时关闭,写下条时再打开。由于MSN Direct日志信息量巨大,所以为了优化性能选择了第一种方式。这就有一个问题,日志浏览器只能打开以前的日志进行浏览,而对当前的日志却无法打开,程序会提示你,该文件已被打开之类云云。你试着用其它文档编辑器去打开,你会发现大多数这类程序都无法打开,目前就我所知,WinHex和记事本程序可以(没有想到记事本程序还有这么强的的一面)。

    从网上搜索“打开已打开文档”(也可以称为文件共享访问,不过有点特殊的是,前提是该文件已被独占打开了),未发现有价值的文章。当然也有釜底抽薪的做法,就是直接读取磁盘,对FAT32的文件系统来说,技术上我还可以实现,但是对NTFS格式的磁盘我就捉襟见肘了。

    本打算深入研究一下记事本到底调用了什么API,后来囿于时间关系,所以采取了曲线救国的方式实现了该功能。

    思路:先用记事本打开,然后从记事本获取信息,最后关闭记事本。不过很不爽的是,采用各种方法记事本的窗体还是无法隐藏(估计是初始打开的文件太大了)。

    相关代码如下:

    #region 用记事本打开已打开的文本文件
        System.Diagnostics.Process Proc;
        
    try
        {
            
    // 启动记事本
            Proc = new System.Diagnostics.Process();                          
            Proc.StartInfo.FileName 
    = "notepad.exe";
            Proc.StartInfo.Arguments 
    = FileName;
            Proc.StartInfo.UseShellExecute 
    = false;                                    
            
    //Proc.StartInfo.RedirectStandardInput = true;
            
    //Proc.StartInfo.RedirectStandardOutput = true;    
            Proc.StartInfo.CreateNoWindow = true;
            Proc.StartInfo.WindowStyle 
    = System.Diagnostics.ProcessWindowStyle.Hidden;
            Proc.Start();      
        }
        
    catch
        {
            Proc 
    = null;
        }
        
    #endregion
        
    #region 从记事本获取数据
        
    if (Proc != null)
        {
            
    // 调用 API, 传递数据
            while (Proc.MainWindowHandle == IntPtr.Zero)
            {
                Proc.Refresh();
            }
            ShowWindow(Proc.MainWindowHandle, 
    0);                        
            IntPtr vHandle 
    = FindWindowEx(Proc.MainWindowHandle, IntPtr.Zero, "Edit"null);
            
    const int WM_GETTEXTLENGTH = 0xE;
            
    int intSize = SendMessageInt(vHandle, WM_GETTEXTLENGTH, 00);
            StringBuilder sb 
    = new StringBuilder(intSize);
            
    const int WM_GETTEXT = 0xD;
            SendMessageStr(vHandle, WM_GETTEXT, intSize, sb);
            Proc.CloseMainWindow();
            
    //Proc.Kill();
            byte[] bytData = System.Text.Encoding.Default.GetBytes(sb.ToString());  
            stream 
    = new MemoryStream(bytData);        
        }
    #endregion

        如果哪个网友有更好的解决方案,忘不吝告知,谢谢!

    MSN Direct日志系统可通过下面4个属性(我新添加),以决定以哪种方式输出日志信息。

        Logger.TraceLogEnable = true;

        Logger.ConsoleLogEnable = true;

        Logger.EventLogEnable = true;

    Logger.FileLogEnable = true;   

    当然以上对MSN Direct日志系统介绍,仅仅是皮毛,诸如XML配置、二进制序列化等等技术细节只有留待日后有时间再细说了。

    MSN项目简介

  • 相关阅读:
    Leetcode 92. Reverse Linked List II
    Leetcode 206. Reverse Linked List
    Leetcode 763. Partition Labels
    Leetcode 746. Min Cost Climbing Stairs
    Leetcode 759. Employee Free Time
    Leetcode 763. Partition Labels
    搭建数据仓库第09篇:物理建模
    Python进阶篇:Socket多线程
    Python进阶篇:文件系统的操作
    搭建数据仓库第08篇:逻辑建模–5–维度建模核心之一致性维度2
  • 原文地址:https://www.cnblogs.com/yefanqiu/p/1599370.html
Copyright © 2011-2022 走看看