首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我在使用Serilog日志时会得到Serilog SelfLog错误?

为什么我在使用Serilog日志时会得到Serilog SelfLog错误?
EN

Stack Overflow用户
提问于 2022-02-22 14:56:57
回答 1查看 1.7K关注 0票数 2

在使用Serilog SelfLog时,我有一个有趣的错误。错误是:

代码语言:javascript
复制
Application: XXX.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
   at System.IO.__Error.WinIOError(Int32, System.String)
   at System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean, Boolean, Boolean)
   at System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions, System.String, Boolean, Boolean, Boolean)
   at System.IO.StreamWriter.CreateFile(System.String, Boolean, Boolean)
   at System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32, Boolean)
   at System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding)
   at System.IO.File.InternalAppendAllText(System.String, System.String, System.Text.Encoding)
   at Serilog.Debugging.SelfLog.WriteLine(System.String, System.Object, System.Object, System.Object)
   at Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink+<OnTick>d__16.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
   at Serilog.Sinks.PeriodicBatching.PortableTimer+<OnTick>d__8.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

我不知道会发生什么。我有.Net Framework4.6.1,Serilog版本2.9.0,不能再次产生错误。

请你能帮我描述一下错误吗?我为什么会犯这个错误?你知道这个错误的解决方案吗?

我在下面使用图书馆:

  • Serilog v2.9.0
  • Serilog.Enrichers.Context v2.4.0
  • Serilog.Extensions.Logging v2.0.4
  • Serilog.Settings.AppSettings v2.2.2
  • Serilog.Sinks.Console v3.1.1
  • Serilog.Sinks.File v4.1.0
  • Serilog.Sinks.Http v5.2.1
  • Serilog.Sinks.PeriodicBatching v2.2.0
  • Serilog.Sinks.RollingFile v3.3.0
  • Microsoft.Extensions.Logging.Abstractions v1.0.0

编辑:我的应用程序在这里:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="serilog:minimum-level" value="Verbose" />
    <add key="serilog:using:Console" value="Serilog.Sinks.Console" />
    <add key="serilog:write-to:Console" />
    <add key="serilog:using:Http" value="Serilog.Sinks.Http" />
    <add key="serilog:write-to:Http.requestUri" value="http://log.XXX.com:8080/TestEngine" />
    <add key="serilog:write-to:Http.batchPostingLimit" value="1" />
    <add key="serilog:write-to:Http.batchFormatter" value="Serilog.Sinks.Http.BatchFormatters.ArrayBatchFormatter, Serilog.Sinks.Http" />
    <add key="serilog:enrich:with-property:application" value="TestEngine" />
  </appSettings>
    <startup> 
    ...

Serilog集成在这里:

代码语言:javascript
复制
var config = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .Enrich.WithMachineName()
    .Enrich.WithUserName()
    .ReadFrom.AppSettings();

if (CustomLogContext == null)
{
   CustomLogContext = new Dictionary<string, object>();
}

foreach (var logContext in CustomLogContext)
{
   config.Enrich.WithProperty(logContext.Key, logContext.Value);
}

if (!string.IsNullOrEmpty(CustomLogFileFullName))
{
   config = config.WriteTo.File($"{CustomLogFileFullName}");
}

Serilog.Log.Logger = config.CreateLogger();

Serilog.Debugging.SelfLog.Enable(msg => File.AppendAllText("internallog.log", msg, Encoding.UTF8));

ILoggerProvider loggerProvider = new SerilogLoggerProvider(Serilog.Log.Logger);

_logger = loggerProvider.CreateLogger("XXX.Logging.Serilog");

解决方案:如@RubenBartelink所述,如果使用Selflog但使用自定义日志文件,则需要承担一些风险。因为Serilog可能不会写入自定义文件,而且可能是Serilog,因此抛出IO异常。这个问题不属于Serilog。问题实际上是File.AppendAlltext操作。解决办法如下:

代码语言:javascript
复制
Serilog.Debugging.SelfLog.Enable(msg => 
{
    try
    {
        File.AppendAllText("internallog.log", msg, Encoding.UTF8);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-23 10:18:18

正如@Daniel A. White的评论中提到的那样,您正在做一件冒险的事情--尝试在“如果其他所有失败”的基础上提供的处理程序中写入文件。下面是一些例子:

  • 如果磁盘已满,而文件日志无法写入(文件接收器不一定会这样做,但如果他们希望通信失败,则通过SelfLog)
  • 如果消息字符串格式错误(Serilog日志调用永远不会抛出;这是基于wiki中的一个基本原则,即日志记录不足以阻止工作应用程序工作)

虽然Serilog调试和诊断Wiki页面当前显示了一个写入文件的示例,但这并不是合同的本质--它绝不能失败。

因此,如果您实际上希望将SelfLog发出到文件中,则需要在处理程序中添加一个try/catch并吞下异常。

我想说,当文件库是您的主要输出时,让一个文件作为备份是非常值得怀疑的。这是双倍的情况,因为您没有任何机制来确保它被修剪(假设您有一个格式错误的消息字符串的紧循环日志记录-它最终会填充您的磁盘)。

我个人已经通过将SelfLog回显到我的Console Sink (根据上面的日志记录不会抛出)来处理这个权衡,因为可以信任操作环境(比如Kubernetes)来捕获它,或者发出警报。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71223500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档