从 ILogger 访问当前 HttpContext

2024-03-06

在 ASP.NET Core 1.0 中,我有一个自定义实现ILoggerProvider and ILogger接口。我希望能够从以下位置访问 HttpContextLog method.

看来我需要注入一个IHttpContextAccessor进入习俗ILogger,但找不到如何做到这一点。这ILoggerProvider对象在启动时创建,并且CreateLogger方法不允许依赖注入。

有没有一种简单的方法来使用依赖注入ILogger?


这是一个例子

Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
    {
        loggerFactory.AddCustomLogger(serviceProvider.GetService<IHttpContextAccessor>());
        // 
    }

自定义记录器:

public class CustomLogProvider : ILoggerProvider
{

    private readonly Func<string, LogLevel, bool> _filter;
    private readonly IHttpContextAccessor _accessor;

    public CustomLogProvider(Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
    {
        _filter = filter;
        _accessor = accessor;
    }

    public ILogger CreateLogger(string categoryName)
    {
        return new CustomLogger(categoryName, _filter, _accessor);
    }

    public void Dispose()
    {
    }
}

public class CustomLogger : ILogger
{
    private string _categoryName;
    private Func<string, LogLevel, bool> _filter;
    private readonly IHttpContextAccessor _accessor;

    public CustomLogger(string categoryName, Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
    {
        _categoryName = categoryName;
        _filter = filter;
        _accessor = accessor;
    }

    public IDisposable BeginScope<TState>(TState state)
    {
        return null;
    }

    public bool IsEnabled(LogLevel logLevel)
    {
        return (_filter == null || _filter(_categoryName, logLevel));
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }

        if (formatter == null)
        {
            throw new ArgumentNullException(nameof(formatter));
        }

        var message = formatter(state, exception);

        if (string.IsNullOrEmpty(message))
        {
            return;
        }

        message = $"{ logLevel }: {message}";

        if (exception != null)
        {
            message += Environment.NewLine + Environment.NewLine + exception.ToString();
        }
        if(_accessor.HttpContext != null) // you should check HttpContext 
        {
            message += Environment.NewLine + Environment.NewLine + _accessor.HttpContext.Request.Path;
        }
        // your implementation

    }

}
public static class CustomLoggerExtensions
{
    public static ILoggerFactory AddCustomLogger(this ILoggerFactory factory, IHttpContextAccessor accessor,
                                          Func<string, LogLevel, bool> filter = null)
    {
        factory.AddProvider(new CustomLogProvider(filter, accessor));
        return factory;
    }
}

Although上述方式有效,我更愿意实施自定义IRequestLogger而不是注射HttpContextAccessor。实现如下(未测试):

public interface IRequestLogger<T>
{
    void Log(LogLevel logLevel, EventId eventId, string message); // you can change this
}

public class RequestLogger<T> : IRequestLogger<T>
{
    private readonly IHttpContextAccessor _accessor;
    private readonly ILogger _logger;
    public RequestLogger(ILogger<T> logger, IHttpContextAccessor accessor)
    {
        _accessor = accessor;
        _logger = logger;
    }

    public void Log(LogLevel logLevel, EventId eventId, string message)
    {
        Func<object, Exception, string> _messageFormatter = (object state, Exception error) =>
        {
            return state.ToString();
        };
        _logger.Log(LogLevel.Critical, 0, new FormattedLogValues(message), null, _messageFormatter);
    }
}

以及简单的用法:

public class LogType
{

}
public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
     services.AddSingleton(typeof(IRequestLogger<>), typeof(RequestLogger<>));
}

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
     loggerFactory.AddConsole(true);
     app.Run(async (context) =>
     {
         var requestLogger = context.RequestServices.GetService<IRequestLogger<LogType>>();
         requestLogger.Log(LogLevel.Critical, 11, "<message>");
         //
     });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 ILogger 访问当前 HttpContext 的相关文章

随机推荐

  • 如何在 Zend Framework 中的布局中包含页眉和页脚?

    我想让 Zend Layout 包含 header phtml 和 footer phtml 以及 layout name phtml 我怎么做 我尝试阅读Zend Layout Zend Layout Controller Plugin
  • 如何在 android 中制作具有自定义布局的 google plus 按钮?

    我想为我的 google plus 按钮创建自定义布局 有什么想法吗 我尝试调用 google plus 按钮的 OnClickEvent 这不起作用 并且尝试更改背景图像 源代码
  • Angular module().factory() 不是 concat (gulp) 之后的函数

    试图连接 丑化我的angular应用程序使用gulp在过去的几个小时里 我将整个过程简化为简单的 concat 甚至将角度文件从 concat 过程中删除到单独的
  • 如何使用 clang-format 3.9 忽略文件或目录

    我目前正在使用 travis ci 在补丁进入 github 时检查补丁 并试图找出 clang format 3 9 是否有 因为 travis ci 目前仅支持最新的 ubuntu 14 04 在扫描时忽略整个目录或文件变化 我的 tr
  • ASP.NET Web API 的不同返回类型

    我正在尝试使用 ASP NET MVC 4 Web API 通过 HTTP 编写真正的 RESTful Web 服务 我当前面临的挑战是根据我的状态代码返回不同的返回类型 实体主体 例如 对于资源 Hammer 我有一个 NET 模型类 H
  • 在 HTML 画布上为 T 恤填充颜色并相应地更改文本颜色

    我在画布上绘制了一件 T 恤 当前正在尝试当用户在上面的菜单上选择一种颜色时填充它 此外 我希望 T 恤上的文字相应地更改 例如 如果选择黑色 则 T 恤文字颜色应为白色 这可能吗 到目前为止的代码片段 T shirt color br
  • 如何使用 python Imaging 创建新的彩色图像?

    我想创建一个新图像 背景颜色 这个工作 img Image new RGB width height red 但我想定制颜色 当我将 红色 更改为 228 150 150 时 它不起作用 你有想法这样做吗 这对我有用 请注意 颜色元组不在引
  • 如何从 numpy.ndarray 中随机选择一些非零元素?

    我已经实现了一个矩阵分解模型 比如 R U V 现在我要训练和测试这个模型 为此 给定一个稀疏矩阵 R 缺失值为零 我想首先在训练中隐藏一些非零元素 并在稍后使用这些非零元素作为测试集 如何从 numpy ndarray 中随机选择一些非零
  • 标头已发送...哪里? [复制]

    这个问题在这里已经有答案了 有人知道如何在此脚本中发送标头吗 我正在使用此脚本来验证表单 因此 它导致发送标头 因此当我在实现此脚本后尝试引导用户时 它会导致正常的 警告 无法修改标头信息 标头已发送 消息 这是脚本
  • 使用 jQuery 作为依赖项而不用 RequireJS 加载 jQuery?

    考虑以下页面 当未加载 RequireJS 时 如何使用 jQuery 作为 RequireJS 模块的依赖项 我知道jQuery 暴露了自己 https github com jquery jquery blob 861a45b8fffc
  • 如何在CSS中对齐两列文本

    我在排列一些文本时遇到一些麻烦 我需要两列 一列包含数字 一列包含文本 如下所示 1 条目一2 条目二3 条目三4 条目五5 条目六 左栏是 Georgia 右栏是 Arial 字体大小略有不同 我可以为每一行设置一个容器 div 并将数字
  • Angular 2 - 如何使用配置文件

    在 ZF2 中工作时 我们使用的配置文件可能因开发人员 生产环境和登台环境而异 它非常方便 因此我想在 Angular 2 中复制它 它在 ZF2 中的工作原理 我们有一个配置文件夹 其中的配置名为 settings local php 和
  • Django 视图内的 BeautifulSoup 导致 WSGI 超时

    由于一个奇怪的原因 当我实例化一个美丽汤Django 视图中的对象 WSGI 超时 任何帮助都是值得赞赏的 因为我把头撞在墙上几个小时 却找不到这个问题的根源 风景 def index request soup BeautifulSoup
  • 注释默认“null”值

    是否可以指定默认为 null 的注释 我想要实现的是类似可选注释属性的东西 例如 public interface Foo Config value public interface Config boolean ignoreUnknown
  • 如何启用事件以便调用 Workbook_BeforeSave

    My Workbook BeforeSave保存前未调用事件 这是我的代码 Option Explicit Private Sub Workbook BeforeSave ByVal SaveAsUI As Boolean Cancel A
  • Django 在内联表单管理中获取实例

    有一个内联表单类 class ItemColorSelectForm forms ModelForm def init self args kwargs super ItemColorSelectForm self init args kw
  • 如何通过ajax(无jquery)发送multipart/form-data表单内容?

    我试图在不重新加载页面的情况下发送一些表单 并且我试图了解底层细节 因此不使用任何 JavaScript 库 var http createRequestObject function createRequestObject var obj
  • XSD 1.1 替代测试 text() 的内容

    这是我想做的
  • 与 RabbitMQ 相比,Amazon SQS 的性能较慢

    我想在我的 Web 应用程序中集成消息队列中间层 我测试了 Rabbitmq 和 Amazon SQS 但发现 Amazon SQS 速度很慢 我在 Amazon SQS 中每秒收到 80 个请求 而在 Rabbitmq 中每秒收到 200
  • 从 ILogger 访问当前 HttpContext

    在 ASP NET Core 1 0 中 我有一个自定义实现ILoggerProvider and ILogger接口 我希望能够从以下位置访问 HttpContextLog method 看来我需要注入一个IHttpContextAcce