如何为NLOG设置每个请求全局变量



我正在努力以我们的Web应用程序最有用的方式设置NLOG

我的思考过程如下

  • 启动新请求
  • 生成新的GUID
  • log webapi事件带GUID
  • 带GUID的日志服务层事件
  • 为下一个请求生成新的GUID

这样,很容易跟踪从请求开始到完成的完整事件

在某些情况下,我要同时运行服务方法,如果线程影响此解决方案

我尝试设置以下内容,但是${activityid}似乎并未将其列入输出

https://github.com/nlog/nlog/wiki/wiki/trace-activity-id-layout-renderer

将值添加到您的httpContext并使用NLOG读取。

例如。

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

在您的nlog.config

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

文档中的更多示例

您需要nlog.web或nlog.web.aspnetcore!安装说明

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}"

最新更新