在IIS 7.5托管的WCF服务中配置NLog,需将IIS应用名纳入日志路径
嘿,这个场景我之前帮朋友处理过,刚好能给你点实用的建议!针对IIS 7.5下多实例WCF服务要把应用名称(不是共用的站点名)纳入NLog日志路径的需求,我整理了几个靠谱的实现方案:
解决IIS 7.5中WCF多实例日志路径包含应用名称的问题
方式一:通过${aspnet-appbasepath}间接提取应用名称
虽然你提到倾向不用baseDir,但${aspnet-appbasepath}可以帮你从应用物理路径里截取最后一段(也就是应用名称),纯配置就能搞定,不用写额外代码。
在NLog.config里先定义变量:
<variable name="appName" value="${aspnet-appbasepath:dir=last}" />
然后在日志目标路径里引用这个变量:
<target name="serviceLog" xsi:type="File" fileName="C:\Logs\${iis-site-name}\${appName}\service-${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${message}" />
这个方式的前提是你的应用物理路径最后一段和IIS里的应用名称一致,适合大多数规范部署的场景。
方式二:自定义NLog布局渲染器精准获取应用名称
如果物理路径命名不规范(比如最后一段不是应用名),那可以自己写个布局渲染器,直接从IIS的应用虚拟路径里提取名称,更精准。
- 创建自定义渲染器类:
using NLog.LayoutRenderers; using System.Web.Hosting; [LayoutRenderer("iis-app-name")] public class IisAppNameLayoutRenderer : LayoutRenderer { protected override void Append(System.Text.StringBuilder builder, NLog.LogEventInfo logEvent) { // 从应用虚拟路径提取名称,比如"/MyServiceV2"会变成"MyServiceV2" var virtualPath = HostingEnvironment.ApplicationVirtualPath; var appName = string.IsNullOrEmpty(virtualPath) ? "RootApp" : virtualPath.TrimStart('/'); builder.Append(appName); } }
- 在NLog.config里注册这个自定义渲染器:
<extensions> <add assembly="你的WCF服务程序集名称" /> </extensions>
- 直接在日志路径里使用
${iis-app-name}变量:
<target name="serviceLog" xsi:type="File" fileName="C:\Logs\${iis-site-name}\${iis-app-name}\service-${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${message}" />
方式三:通过WCF服务行为注入全局变量
如果你的WCF服务有自定义的启动逻辑,也可以在服务初始化时获取应用名称,注入到NLog的全局诊断上下文(GDC)里。
- 创建自定义服务行为:
public class AppNameInitializerBehavior : IServiceBehavior { public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { var appName = HostingEnvironment.ApplicationVirtualPath.TrimStart('/'); NLog.GlobalDiagnosticsContext.Set("AppName", appName); } // 其他接口方法空实现即可 public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } }
- 在WCF配置里注册这个行为,然后在NLog.config里引用全局变量:
<target name="serviceLog" xsi:type="File" fileName="C:\Logs\${iis-site-name}\${gdc:item=AppName}\service-${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${message}" />
最后提醒下:要确保NLog.Web的版本和你的.NET Framework版本匹配(IIS7.5对应.NET Framework 4.x),同时给日志目录的写入权限分配给IIS应用池的运行身份(比如IIS_IUSRS组)。
内容的提问来源于stack exchange,提问作者Moelgaard
相关产品推荐
相关产品推荐

