我设置了一个. Net 6核心最小API来使用SeriLog登录MS SQL Server。在我的类库中,只有当我修改了类库中的构造函数时,我才设法用SeriLog进行日志记录。我试图避免修改我的类库类或方法的构造函数。
在我使用控制台应用程序的经验中,如果我在我的main Program.cs中设置了SeriLog,那么我可以在我的类库中的任何类中使用日志记录,而无需将日志记录器传递给构造函数。所以,我可以用Log。信息(“我的消息”)在类库的任何地方,它的工作。我正试图在一个. Net 6最小API项目中用我的Program.cs实现同样的效果。
我觉得从这个主题的其他问题来看,应该可以做到。特别是这个答案,其中的答案是:
你不必在类库里做任何事情。只有主应用程序具有合成根(应用程序生命周期中可以设置对象图的最早点)。
因此,根据上述内容,在我的API程序中.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");
}
}
}
我发现问题是我的API程序中缺少一行代码.cs文件。我需要添加:“Log.Logger = logger;”在设置SeriLog记录器之后。
工作解决方案的代码如下。
在我的. NET6 APIProgram.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数据库,带有自定义列等。
主要内容:Logger日志方法的例子,Logger的日志方法Logger 类有多种方法来处理日志记录活动。Logger 类不允许我们实例化一个新的 Logger 实例,但它支持两种获取 Logger 对象的静态方法: 两个方法中的第一个返回应用程序实例的根记录器,它没有名称。 任何其他命名的 Logger 对象实例都是通过传递记录器的名称由第二种方法获得的。记录器的名称可以是您传递的任何字符串,通常是类或包名称,如下所述: Logger日志方法的例子 Lo
一般来说,你应该在运行时增加调试选项来调试问题;也可以把调试选项添加到 Ceph 配置文件里来调试启动问题,然后查看 /var/log/ceph (默认位置)下的日志文件。 Tip 调试输出会拖慢系统,这种延时有可能掩盖竞争条件。 日志记录是资源密集任务。如果你碰到的问题在集群的某个特定区域,只启用那个区域对应的日志功能即可。例如,你的 OSD 运行良好、元数据服务器却不行,这时应该先打开那个可疑
我想在我的应用程序中使用SLF4J+logback用于两个目的--日志和审计。 14:41:57.978[main]信息AUDIT_LOGGER-110欢迎使用main 如何确保审核消息在审核记录器下只出现一次?
问题内容: 我正在考虑将Redis用于Web应用程序日志记录目的。我用谷歌搜索,有人将日志转储到Redis队列/列表中,然后将计划的工作人员转储到磁盘中。 http://nosql.mypopescu.com/post/8652869828/another-redis-use-case- centralized-logging 我希望寻求理解,为什么不直接使用Redis持久化到磁盘?如果我分配了一
logging 模块自 2.3 版以来一直是 Python 标准库的一部分。在 PEP 282 中有对它的简洁描述。除了 基础日志教程 之外,这些文档是非常难以阅读的。 日志记录一般有两个目的: 诊断日志 记录与应用程序操作相关的日志。例如,当用户遇到程序报错时, 可通过搜索诊断日志以获得上下文信息。 审计日志 为商业分析而记录的日志。从审计日志中,可提取用户的交易信息, 并结合其他用户资料构成用
我正在使用Python日志模块,并希望禁用由我导入的第三方模块打印的日志消息。例如,我使用的是如下所示: 当我执行logger.debug时,它会输出我的调试消息(“my Message!”),但它也会从我导入的任何模块中输出调试消息(如请求和许多其他东西)。 我只想看到我感兴趣的模块的日志消息。有没有可能让日志模块做到这一点?