gpt4 book ai didi

c# - 在 ILogger 自定义实现中检索身份

转载 作者:行者123 更新时间:2023-12-03 21:33:40 29 4
gpt4 key购买 nike

我正在实现一个自定义的 Microsoft.Extensions.Logging.ILogger (和 ILoggerProvider。我想检索当前的身份,但我真的不知道,因为我无法注入(inject)任何东西,而且我也不知道当前的 HttpContext。

我的方法可能是错误的......这种要求有典型的解决方案吗?

这里有几行代码:

factory.AddProvider(new MongoDBLoggerProvider(connectionString, database));

在提供者中:
public ILogger CreateLogger(string categoryName)
{
var client = new MongoClient(_connectionString);
var database = client.GetDatabase(_database);

return new MongoDBLogger(database, categoryName);
}

在记录器中:
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var now = DateTime.Now;
var entry = new LogEntry
{
Date = now,
UserId = ?????
Exception = exception,
Level = logLevel,
State = state.ToString(),
Scope = _categoryName,
EventId = eventId.Id,
EventName = eventId.Name,
FormattedState = formatter != null ? formatter(state, exception) : null
};

PushAndForget(entry, _database);
}

最佳答案

这是一个可以访问身份的工作自定义记录器的示例。它应该完成您正在寻找的内容,我刚刚在示例中重命名了一些类以提高可读性。在您设计客户记录器时,这篇 Microsoft 文章也可能是一个有用的资源https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1#create-a-custom-logger
您可以根据需要设置配置值:

public class LoggingServiceConfig
{
public LogLevel LogLevel { get; set; } = LogLevel.Information;
public int EventId { get; set; } = 0;
public ConsoleColor Color { get; set; } = ConsoleColor.Yellow;
}
Config 类有以下用途:
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
设置自定义记录器:
public class LoggingService : ILogger
{
private readonly ILogStore _logStore;
private readonly Microsoft.AspNetCore.Http.IHttpContextAccessor _httpContextAccessor;
private readonly LoggingServiceConfig _config;

public LoggingService(string categoryName, LoggingServiceConfig config,
Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor,
ILogStore logStore)
{
_config = config;
_logStore = logStore;
_httpContextAccessor = httpContextAccessor;

}

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

public bool IsEnabled(LogLevel logLevel)
{
return true; //currently log everything regardless of logLevel
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
LogEntry log = new LogEntry(); //this is your log entry
if (_httpContextAccessor.HttpContext != null)
{
var userManager = _httpContextAccessor.HttpContext.RequestServices.GetService<UserManager<AspNetUser>>(); //this is the user manager you can use to perform identity functions, you can likewise request the signInManager service as well if needed

var user = userManager.GetUserAsync(_httpContextAccessor.HttpContext.User);

if (user != null && user.Result != null)
{
//do something with user.Result as this is your identity user record
log.UserId = user.Result.UserId;
log.Username = user.Result.UserName;
}
}

if (exception != null)
{
log.ErrorMessage = exception.Message;
}

var signInManager = _httpContextAccessor.HttpContext.RequestServices.GetService<SignInManager<AspNetUser>>(); //I accessed the sign in manager in case you need it to conditionally affect how you write create your LogEntry

//add other properties you want to the log here
_logStore.Add(log); //this is where you can call your PushAndForget or any method to write to database assumed you injected it correctly or the like, you can reference the .net core respository pattern for further details on how i did my _logStore
}
}
自定义记录器有以下用途:
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
设置日志记录提供程序:
public class LoggingServiceLoggerProvider : ILoggerProvider
{
private readonly LoggingServiceConfig _config;
private readonly ConcurrentDictionary<string, LoggingService> _loggers = new ConcurrentDictionary<string, LoggingService>();
private readonly ILogStore _logStore;
private readonly Microsoft.AspNetCore.Http.IHttpContextAccessor _httpContextAccessor;
public LoggingServiceLoggerProvider(LoggingServiceConfig config,
Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor,
ILogStore logStore)
{
_config = config;
_httpContextAccessor = httpContextAccessor;
_logStore = logStore; //this is a repository for storing logs
}
public ILogger CreateLogger(string categoryName)
{
return _loggers.GetOrAdd(categoryName, name => new LoggingService(name, _config,
_httpContextAccessor,
_logStore));
}

public void Dispose()
{
_loggers.Clear();
}
}
自定义日志记录提供程序具有以下 using 语句:
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
在您的 Startup.cs 中确保配置方法具有 ILoggerFactory loggerFactory 参数并包括以下内容:
loggerFactory.AddProvider(new LoggingServiceLoggerProvider(
new LoggingServiceConfig
{
LogLevel = LogLevel.Error,
Color = ConsoleColor.Red
},
new Microsoft.AspNetCore.Http.HttpContextAccessor(),
new LogStore()));

关于c# - 在 ILogger 自定义实现中检索身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39367044/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com