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(...) 方法
日志中的展示效果:
添加自定义的执行过程日志
有些时候,我们会直接使用 Console.WriteLine(..)输出一些日志,例如:
这样做虽然不影响业务结果的正确性,但是极不建议,
它有一个很大的缺点:它们会淹没一些警告和异常消息!!
另一方面,这些消息输出后,再查看时,并不知道当时那个业务流程的其它关系信息,所以这些消息的价值非常有限!
所以,如果确实需要以后查看这些消息,可以将它们与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(...) 方法
日志中的展示效果:
修改默认的日志字段
默认情况下,ClownFish会自动产生日志内容。如果觉得默认的日志内容不利于分析问题,应用程序可以修改它。
例如:默认情况下,消息处理的日志一般是这种形式:
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;
}
最后的日志内容如下图:
此时的日志内容更能反映业务处理场景。
日志中的预留字段
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; }
其它未列出的字段,可根据观察实际运行后产生的日志,
如果没有赋值或者字段内容没有价值,也可以由应用程序来指定。