如何为NLog设置每个请求的全局变量?

时间:2017-06-24 13:25:37

标签: c# .net logging nlog

我正在以最有用的方式为我们的Web应用程序设置NLogs

我的思考过程如下

  • 启动新请求
  • 生成新的guid
  • 使用guid记录webapi事件
  • 使用guid
  • 记录服务层事件
  • 为下一个请求生成新的guid

通过这种方式,可以轻松跟踪从请求开始到结束的所有事件系列

如果线程影响此解决方案,还有一些我并行运行服务方法的方案

我已尝试设置以下内容,但<form action="<?php echo base_url();?>home/create" method="POST" role="form" enctype="multipart/form-data" > 似乎没有转移到输出

https://github.com/NLog/NLog/wiki/Trace-Activity-Id-Layout-Renderer

2 个答案:

答案 0 :(得分:3)

将值添加到httpContext并使用NLog读取。

E.g。

HttpContext.Current.Items["myvariable"] = 123;

在你的NLog.config

${aspnet-item:variable=myvariable} - produces "123"

More examples in the docs

你需要NLog.web或NLog.web.aspnetcore! Install instructions

答案 1 :(得分:1)

Ultimatley这就是我最终做的事情

我设置了一个新类,以便在系统的任何地方轻松获取请求数据

public static class HttpContextRequestData
{
    public static string RequestGuid
    {
        get
        {
            if (HttpContext.Current.Items["RequestGuid"] == null)
                return string.Empty;
            else
                return HttpContext.Current.Items["RequestGuid"] as string;
        }
        set
        {
            HttpContext.Current.Items["RequestGuid"] = value;
        }
    }


    public static DateTime RequestInitiated
    {
        get
        {
            if (HttpContext.Current.Items["RequestInitiated"] == null)
                return DateTime.Now;
            else
                return Convert.ToDateTime(HttpContext.Current.Items["RequestInitiated"]);
        }
        set
        {
            HttpContext.Current.Items["RequestInitiated"] = value;
        }
    }
}

然后我设置global.asax为每个请求设置一个Guid。我还添加了一些基本规则来记录请求长度,如果超过1分钟则会致命

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpContextRequestData.RequestGuid = Guid.NewGuid().ToString();
        HttpContextRequestData.RequestInitiated = DateTime.Now;
        logger.Info("Application_BeginRequest");
    }

    void Application_EndRequest(object sender, EventArgs e)
    {
        var requestAge = DateTime.Now.Subtract(HttpContextRequestData.RequestInitiated);

        if (requestAge.TotalSeconds <= 20)
            logger.Info("Application_End, took {0} seconds", requestAge.TotalSeconds);
        else if (requestAge.TotalSeconds <= 60)
            logger.Warn("Application_End, took {0} seconds", requestAge.TotalSeconds);
        else
            logger.Fatal("Application_End, took {0} seconds", requestAge.TotalSeconds);
    }

然后为了简化操作,我设置了一个自定义的NLog LayoutRender,以便RequestGuid自动添加到记录事件中,而不必记住包含它

[LayoutRenderer("RequestGuid")]
public class RequestGuidLayoutRenderer : LayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        builder.Append(HttpContextRequestData.RequestGuid);
    }
}

在NLog.config中注册了RequestGuidLayoutRenderer

 <extensions>
    <add assembly="InsertYourAssemblyNameHere"/>
 </extensions>

最后添加到我的目标配置

<target name="AllLogs" xsi:type="File" maxArchiveFiles="30" fileName="${logDirectory}/AllLogs.log" layout="${longdate}|${RequestGuid}|${level:uppercase=true}|${message}|${exception:format=tostring}"