【问题标题】:How to get IIS site name in NLog如何在 NLog 中获取 IIS 站点名称
【发布时间】:2014-10-01 07:47:12
【问题描述】:

我正在尝试动态记录多个 IIS 站点的站点名称,而不是单独为每个站点提供名称作为变量。我的 NLog 配置是集中式的,这意味着每个站点都引用同一个 NLog 配置文件。另外,我不能对站点本身进行更改,我只能修改配置文件。

例如,在处理 WinForms 应用程序时,我可以使用 ${processname} 布局渲染器。但是,对于 IIS 站点,这将返回 ISS 应用程序池进程名称,例如 w3wp。但这不允许我区分多个 IIS 站点。

我目前的解决方案是检查进程名称是否为 w3wp,然后使用 ${windows-identity} 布局渲染器,因为这将在 Identity 设置为 ApplicationPoolIdentity 时返回应用程序池的名称。但这并不总是可能/想要的。

我也一直在考虑使用 ${basedir},但我找不到删除任何不必要部分的方法,因为我只需要路径的最后一个文件夹。

有什么想法吗?

【问题讨论】:

    标签: asp.net iis iis-7.5 nlog


    【解决方案1】:

    我不知道有没有内置的功能可以知道这种信息,但是你可以创建自己的LayoutRenderer,创建代码如下:

    namespace NLog.Extensions.LayoutRenderers
    {
        using System.Text;
        using NLog.LayoutRenderers;
    
        [LayoutRenderer("IISSiteName")]
        public class IISSiteName : LayoutRenderer
        {
            protected override void Append(StringBuilder builder, LogEventInfo logEvent)
            {
                if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
                    builder.Append(System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName());
            }
        }
    }
    

    您必须编译此代码并使用 NLog.config 文件中的标记添加 DLL,如下所示

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" >
    
      <extensions>
        <add assemblyFile="c:\\your-path-to-dll" />
      </extensions>
    
      <targets>
        <target xsi:type="File" name="file" fileName="${basedir}\file.txt" layout="${date} ${level} ${IISSiteName} "/>
      </targets>
    
      <rules>
        <logger name="*" minlevel="Trace" writeTo="file" />
      </rules>
    
    </nlog>
    

    如果将编译后的 DLL 作为对项目的引用添加,则必须更改程序集的 assemblyPath 并将其添加为 Namespace.Class 格式。

    我让它在我的电脑上运行,所以它应该可以正常运行。如果没有,请告诉我。

    问候

    【讨论】:

    • 到目前为止我测试的每个站点都完成了这项工作。接受这个答案。
    【解决方案2】:

    在您的 NLog.config 文件中,添加如下内容:

    <parameter name="@WebsiteName" layout="${gdc:WebsiteName}"/> <!-- custom field! -->
    

    然后,当您初始化记录器时,请执行以下操作:

    var logger = LogManager.GetCurrentClassLogger();
    GlobalDiagnosticsContext.Set("WebsiteName",System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName());
    

    希望这会有所帮助!

    编辑:我现在意识到您无法更新实际的网络源。对不起。这会更好吗(您必须将 NLog.Exended.dll 和扩展节点添加到配置文件中):

    <parameter name="@WebsiteName" layout="${aspnet-request:serverVariable=SERVER_NAME}"/> <!-- IIS Server Variable -->
    

    可能是 HTTP_HOST 或 SERVER_NAME。我总是让那些切换。

    您必须在 NLog.config 文件以及 NLog.Extended.dll 中添加扩展节点:

    <extensions><add assembly="NLog.Extended" assemblyFile="NLog.Extended.dll"/></extensions>
    

    【讨论】:

    • Tino 无法修改正在运行的应用程序的代码,但这是个好主意。
    • 这不起作用。我在我的工作示例中添加了两个 serverVariables:SERVER_NAME 写了“localhost”,而 HTTP_HOST 写了“localhost:55021”,我的答案中的 customRenderer 写了“Pricing.Estandar.Ejemplos.Logs.Web(1)”,它对应于站点名称。 SiteName 是您从 IIS 获得的,而不是从 HTTP_CONTEXT 获得的,所以我认为您无法通过请求获得它,但不确定
    • 这在使用 APP_POOL_ID 时应该可以工作,但是一些站点是 WCF REST 服务(显然)并且服务器变量最终为空。我更喜欢使用这个解决方案(在编辑之后),因为它似乎是最直接的。
    • (本来想投票赞成你的答案(以及接受的答案),但我还不能......)
    【解决方案3】:

    现在有一个NLog.Web package,它有一个布局渲染器${iis-site-name},它应该可以满足您的需求。

    【讨论】:

      【解决方案4】:

      也许我还没有理解你的限制,但有什么阻止你使用 asp net 应用程序布局渲染器:

      https://github.com/NLog/NLog/wiki/AspNetApplication-layout-renderer

      ${aspnet-application:variable=String}
      

      ??

      【讨论】:

      • 这需要我为每个站点单独定义站点名称作为变量。这是我试图避免的。
      • 你可以使用不同的应用程序池吗?我认为您无法更改任何代码,因此无法选择编写自定义渲染器?
      • 每个站点都有自己的应用程序池。编写自定义渲染器确实不是一种选择。
      • 使用不同的应用程序池,您可以获得通过名称标识应用程序池的服务器变量并将其传递给 aspnet-application 渲染器。
      • @Tino,正如我在回答中发布的那样,编写 CustomRenderer 应该是一个选项,您可以使用“”标签加载动态扩展 NLog 的 DLL。所以你不需要修改应用程序内部的任何代码。
      【解决方案5】:

      如下所示的 nlog.config 适用于我的 dotnet 核心项目。只需将文件名设置为fileName="C:\[yourPath]\Log\${iis-site-name}${date:format=yyyyMMdd}.txt"

      <?xml version="1.0" encoding="utf-8" ?>
      <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          autoReload="true"
          internalLogLevel="info"
          internalLogFile="c:\temp\internal-nlog.txt">
      
          <!-- the targets to write to -->
          <targets>
              <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
              <target xsi:type="File" name="ownFile-web" fileName="C:\inetpub\archive\Log\${iis-site-name}${date:format=yyyyMMdd}.txt"
                      layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
          </targets>
      
          <!-- rules to map from logger name to target -->
          <rules>
              <!--All logs, including from Microsoft-->
              <!--<logger name="*" minlevel="Debug" writeTo="allfile" />-->
      
              <!--Skip non-critical Microsoft logs and so log only own logs-->
              <logger name="Microsoft.*" maxLevel="Info" final="true" />
              <!-- BlackHole without writeTo -->
              <logger name="*" minlevel="Debug" writeTo="ownFile-web" />
          </rules>
      </nlog>
      

      【讨论】:

        猜你喜欢
        • 2010-12-11
        • 1970-01-01
        • 2014-02-07
        • 1970-01-01
        • 2014-07-30
        • 2013-03-03
        • 2012-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多