C# 如何为各种控制器和asp net mvc过滤器创建nlog记录器?
我需要通过编程为每个控制器(比如:文档、客户和仓库)和控制器上方的过滤器(记录发送到每个操作的参数)创建日志记录器。每个控制器逻辑应记录到另一个文件,例如Documents.csv、Customers.csv和Warehouses.csvC# 如何为各种控制器和asp net mvc过滤器创建nlog记录器?,c#,asp.net-mvc,logging,nlog,C#,Asp.net Mvc,Logging,Nlog,我需要通过编程为每个控制器(比如:文档、客户和仓库)和控制器上方的过滤器(记录发送到每个操作的参数)创建日志记录器。每个控制器逻辑应记录到另一个文件,例如Documents.csv、Customers.csv和Warehouses.csv 目前我有一个nlog记录器的包装器。包装器通过构造函数注入控制器实例,然后通过LogManager初始化内部nlog logger。初始化创建新的目标和日志级别,并将其分配给LogManager.Configuration 问题是,在几次请求之后,每个记录器都
目前我有一个nlog记录器的包装器。包装器通过构造函数注入控制器实例,然后通过LogManager初始化内部nlog logger。初始化创建新的目标和日志级别,并将其分配给LogManager.Configuration 问题是,在几次请求之后,每个记录器都会记录到每个文件,因此来自客户的ex.logic会记录到Customers.csv,反之亦然,来自过滤器的记录器也是如此 然后,我应该如何为每个控制器和过滤器分别配置具有不同目标的单独日志记录器 我更喜欢编程配置,而不是通过xms等 适配器(按要求):
public class Logger : ILogger
{
private NLog.Logger _logger;
string _deployVersion;
public Logger(string deploymentVersion)
{
_deployVersion = deploymentVersion;
}
public void Init(string loggerName)
{
_logger = NLog.LogManager.GetLogger(loggerName);
}
public void Init(string loggerName, string header, string layout, Level level)
{
LoggingConfiguration config;
if (NLog.LogManager.Configuration == null)
{
config = new LoggingConfiguration();
}
else
{
config = LogManager.Configuration;
}
if (config.FindTargetByName(loggerName) == null)
{
var target = CreateTarget(loggerName, header, layout, level); //configures target: path, archives and layout
config.AddTarget(loggerName, target);
var logLevel = GetLogLevel(level); //translates Level enum to NLog level
var rule1 = new LoggingRule("*", logLevel, target);
config.LoggingRules.Add(rule1);
LogManager.Configuration = config;
}
_logger = LogManager.GetLogger(loggerName);
}
...
//Info, Debug etc. methods
很好,您已经在这里使用了一个接口,这使得这个模式更容易生成 这里的主要问题是责任,因为控制器代码(我假设)将调用
Init(字符串日志名、字符串头、字符串布局、级别)
。这可能不是最佳实践,因为您可能需要多次重复此代码,并且控制器可能不应该关心日志的去向或其格式…只关心使用日志的事实
使用工厂获取正确的记录器类型,而不是直接注入。例如,CustomerLogger:ILogger
:
public class LogFactory
{
public ILogger Get<T>() where T : ILogger
{
ILogger instance = null;
if (typeof(T) == typeof(CustomerLogger))
{
instance = (T)Activator.CreateInstance(typeof(T), "CustomerLogger", "Header", "Layout", Level.Verbose);
}
else if (...)
{
...etc
}
return instance;
}
}
公共类日志工厂
{
public ILogger Get()其中T:ILogger
{
ILogger实例=null;
if(typeof(T)=typeof(CustomerLogger))
{
instance=(T)Activator.CreateInstance(typeof(T),“CustomerLogger”,“Header”,“Layout”,Level.Verbose);
}
否则如果(…)
{
等
}
返回实例;
}
}
这意味着您可以将ILogger
混凝土的管理和创建留给工厂
请注意,我正在传入字符串日志名、字符串头、字符串布局、级别
,这样您就可以在CustomerLogger
构造函数中调用Init
。然后,您可以使用不同的ILogger
实现来满足您的需要
然后,您可以让LogFactory
使用一个接口并将其注入控制器,或者简单地在控制器中新建工厂,无论您调用LogFactory.Get()
。出于单元测试的目的,选项A会更好
希望这有帮助 太好了,您已经在这里使用了一个界面,这使得这个模式更容易生成 这里的主要问题是责任,因为控制器代码(我假设)将调用
Init(字符串日志名、字符串头、字符串布局、级别)
。这可能不是最佳实践,因为您可能需要多次重复此代码,并且控制器可能不应该关心日志的去向或其格式…只关心使用日志的事实
使用工厂获取正确的记录器类型,而不是直接注入。例如,CustomerLogger:ILogger
:
public class LogFactory
{
public ILogger Get<T>() where T : ILogger
{
ILogger instance = null;
if (typeof(T) == typeof(CustomerLogger))
{
instance = (T)Activator.CreateInstance(typeof(T), "CustomerLogger", "Header", "Layout", Level.Verbose);
}
else if (...)
{
...etc
}
return instance;
}
}
公共类日志工厂
{
public ILogger Get()其中T:ILogger
{
ILogger实例=null;
if(typeof(T)=typeof(CustomerLogger))
{
instance=(T)Activator.CreateInstance(typeof(T),“CustomerLogger”,“Header”,“Layout”,Level.Verbose);
}
否则如果(…)
{
等
}
返回实例;
}
}
这意味着您可以将ILogger
混凝土的管理和创建留给工厂
请注意,我正在传入字符串日志名、字符串头、字符串布局、级别
,这样您就可以在CustomerLogger
构造函数中调用Init
。然后,您可以使用不同的ILogger
实现来满足您的需要
然后,您可以让LogFactory
使用一个接口并将其注入控制器,或者简单地在控制器中新建工厂,无论您调用LogFactory.Get()
。出于单元测试的目的,选项A会更好
希望这有帮助 “目前我有一个nlog logger的包装器。”-你能在你的问题中提供这一点,以便答案可以在必要时对其进行调整吗?添加了包装器代码:)如果要求是“每个控制器一个文件”,那么有一个更简单的方法。还是我遗漏了什么?@Julian问题是记录器被传递到下面的一些类,并在那里使用,而不是直接在控制器中使用。但我想将这种体系结构中创建的逻辑用于另一个日志文件。是的,我知道整个日志本可以做得更好,但现在没有时间重构:/G0dsquad-谢谢,我会尝试使用您的解决方案,很快会返回到答案:)“目前我有一个nlog logger的包装器。”-您能否在您的问题中提供这一点,以便答案可以在必要时对其进行调整?添加了包装代码:)如果要求是“每个控制器一个文件”,则有一种更简单的方法。还是我遗漏了什么?@Julian问题是记录器被传递到下面的一些类,并在那里使用,而不是直接在控制器中使用。但我想将这种体系结构中创建的逻辑用于另一个日志文件。是的,我知道整个日志本可以做得更好,但现在没有时间进行重构:/G0dsquad-谢谢,我很快会尝试使用您的解决方案,并会返回到答案:)