我设置了一个.Net 6来使用SeriLog登录到。在类库中,只有在修改类库中的构造函数时,我才能使用SeriLog进行日志记录。我试图避免修改类库类或方法的构造函数。
在我使用控制台应用程序的经验中,如果我在我的主Program.cs中设置了Program.cs,那么我可以在类库中的任何类中使用日志记录,而无需将记录器传递给构造函数。因此,我可以在类库中的任何地方使用Log.Information(“我的消息”),它可以工作。我正试图在我的Program.cs 6最小API项目中实现同样的目标。
我觉得从这个题目上看其他问题是可以做到的。特别是this one,其中的答案指出:
,您不必在类库中做任何事情。只有主应用程序有一个组合根(应用程序生命周期中的最早点,您可以设置对象图)。
因此,在我的API Program.CS中,我有下面的代码(我已经指出了哪些可以工作,哪些不在注释中):
//Configure SeriLog
builder.Logging.ClearProviders();
var appSettings = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var logDB =
builder.Configuration.GetSection("ConnectionStrings:Default").Value;
var sinkOpts = new MSSqlServerSinkOptions { TableName = "Logs" };
var columnOptions = new ColumnOptions();
var logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft",
Serilog.Events.LogEventLevel.Information)
.WriteTo.MSSqlServer(
connectionString: logDB,
sinkOptions: sinkOpts,
columnOptions: columnOptions,
appConfiguration: appSettings
).CreateLogger();
builder.Logging.AddSerilog(logger);
//Depency injection for Class Library method
//LoggerTestClass is a class in my Class Library project
builder.Services.AddScoped<ILoggerTestClass, LoggerTestClass>();
var app = builder.Build();
app.ConfigureTestAPI();方法"ConfigureTestAPI()“位于扩展类中,如下所示:
public static class API_Test
{
public static void ConfigureTestAPI(this WebApplication app)
//Extension method for app
{
app.MapGet("/test/", GetTest);
}
private static async Task<IResult> GetTest(int id,
ILogger<LoggerTestClass> logger, ILoggerTestClass testClass)
{
try
{
try
{
//This works
logger.LogInformation("Starting test now");
//This does NOT work
Log.Information("Using Log. directly");
testClass.Test(); //Call to class library method
logger.LogInformation("Test finished"); //Also works
return Results.Ok("OK");
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
}最后,这里是类库中带有测试方法的类:
namespace TestingLib.Testing;
public class LoggerTestClass : ILoggerTestClass
{
private Microsoft.Extensions.Logging.ILogger _logger;
public LoggerTestClass(ILogger<LoggerTestClass> logger)
{
_logger = logger;
}
public void Test()
{
try
{
//Does not work
Log.Information("Test logging from class library using Log.");
//Does not work
Log.Logger.Information("In Test Class in DLL. Trying loging with [Log.Logger.Information]");
//This works
_logger.LogInformation("In Test Class in DLL. Trying loging with [_logger.LogInformation]");
}
catch (Exception ex)
{
Log.Error("An error in class library");
}
}
}发布于 2022-02-23 21:44:20
我发现问题在于我的API Program.cs文件中缺少一行代码。我需要在设置Log.Logger记录器之后添加:“SeriLog = logger;”。
工作解决方案的代码如下。
在我的.NET6 API Program.cs文件中,我有以下内容:
var builder = WebApplication.CreateBuilder(args);
//Configure SeriLog
builder.Logging.ClearProviders();
var appSettings = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var logDB = builder.Configuration.GetSection("ConnectionStrings:Default").Value;
var sinkOpts = new MSSqlServerSinkOptions { TableName = "Logs" };
var columnOptions = new ColumnOptions
{
AdditionalColumns = new Collection<SqlColumn>
{
new SqlColumn("UserID", SqlDbType.Int),
new SqlColumn("RunTag", SqlDbType.NVarChar),
new SqlColumn("CustomType", SqlDbType.NVarChar)
}
};
var logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Information)
.WriteTo.MSSqlServer(
connectionString: logDB,
sinkOptions: sinkOpts,
columnOptions: columnOptions,
appConfiguration: appSettings
).CreateLogger();
builder.Logging.AddSerilog(logger);
//NOTE that this is not needed
//builder.Services.AddScoped<TestingLib.Testing.ILoggerTestClass, TestingLib.Testing.LoggerTestClass>();在这个文件中,我有这样一个:
Log.Logger = logger; //This was the line I was missing!
var app = builder.Build();调用类库的API Get方法现在如下所示(如果与问题中的原始方法相比,您将看到不再需要传递ILogger ):
private static async Task<IResult> GetTest(int id)
{
try
{
try
{
string runTag = "In API GetTest(id)";
string custom = "Calling from API method";
Log.Information("{Message}-{RunTag}-{CustomType}", "Message logging in API method", runTag, custom);
//Call to Class Library Method - no need to pass ILogger
LoggerTestClass testClass = new LoggerTestClass();
testClass.Test();
return Results.Ok("OK");
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}最后,这里是我的类库中的完整测试类。类库包含对SeriLog的引用:
using Serilog;
namespace TestingLib.Testing;
public class LoggerTestClass //: ILoggerTestClass
{
public LoggerTestClass()
{
//No need to pass in ILogger to class
}
public void Test()
{
try
{
string runTag = "In Class Library Method)";
string custom = "Calling class library method Test()";
Log.Information("{Message}-{RunTag}-{CustomType}", "Message logging in Class Library", runTag, custom);
}
catch (Exception ex)
{
Log.Error("An error in class library");
}
}
}我发现这个很适合我的项目。类库中的日志直接通过自定义列进入我的SQL数据库,等等。
https://stackoverflow.com/questions/71230390
复制相似问题