ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – Windsor Logging Facility:控制日志名称

2019-05-17 19:55:33  阅读:196  来源: 互联网

标签:c nlog castle-windsor


我正在使用Windsor Logging Facility和NLog集成向项目添加日志记录.

而不是遵循Windsor文档推荐的将Log属性添加到我想要支持日志记录的类的做法,我决定尝试使用动态拦截来实现它.到目前为止,拦截器相当基本;它只是使用构造函数注入来获取ILogger的一个实例:

class LoggingInterceptor : IInterceptor
{
    private readonly ILogger _logger;
    public LoggingInterceptor(ILogger logger)
    {
        if (logger == null) throw new ArgumentNullException("logger");
        _logger = logger;
    }

    public void Intercept(IInvocation invocation)
    {
        // just a placeholder implementation, I'm not actually planning to do this ;)
        _logger.Info(invocation.Method.Name);
        invocation.Proceed();
    }
}  

除此之外,我所做的只是注册拦截器并将其应用于组件的最小值,而日志工具则负责其余部分.

container.Register(Component.For<LoggingInterceptor>().LifeStyle.Transient);

container.Register(
    Component.For<IEmployeeRepository>()
    .ImplementedBy<EmployeeRepository>()
    .Interceptors(InterceptorReference.ForType<LoggingInterceptor>()).First);

到目前为止这么好 – 有点像.我得到的记录器遵循NLog推荐的每个类一个记录器的做法.在这种情况下,我认为这不是一个很好的选择.这意味着每条消息都会转到一个名为“MyApplication.Interceptors.LoggingInterceptor”的日志,这个日志并不是非常有用.

我更喜欢在已经应用了记录器的抽象之后命名日志.例如,如果记录器已应用于IEmployeeRepository的实现,则日志应命名为EmployeeRepository.这可行吗?

编辑:
我已经尝试实现自定义ILoggerFactory并指示容器使用它.然而,我很快遇到了障碍:当Windsor进入工厂时,提供的唯一信息是获取记录器的对象类型.没有提供有关该对象的其他信息,因此ILoggerFactory无法找到拦截器已应用的抽象.

我注意到ILoggerFactory.Create()有两个重载接受字符串作为参数.温莎似乎没有直接使用其中任何一个,但人们会认为他们必须在那里是有原因的.流畅的注册API中是否有可用于指定使用特定字符串的内容?

解决方法:

这是一个与你的问题非常相似的问题,它有一个公认的答案.在链接中,发布答案的人建议使拦截器依赖于ILoggerFactory,在Intercept方法中,使用IInvocation.TargetType作为类型发送到ILoggerFactory以获取适当的记录器.

注意,我不使用Castle,所以我不能对这个建议发表更多评论.

public class LoggingInterceptor : IInterceptor
{
    private readonly ILoggerFactory _loggerFactory;

    public LoggingInterceptor(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    public void Intercept(IInvocation invocation)
    {
        var logger = _loggerFactory.Create(invocation.TargetType);
        if (logger.IsDebugEnabled)
        {
            logger.Debug(CreateInvocationLogString(invocation));
        }
        try
        {
            invocation.Proceed();
        }
        catch (Exception e)
        {
            logger.Warn(CreateInvocationLogString(invocation));
            throw;
        }
        logger.Info(CreateInvocationLogString(invocation));
    }

    private static String CreateInvocationLogString(IInvocation invocation)
    {
        var sb = new StringBuilder(100);
        sb.AppendFormat("Called: {0}.{1}(", invocation.TargetType.Name, invocation.Method.Name);
        foreach (var argument in invocation.Arguments)
        {
            var argumentDescription = argument == null ? "null" : argument.ToString();
            sb.Append(argumentDescription).Append(",");
        }
        if (invocation.Arguments.Any())
        {
            sb.Length--;
        }
        sb.Append(")");
        return sb.ToString();
    }
}

Castle: How can i get the correct ILogger in the logging interceptor?

您可能已经看过这个,但这里有一个指向Castle示例的链接,该示例显示了如何创建日志记录拦截器以及显然如何为包装类型创建记录器:

http://docs.castleproject.org/Windsor.Introduction-to-AOP-With-Castle.ashx

编辑:ILoggerFactory for nlog的实现是ExtendedNLogFactory,它在Castle.Core-NLog nuget包中(http://www.nuget.org/packages/Castle.Core-NLog)

标签:c,nlog,castle-windsor
来源: https://codeday.me/bug/20190517/1123632.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有