日志组件

本文主要介绍ClownFish内置日志,日志组件,及日志配置相关内容。



执行主体

以下3类场景被ClownFish视做执行主体,为自动为它们产生OprLog日志

  • HTTP响应 - HttpAction (Controller)
  • 消息处理 - MessageHandler
  • 后台任务 - BackgroundTask



内置日志

ClownFish/Nebula内置5类日志

  1. 操作日志:每个【执行主体】每次执行都会产生一条操作日志OprLog
  2. 异常日志:【执行主体】在发生异常时出现,异常信息会合并到当次OprLog中
  3. 性能日志:【执行主体】都会有性能监控,如果超过性能阀值,将产生性能日志,合并到OprLog中
  4. 框架性能日志:记录ASP.NET执行过程中耗费的性能,如果超过性能阀值,将产生性能日志 NebulaLog
  5. 致命异常日志:会记录导致程序异常退出的异常,错误消息固定写入到系统临时目录下,文件名: {sys-temp-directory}_ClownFish_net_error_{date}.txt



日志组件

日志组件由ClownFish提供,主要特性有:

  • 支持结构化日志(非随意性文本)
  • 区分日志数据类型和写入器概念
    • 日志数据类型就是一个.NET类型,包含日志的数据成员定义
    • 写入器是指将日志数据对象写入到哪里(实现持久化)
  • 一个日志类型可以对应多个写入器(同时写到多个地方)
  • 日志采用异步设计,不阻塞调用线程



写日志

可以在代码中调用以下API

/// <summary>
/// 日志记录的工具类
/// </summary>
public static class LogHelper
{
    /// <summary>
    /// 记录指定的日志信息
    /// 说明:此方法是一个异步版本,内部维护一个缓冲队列,每 XXms 执行一次写入动作
    /// </summary>
    /// <typeparam name="T">日志信息的类型参数</typeparam>
    /// <param name="info">要写入的日志信息</param>
    public static void Write<T>(T info) where T: class, ITime

    /// <summary>
    /// 直接将一个异常对象写入到异常日志
    /// </summary>
    /// <param name="ex"></param>
    /// <param name="addition"></param>
    public static void Write(Exception ex, string addition = null)
}



注意事项

虽然LogHelper提供了一个记录异常对象的方法,但是不建议在以下场景中调用

  • HTTP请求过程中(Controller,BLL)
  • 消息处理过程中(MessageHandler)
  • 后台任务中(BackgroundTask)

因为这些执行环境中ClownFish有异常处理机制,会统一记录异常,而且异常日志会有上下文关联信息。



日志配置

在每个项目中,日志的配置文件是ClownFish.Log.config,以下是Nebula类库中的默认配置

<?xml version="1.0" encoding="utf-8"?>
<LogConfig>
    <!--是否启用日志写入功能,总开关-->
    <Enable>true</Enable>
    <!--日志从缓存区写入持久化存储的间隔时间,单位:毫秒-->
    <TimerPeriod>500</TimerPeriod>
    <!--性能日志的阀值参数,超过这个阀值将会认为是“慢”操作,此时会标记 IsSlow=1,并记录请求,单位:毫秒-->
    <Performance HttpExecute="100" HandleMessage="200"  />
    <!-- 【本地】日志文件相关配置 -->
    <File RootPath="Logs" MaxLength="500M" MaxCount="100" />

    <Writers>
        <!--定义几个内置的写入器 -->
        <Writer Name="Xml" Type="ClownFish.Log.Writers.XmlWriter, ClownFish.net" />
        <Writer Name="Json" Type="ClownFish.Log.Writers.JsonWriter, ClownFish.net" />
        <Writer Name="Json2" Type="ClownFish.Log.Writers.Json2Writer, ClownFish.net" />
        <Writer Name="Http"  Type="ClownFish.Log.Writers.HttpJsonWriter, ClownFish.net" />
        <Writer Name="ES"    Type="ClownFish.Log.Writers.ElasticsearchWriter, ClownFish.net" />
        <Writer Name="Rabbit2" Type="ClownFish.Log.Writers.RabbitHttpWriter, ClownFish.net" />
        <Writer Name="Rabbit" Type="ClownFish.Rabbit.Log.RabbitWriter, ClownFish.Rabbit" />
        
        <!--如果项目中有自定义的写入器,请自行在项目中创建 ClownFish.Log.config 并添加 【你新增的】写入器-->
    </Writers>
    
    <Types>
        <!--定义支持的数据类型,并为每种数据类型配置使用哪种写入器,
            如果某个数据类型同时指定了多个写入器,将会以不同的持久化方式同时记录多次。-->
        <Type DataType="ClownFish.Log.Logging.OprLog, ClownFish.net" Writers="NULL" />
        <Type DataType="ClownFish.Log.Logging.InvokeLog, ClownFish.net" Writers="NULL" />
        <Type DataType="Nebula.Log.NebulaLog, Nebula.net" Writers="NULL" />

        <!--### 注意:1,为能让配置文件通用,这里并没有为每个日志数据类型指定关联的写入器,
                      2,写入器的关联设置在配置参数 ClownFish_Log_WritersMap 中一次性指定  -->
    </Types>
</LogConfig>

以上默认配置中,所有日志数据类型对应的写入器是NULL,即不执行任何写入。

实际使用时,可以在配置服务中增加一个参数项来全局指定:
xx

name: ClownFish_Log_WritersMap
value: InvokeLog=Rabbit;OprLog=es;NebulaLog=es;*=NULL

value的含意是:

  • InvokeLog=Rabbit    表示 ClownFish.Log.Logging.InvokeLog 类型将使用 Rabbit 写入器
  • OprLog=es;NebulaLog=es    表示 OprLog和NebulaLog,这2类日志使用 ES写入器
  • *=NULL     *星号表示其它(未列出的)日志类型,它们将使用 NULL写入器(即丢弃)

举例:如果需要将OprLog日志同时写入ES和本地JSON文件,可以这样设置:
InvokeLog=Rabbit;OprLog=es,Json;*=NULL