OprLog日志中添加自定义内容

OprLog中的绝大部分数据成员都由框架负责填充,不需要应用程序自己来做日志埋点。

但是也允许应用添加一些自定义的内容:

  • 性能日志中的执行过程(可在JaegerUI中展示)
  • 普通的 time:message 文本日志消息
  • 预留字段(BizId,BizName,Text1-5)



添加自定义的执行过程

如果你需要记录某一段代码的执行时间,可参考下面的代码:

[Route("demo1.aspx")]
public string DemoCode1()
{
    DateTime startTime = DateTime.Now;   // 记录开始时间
    lock( s_lockObject1 ){

        // 记录上面 lock 的等待时间
        this.NHttpContext.PipelineContext.OprLogScope.AddStep(startTime, "wait_lock_1", "其它描述信息");

         Method1();
    }
    

    // 省略不相关代码。。。。。
}

要点提示:

  • 在执行前记录一个时间点, startTime
  • 调用 OprLogScope.AddStep(...) 方法

日志中的展示效果:

xx


xx




添加自定义的执行过程日志

有些时候,我们会直接使用 Console.WriteLine(..)输出一些日志,例如:

xx

这样做虽然不影响业务结果的正确性,但是极不建议,
它有一个很大的缺点:它们会淹没一些警告和异常消息!!



另一方面,这些消息输出后,再查看时,并不知道当时那个业务流程的其它关系信息,所以这些消息的价值非常有限!
所以,如果确实需要以后查看这些消息,可以将它们与OprLog保存在一起。

实现方法可参考代码:

[Route("demo2.aspx")]
public async Task<int> DemoCode2()
{
    OprLogScope logScope = this.NHttpContext.PipelineContext.OprLogScope;
 
    logScope.Log("正在生成报告第 1 页");
    // 省略一些业务代码块,,,,
    
    logScope.Log("正在生成报告第 2 页");
    // 省略一些业务代码块,,,,

    logScope.Log("正在生成报告第 3 页");
    // 省略一些业务代码块,,,,

    logScope.Log("正在生成报告第 4 页");
    // 省略一些业务代码块,,,,

    logScope.Log("正在生成报告第 5 页");
    // 省略一些业务代码块,,,,

    logScope.Log("正在发送报告");
    // 省略一些代码,,,,,,

    return 200;
}


要点提示:

  • 调用 OprLogScope.Log(...) 方法

日志中的展示效果:

xx




修改默认的日志字段

默认情况下,ClownFish会自动产生日志内容。如果觉得默认的日志内容不利于分析问题,应用程序可以修改它。

例如:默认情况下,消息处理的日志一般是这种形式:

xx

OprName, Url 基本上都是这样格式的。对于某些特定场景,这样的数据并不友好。

下面的代码将会对日志字段做出修改:

OprLogScope scope = context.OprLogScope;

// 修改日志中的2个成员,因为默认的取值不方便查看和统计:
// oprName=HttpRequestMessageHandler/Execute
// url=msg://RabbitMQ/async/HttpRequestMessageHandler/61dafeb52f06453c978bcf0cf879ede7/0

scope.OprLog.Url = httpOption.Url;
scope.OprLog.OprName = GetUrlActionName(httpOption.Url) ?? scope.OprLog.OprName;

// 额外增加2个字段
scope.OprLog.TenantId = tenantId;
scope.OprLog.Text1 = "serverId=" + serverId;




private static string GetUrlActionName(string url)
{
    if( url.IsNullOrEmpty() == false ) {

        // 取URL的最后一段,
        // 例如:"http://databus.com/v20/api/datacenter/agent/win/server/save-process-sample.svc"   得到  "save-process-sample.svc"
        int p = url.LastIndexOf('/');
        if( p > 0 && p != url.Length - 1 ) {
            return url.Substring(p + 1, url.Length - p - 1);
        }
    }

    return null;
}

最后的日志内容如下图:

xx

此时的日志内容更能反映业务处理场景。




日志中的预留字段

OprLog日志结构预留了7个字段可由应用程序来填充,方便记录一些与业务相关的数据到日志中。

/// <summary>
/// 业务ID,例如:工作流的流程ID
/// </summary>
public string BizId { get; set; }
/// <summary>
/// 业务操作名称,例如:某个工作流的节点名称
/// </summary>
public string BizName { get; set; }

/// <summary>
/// Text1,预留字段,具体含意由应用程序决定
/// </summary>
public string Text1 { get; set; }
public string Text2 { get; set; }
public string Text3 { get; set; }
public string Text4 { get; set; }
public string Text5 { get; set; }

其它未列出的字段,可根据观察实际运行后产生的日志,
如果没有赋值或者字段内容没有价值,也可以由应用程序来指定。