我有一个包含多个 Web 服务的 Web 应用程序。此 Web 应用程序具有业务和持久层。是否可以为每个 Web 服务使用单独的日志附加程序(日志文件)?
这也适用于网页。本质上,我想分离我的日志不是基于类或层/命名空间,而是从入口点,可以是 Web 服务或网页。
您可以定义要在每个 Web 服务中获取的记录器:
namespace log4net
{
public class LogManager
{
public static ILog GetLogger(string name);
public static ILog GetLogger(Type type);
}
}
然后在您的应用程序中,您可以适当地调用每个记录器:
public class MyApp
{
// Define a static logger variable so that it references the
// Logger instance named "MyApp".
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
static void Main(string[] args)
{
// Set up a simple configuration that logs on the console.
BasicConfigurator.Configure();
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
}
}
确保更改typeof
为正确的 Web 服务。
来源和更多信息在这里。
我建议在每个页面中使用嵌套诊断上下文(NDC),然后根据 NDC 过滤日志输出。
NDC 信息将包含在从当前线程上下文记录的事件中,其中将包括页面代码、服务代码、存储库代码等。
使用对 NDC 内容的过滤,您可以将日志输出与各种服务分开。
Gortok,这是我们处理日志的典型方式。但是,我的意思有所不同,我认为我的问题不够清楚。
这是一个假设的示例:我们有一个 Web 应用程序,它有一些管理页面和一些客户页面,我们希望每组页面有两个不同的 admin.log 和 customer.log 文件。两组页面都使用业务层(包括CustomerService、OrderService等)和存储层CustomerRepository、OrderRepository等)。应用程序中的所有层和类都在两组页面中使用,但我们希望将日志分开。当管理页面中发生异常并且您浏览与跟踪问题相关的日志时,这会更容易。您提到的记录事物的典型方式的解决方案并未涵盖这种情况,因为当您使用typeof(MyApp)(MyApp 是类或命名空间的名称)不会根据用户发起请求的页面来指示要使用的附加程序。
也许处理这种情况的一种方法是在整个应用程序中使用域值对象,并在用户在 UI 级别发起请求时将其值设置为适当的记录器,并在您在每个中定义记录器时使用该值作为构造函数参数班级。但我想知道在 log4net 中是否有更好的方法来处理我不知道的这种方法。
我的问题现在更清楚了吗?
我可以使用 PropertyFilter 来做到这一点。我在配置文件中定义了以下附加程序:
<appender name="UiFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Log1.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="5MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
<filter type="log4net.Filter.PropertyFilter">
<Key value="channel"/>
<StringToMatch value="ui" />
<AcceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
<appender name="WsFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Log1.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="5MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
<filter type="log4net.Filter.PropertyFilter">
<Key value="channel"/>
<StringToMatch value="ws" />
<AcceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
上述 appender 的重要部分是标签。当用户使用 UI 时,我将“channel”属性设置为“ui”,如下代码:
log4net.GlobalContext.Properties["channel"] = "ui";
当用户使用网络服务时,我使用以下代码:
log4net.GlobalContext.Properties["channel"] = "ws";
发起请求时,我需要在最高级别的条目上设置“通道”属性。