私はASP.NET Coreを勉強中です。ファイルシステムでのロギングを成功させましたが、データベースソリューションでロギング機能を実装する方法はどうですか?どのように私の 'LoggerDatabaseProvider
'にEFのコンテキストを渡すには、まだそれらの2つのデカップル?以下のコードは、いくつかの先行質問をクリアする必要があります。ASP.NET Core ILoggerProvider for database
Startup.cs:ここ
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddEntityFramework()
.AddEntityFrameworkSqlServer()
.AddDbContext<WorldContext>();
services.AddTransient<WorldContextSeedData>();
services.AddScoped<IWorldRepository, WorldRepository>();
//this one adds service with Dependency Injection that calls 'MyLogger' constructor with two parameters, instead the default one parametereless constructor.
services.AddScoped<ILogger, LoggerFileProvider.Logger>(provider => new LoggerFileProvider.Logger("CustomErrors", Startup.Configuration["Data:LogFilePath"]));
//services.AddScoped<ILogger, LoggerDatabaseProvider.Logger>(provider => new LoggerDatabaseProvider.Logger("CustomErrors"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, WorldContextSeedData seeder)
{
string basePath = Startup.Configuration["Data:LogFilePath"];
loggerFactory.AddProvider(new LoggerFileProvider(basePath));
loggerFactory.AddProvider(new LoggerDatabaseProvider());
app.UseStaticFiles();
app.UseMvc(config =>
{
config.MapRoute(
name: "Default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "App", action = "index" }
);
});
seeder.EnsureSeedData();
}
は、テキストファイルと私の実装に成功ロガーです:非常によく似た実装について
public class LoggerFileProvider : ILoggerProvider
{
private readonly string _logFilePath;
public LoggerFileProvider(string logFilePath)
{
_logFilePath = logFilePath;
}
public ILogger CreateLogger(string categoryName)
{
return new Logger(categoryName, _logFilePath);
}
public void Dispose()
{
}
public class Logger : ILogger
{
private readonly string _categoryName;
private readonly string _path;
public Logger(string categoryName, string logFilePath)
{
_path = logFilePath;
_categoryName = categoryName;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
try
{
RecordMsg(logLevel, eventId, state, exception, formatter);
}
catch (Exception ex)
{
//this is being used in case of error 'the process cannot access the file because it is being used by another process', could not find a better way to resolve the issue
RecordMsg(logLevel, eventId, state, exception, formatter);
}
}
private void RecordMsg<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
string msg = $"{logLevel} :: {_categoryName} :: {formatter(state, exception)} :: username :: {DateTime.Now}";
using (var writer = File.AppendText(_path))
{
writer.WriteLine(msg);
}
}
public IDisposable BeginScope<TState>(TState state)
{
return new NoopDisposable();
}
private class NoopDisposable : IDisposable
{
public void Dispose()
{
}
}
}
}
しかし、どのように、しかし、データベースソリューション?私のWorldContext
は、EFによってデータベースとの通信に利用されていますが、もしそれが簡単なら私のリポジトリを利用することができます。コンテキストとリポジトリのデカップルを「LoggerDatabaseProvider
」から取り除きたいので、他のプロジェクトで利用することができます。
そのほぼすべてのロギングフレームワークDBのログプロバイダーを使用しないのはなぜありますか? – Brad