zoukankan      html  css  js  c++  java
  • ASP.Net MVC 之如何写Log

        日志(Log)对于一个程序的重要性不言而喻。操作系统的代码bootloader之后,就必须要实现串口打印log,因为你根本没有办法debug,这是早期移植Windows CE 5.0到6.0的经验,直到现在还是受用。集成开发环境,特别是Visual studio提供了强大的debug环境,特别是C#,Java等高级语言很容易发现NullReferenceException之类的异常,但对于C++等程序来说,没有Log简直没法做。其实对于线上环境来说,log还是很重要,因为你不可能很方便地重现环境。特别是对于facebook之类的公司,甚至利用log进行用户行为分析,这算是使用log的上乘了,我们先利用好log做好基本工作吧。

    1.Log写在哪儿

          1. 函数入口写上Log,并且要把参数也写上(我认为是必须 )

          2. 异常处写上Log(我认为是必须)

          3. 计算特别复杂,没有把握的地方写上(视自己的情况而定 )

          下面有代码例子:

                public ActionResult Index(int Id)

            {
                _logger.DebugFormat(
    "Comment load single comment by commentId :{0}", Id);
                
                
    try
                {
                    var comment 
    = _commentService.Get(Id);
                    
    return FormatResult(comment); 
                }
                
    catch(Exception e)
                {
                    _logger.Error(e.Message);
                }

                
    return FormatResult(InCityErrorMessage.INCITY_COMMENT_LOAD_FAILED);
            }

          

    2.正确使用Log的级别

          1. 函数入口处的Log和一般调试的Log使用debug级别,如上面的代码片段.

                _logger.DebugFormat("Comment load single comment by commentId :{0}", Id);

               

          2. 执行某项操作之后,使用info级别。例如支付成功,注册用户等。

          _logger.InfoFormat("Add order complete, orderId{0}, tradeNo:{1}, buyCount:{2}, unitPrice:{3}, orderDate:{4}, orderState:{5}", orderContract.Id, orderContract.TradeNo, orderContract.BuyCount, orderContract.Price, orderContract.OrderDate, orderContract.OrderStateText);        

          3. 异常处使用Error,或者明显出错的地方

              _logger.Error(e.Message);

          

          4. 发生严重地错误,导致破坏业务流程,例如短信发送或者订单处理,或者程序Crash.

    public virtual bool Send(BaseSMSContract contract)

            {            
                try
                {
                    _logger.Debug(
    "In SMSService Send");
                    //.......

                }
                
    catch (Exception e)
                {
                    _logger.Fatal(e.Message);
                }

                
    return false;

            }          

    3.根据级别不同使用将Log输出到文件,数据库

           能够利用现有的框架来写log那是非常方便了。我们项目中使用的是asp.net mvc框架,使用和Log4net很好地实现了log。

           下面介绍下具体的步骤: 

           

           1.下载Common.Logging,Common.Logging.Log4net,log4net三个dll, 并在项目中引用它们。

       

     

           2.Web.config (App.config同理)需要两个地方配置,一个是在configSections中配置

      <sectionGroup name="common">

           <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
        
    </sectionGroup>

        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>          

            

           3.另一个是配置common/logging和log4net. 

              

     <common>
        <logging>
          
    <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
            
    <arg key="configType" value="INLINE"/>
          
    </factoryAdapter>
        
    </logging>
      
    </common>
      
    <log4net>
        
        
    <!--输出到Visual studio输出窗口-->
        
    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">
          
    <layout type="log4net.Layout.PatternLayout">
            
    <!--格式-->
            
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
          
    </layout>
        
    </appender>
        
        
    <!--输出到文件-->
        
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">

          
    <!--文件名-->
          
    <file value="incity_api.log"/>

          
    <!--追加方式写-->
          
    <appendToFile value="true"/>
          
    <rollingStyle value="Size"/>

          
    <!--每次写10个文件后覆盖-->
          
    <maxSizeRollBackups value="10"/>

          
    <!--每个文件做大500k-->
          
    <maximumFileSize value="500KB"/>
          
    <staticLogFileName value="true"/>

          
    <!--格式-->
          
    <layout type="log4net.Layout.PatternLayout">
            
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
          
    </layout>
        
    </appender>

        
    <!--Ado net数据库,需要建立表eventlog,字段是ID, log(varchar), createTime(datetime), level(int)-->
        
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">

          
    <!--log到了512个字节才会输出到数据库 -->
          
    <bufferSize value="512"/>
          
          
    <!--只有级别在INFO上的才会写Log-->
          
    <filter type="log4net.Filter.LevelRangeFilter">
            
    <param name="LevelMin" value="INFO"/>
            
    <param name="LevelMax" value="FATAL"/>
          
    </filter>
          
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089"/>

          
    <!--数据库连接 -->
          
    <connectionString value="server=.\SQLEXPRESS;database=incity;integrated security=false;persist security info=True;UID=sa;PWD=cry.cap.fox-999"/>

          
    <!--执行的数据库命令 -->
          
    <commandText value="INSERT INTO eventlog ([log],[createTime],[level]) VALUES (@log, @createTime, @level)"/>

          
    <!--数据库参数 -->
          
    <parameter>
            
    <parameterName value="@createTime"/>
            
    <dbType value="DateTime"/>
            
    <layout type="log4net.Layout.RawTimeStampLayout"/>
          
    </parameter>
          
          
    <parameter>
            
    <parameterName value="@log"/>
            
    <dbType value="String"/>
            
    <size value="1024"/>
            
    <layout type="log4net.Layout.PatternLayout">
              
    <conversionPattern value="%message"/>
            
    </layout>
          
    </parameter>
          
          
    <parameter>
            
    <parameterName value="@level"/>
            
    <dbType value="String"/>
            
    <size value="50"/>
            
    <layout type="log4net.Layout.PatternLayout">
              
    <conversionPattern value="%level"/>
            
    </layout>
          
    </parameter>
        
    </appender>
        
        
    <root>
          
    <level value="DEBUG"/>
          
    <appender-ref ref="TraceAppender"/>
          
    <appender-ref ref="RollingFileAppender"/>
          
    <appender-ref ref="AdoNetAppender"/>
        
    </root>
      
    </log4net>

        

        上述的配置主要实现了下面的功能: 

    • log同时输出到了文件,数据库,Visual Studio输出(其实还可以有udp网络等等),主要都是靠 log4net不同的Appender实现。
    • log输出到文件的时候,是追加方式写,每个日志文件最大500k,写了10个后又从第一个开始覆盖
    • 只有info级别以上的log才会写到数据库中,不是每次写日志都会写数据库,只有到了512个字节才会flush到数据表eventlog中,eventlog需要自己先创建好,数据库会记录时间,级别,内容等信息。

     4.代码中使用

    下面的代码片段讲述了如何使用log4net,OK,快去看看你的日志吧。

    using Common.Logging;


    namespace InCity.Restful.Controllers
    {
        
    public class CommentController : BaseController
        {
            
    private readonly CommentService _commentService;
            
    private readonly UserService _userService;
            
    private readonly ILog _logger = LogManager.GetCurrentClassLogger();

            
    public CommentController(CommentService commentService, 
                                     UserService userService)
            {
                _commentService 
    = commentService;
                _userService 
    = userService;
            }

            
    public ActionResult Index(int Id)
            {
                _logger.DebugFormat(
    "Comment load single comment by commentId :{0}", Id);
                
                
    try
                {
                    var comment 
    = _commentService.Get(Id);
                    
    return FormatResult(comment); 
                }
                
    catch(Exception e)
                {
                    _logger.Debug(e.Message);
                }

                
    return FormatResult(InCityErrorMessage.INCITY_COMMENT_LOAD_FAILED);

            }

  • 相关阅读:
    ZeptoLab Code Rush 2015
    UVa 10048 Audiophobia【Floyd】
    POJ 1847 Tram【Floyd】
    UVa 247 Calling Circles【传递闭包】
    UVa 1395 Slim Span【最小生成树】
    HDU 4006 The kth great number【优先队列】
    UVa 674 Coin Change【记忆化搜索】
    UVa 10285 Longest Run on a Snowboard【记忆化搜索】
    【NOIP2016提高A组模拟9.28】求导
    【NOIP2012模拟10.9】电费结算
  • 原文地址:https://www.cnblogs.com/enjoyeclipse/p/2106951.html
Copyright © 2011-2022 走看看