Serilog MSSQL Sink 不将日志写入数据库
Serilog MSSQL Sink doesn't write logs to database
我已经创建了一个 .Net class 库 (4.6.2) 并创建了 serilog 实现,它被其他接口(例如控制台应用程序)调用。现在,当我使用文件接收器类型时,日志会写入文件,但使用 MSSQL 接收器时,它不会这样做。
日志 table 正在使用 autoCreateTable 选项
提供的列选项创建
ILogger logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(connectionString,
tableName,
autoCreateSqlTable: autoCreateSqlTable,
restrictedToMinimumLevel: LogEventLevel.Verbose,
columnOptions: GetSQLSinkColumnOptions(),
batchPostingLimit: batchPostingLimit)
.CreateLogger();
我还启用了 serilog 的自记录,但没有显示异常。没有找到任何有用的解决方案。
然而,日志 table 正在生成。我已经检查了用户的权限,它也具有正确的权限。
下面是代码的快照。
public static class GenericLogger
{
private static ILogger _usageLogger;
private static ILogger _errorLogger;
static GenericLogger()
{
var logTypes = LogConfigurationHelper.GetLogTypes();
if (logTypes != null && logTypes.Count > 0)
{
foreach (var logType in logTypes)
{
ConfigureLogger(logType.Id); // Intitalizes logs based on
//configuration.
}
}
Serilog.Debugging.SelfLog.Enable(msg =>
{
Debug.Print(msg);
Debugger.Break();
});
}
///The write log function
///
public static void WriteError(LogDetail infoToLog)
{
if (infoToLog.Exception != null)
{
infoToLog.Message = GetMessageFromException(infoToLog.Exception);
}
_errorLogger.Write(LogEventLevel.Information,
"{Timestamp}{Product}{Layer}{Location}{Message}" +
"{Hostname}{UserId}{UserName}{Exception}{ElapsedMilliseconds}" +
"{CorrelationId}{CustomException}{AdditionalInfo}",
infoToLog.TimeStamp, infoToLog.Product, infoToLog.Layer, infoToLog.Location, infoToLog.Message,
infoToLog.Hostname, infoToLog.UserId, infoToLog.UserName, infoToLog.Exception?.ToCustomString(),
infoToLog.ElapsedMilliseconds, infoToLog.CorrelationId, infoToLog.CustomException,
infoToLog.AdditionalInfo);
// To add ((IDisposable) _errrorLog).Dispose();
}
}
以下是一些可以帮助您解决问题的想法:
您是否仅使用 Verbose
或 Debug
事件进行测试?这可能是原因。您没有为 Serilog 指定全局最低级别(您只为接收器指定了最低级别,它充当过滤器),以及 default minimum is Information
,这意味着 Verbose
和 Debug
被忽略...为 Serilog 指定全局 MinimumLevel
:
ILogger logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.MSSqlServer(connectionString,
tableName,
autoCreateSqlTable: autoCreateSqlTable,
restrictedToMinimumLevel: LogEventLevel.Verbose,
columnOptions: GetSQLSinkColumnOptions(),
batchPostingLimit: batchPostingLimit)
.CreateLogger();
你要处理你的记录器吗? Serilog.Sinks.MSSqlServer
是 "periodic batching sink",因此您需要确保在最后处理记录器以强制其将日志刷新到数据库。参见 Lifecycle of Loggers。
((IDisposable) logger).Dispose();
即使您为 batchPostingLimit
、it waits 5
seconds by default before sending the logs to the database 使用 1
。如果您的应用在此期间之前关闭并且您没有处理记录器,则消息将丢失。
为了排除故障,使用AuditTo
而不是WriteTo
(并删除不适用于审计的batchPostingLimit
)。 WriteTo
是安全的,会吃掉任何异常,而 AuditTo
会让异常冒泡。
ILogger logger = new LoggerConfiguration()
.AuditTo.MSSqlServer(
connectionString,
tableName,
restrictedToMinimumLevel: LogEventLevel.Verbose,
autoCreateSqlTable: true)
.CreateLogger();
当然,一旦你弄清楚哪里出了问题,就回到WriteTo
。
在我的例子中,这是因为我的数据库用户没有必要的权限来登录数据库 schema.table。
我最终做了如下事情:
/* CREATE A NEW ROLE */
CREATE ROLE db_logger
/* GRANT SELECT, INSERT TO THE ROLE */
GRANT SELECT, INSERT ON [Logging].[Logs] TO db_logger --Allows SeriLog to insert
奇怪的是 "WriteTo" 需要 SELECT 权限,但 "AuditTo" 不需要。这两种方法都需要 INSERT 权限。
我已经创建了一个 .Net class 库 (4.6.2) 并创建了 serilog 实现,它被其他接口(例如控制台应用程序)调用。现在,当我使用文件接收器类型时,日志会写入文件,但使用 MSSQL 接收器时,它不会这样做。 日志 table 正在使用 autoCreateTable 选项
提供的列选项创建ILogger logger = new LoggerConfiguration()
.WriteTo.MSSqlServer(connectionString,
tableName,
autoCreateSqlTable: autoCreateSqlTable,
restrictedToMinimumLevel: LogEventLevel.Verbose,
columnOptions: GetSQLSinkColumnOptions(),
batchPostingLimit: batchPostingLimit)
.CreateLogger();
我还启用了 serilog 的自记录,但没有显示异常。没有找到任何有用的解决方案。
然而,日志 table 正在生成。我已经检查了用户的权限,它也具有正确的权限。
下面是代码的快照。
public static class GenericLogger
{
private static ILogger _usageLogger;
private static ILogger _errorLogger;
static GenericLogger()
{
var logTypes = LogConfigurationHelper.GetLogTypes();
if (logTypes != null && logTypes.Count > 0)
{
foreach (var logType in logTypes)
{
ConfigureLogger(logType.Id); // Intitalizes logs based on
//configuration.
}
}
Serilog.Debugging.SelfLog.Enable(msg =>
{
Debug.Print(msg);
Debugger.Break();
});
}
///The write log function
///
public static void WriteError(LogDetail infoToLog)
{
if (infoToLog.Exception != null)
{
infoToLog.Message = GetMessageFromException(infoToLog.Exception);
}
_errorLogger.Write(LogEventLevel.Information,
"{Timestamp}{Product}{Layer}{Location}{Message}" +
"{Hostname}{UserId}{UserName}{Exception}{ElapsedMilliseconds}" +
"{CorrelationId}{CustomException}{AdditionalInfo}",
infoToLog.TimeStamp, infoToLog.Product, infoToLog.Layer, infoToLog.Location, infoToLog.Message,
infoToLog.Hostname, infoToLog.UserId, infoToLog.UserName, infoToLog.Exception?.ToCustomString(),
infoToLog.ElapsedMilliseconds, infoToLog.CorrelationId, infoToLog.CustomException,
infoToLog.AdditionalInfo);
// To add ((IDisposable) _errrorLog).Dispose();
}
}
以下是一些可以帮助您解决问题的想法:
您是否仅使用 Verbose
或 Debug
事件进行测试?这可能是原因。您没有为 Serilog 指定全局最低级别(您只为接收器指定了最低级别,它充当过滤器),以及 default minimum is Information
,这意味着 Verbose
和 Debug
被忽略...为 Serilog 指定全局 MinimumLevel
:
ILogger logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.MSSqlServer(connectionString,
tableName,
autoCreateSqlTable: autoCreateSqlTable,
restrictedToMinimumLevel: LogEventLevel.Verbose,
columnOptions: GetSQLSinkColumnOptions(),
batchPostingLimit: batchPostingLimit)
.CreateLogger();
你要处理你的记录器吗? Serilog.Sinks.MSSqlServer
是 "periodic batching sink",因此您需要确保在最后处理记录器以强制其将日志刷新到数据库。参见 Lifecycle of Loggers。
((IDisposable) logger).Dispose();
即使您为 batchPostingLimit
、it waits 5
seconds by default before sending the logs to the database 使用 1
。如果您的应用在此期间之前关闭并且您没有处理记录器,则消息将丢失。
为了排除故障,使用AuditTo
而不是WriteTo
(并删除不适用于审计的batchPostingLimit
)。 WriteTo
是安全的,会吃掉任何异常,而 AuditTo
会让异常冒泡。
ILogger logger = new LoggerConfiguration()
.AuditTo.MSSqlServer(
connectionString,
tableName,
restrictedToMinimumLevel: LogEventLevel.Verbose,
autoCreateSqlTable: true)
.CreateLogger();
当然,一旦你弄清楚哪里出了问题,就回到WriteTo
。
在我的例子中,这是因为我的数据库用户没有必要的权限来登录数据库 schema.table。
我最终做了如下事情:
/* CREATE A NEW ROLE */
CREATE ROLE db_logger
/* GRANT SELECT, INSERT TO THE ROLE */
GRANT SELECT, INSERT ON [Logging].[Logs] TO db_logger --Allows SeriLog to insert
奇怪的是 "WriteTo" 需要 SELECT 权限,但 "AuditTo" 不需要。这两种方法都需要 INSERT 权限。