Serilog Seq Sink并不总是捕捉事件

时间:2015-12-09 21:44:58

标签: azure asp.net-core serilog getseq

我在Azure实例(Windows Server 2012 R2 Datacenter)上运行Seq,并从本地工作站上运行的控制台应用程序使用Serilog进行日志记录。我配置了3个接收器 - 文件,控制台和Seq。我也在运行dnxcore50(以防万一你认为我的设置不够笨拙)。我的所有事件都在100%的时间内显示在控制台和文件中。 Seq仅捕获大约每5次或更多次运行的事件,即它将捕获运行的所有事件或不捕获它们。我使用免费的单用户许可来评估Seq,我没有发现任何暗示会有任何限制导致此行为。

我已经在记录器上设置了SelfLog.Out,但除了我添加的测试行之外,它没有任何记录,以确保自我记录至少可以写入指定的文件。

public abstract class SerilogBaseLogger<T> : SerilogTarget
{
    protected SerilogBaseLogger(SerilogOptions options, string loggerType)
    {
        LoggerConfiguration = new LoggerConfiguration();
        Options = options;
        LevelSwitch.MinimumLevel = options.LogLevel.ToSerilogLevel();

        var file = File.CreateText(Path.Combine(options.LogFilePath, string.Format("SelfLog - {0}.txt", loggerType)));
        file.AutoFlush = true;
        SelfLog.Out = file;
        SelfLog.WriteLine("Testing self log.");
    }

    // ... snip ....
}

public class SerilogSeqTarget<T> : SerilogBaseLogger<T>
{
    public string Server => Options.Seq.Server;

    public SerilogSeqTarget(SerilogOptions options)
        : base(options, string.Format("SerilogSeqTarget[{0}]", typeof(T)))
    {
        LoggerConfiguration
            .WriteTo
            .Seq(Server);

        InitializeLogger();
    }

    public override string ToString()
    {
        return string.Format("SerilogSeqTarget<{0}>", typeof(T).Name);
    }
}

public class SerilogLoggerFactory<TType> : LoggerFactory<SerilogTarget>
{
    // .... snip ....

    public override IMyLoggerInterface GetLogger()
    {
        var myLogger = new SerilogDefaultLogger()
            .AddTarget(SerilogTargetFactory<TType>.GetFileTarget(Options))
            .AddTarget(SerilogTargetFactory<TType>.GetConsoleTarget(Options))
            .AddTarget(SerilogTargetFactory<TType>.GetSeqTarget(Options));

        myLogger.Info("Logger initialized with {@options} and targets: {targets}", Options, ((SerilogDefaultLogger)myLogger).Targets);

        return myLogger;
    }
}

public class SerilogTargetFactory<TType>
{
    // ... snip ...

    public static SerilogTarget GetSeqTarget(SerilogOptions options)
    {
        return !string.IsNullOrEmpty(options.Seq.Server)
                   ? new SerilogSeqTarget<TType>(options)
                   : null;
    }
}

有什么建议吗?这只是处于最前沿的副作用,与预发布的一切一起工作(虽然在这种情况下我会期望事情有些失败)?

1 个答案:

答案 0 :(得分:3)

在定位dnxcore50 / CoreCLR时,Serilog无法挂钩AppDomain关闭,以确保始终刷新所有缓冲的消息。 (AppDomain在该个人资料中不存在: - )

有几种选择:

  1. 在关机时配置记录器(尤其是Seq one):

    (logger as IDisposable)?. Dispose();

  2. 使用静态Log类并在关闭时调用其CloseAndFlush()方法:

    Log.CloseAndFlush();

  3. 后者 - 使用静态Log类而不是各种单独的ILogger实例 - 可能是最快捷,最容易实现的,但它与处理记录器的效果完全相同任何一种方法都应该这样做。