LoggingSession.SaveToFileAsync有时会创建以.etl.tmp结尾的文件

时间:2015-03-05 21:53:01

标签: c# logging winrt-xaml win-universal-app

我有一个通用的Windows / WindowsPhone 8.1应用程序,我使用LoggingSession在我的应用程序运行时记录消息。

当发生未处理的异常时,我记录异常然后等待对LoggingSession.SaveToFileAsync的调用以将日志转储到文件中。下次我的应用程序启动时,我上传日志文件并在我的最后收到它。

我看到的问题是,有时我的日志文件以.etl.tmp结尾(通常文件大小为50 - 100 Kb),当我尝试打开它们时(使用跟踪器或Windows事件查看器)我没有看到任何日志。其他时候我打开通常大约200Kb的.etl.tmp文件,我看到一些日志条目。而有时候日志文件(通常在20Kb以下)正确地以.etl扩展名(没有.tmp)结束,并且所有记录的消息都在那里。

1)为什么LoggingSession.SaveToFileAsync有时会生成扩展名为.etl.tmp的文件?

2)有关如何解决此问题的任何建议?我需要捕获所有日志(甚至是未处理的异常),然后再将它们保存到文件中,以便我在应用程序的unhadnled异常事件处理程序中调用LoggingSession.SaveToFileAsync。我还需要我的日志记录解决方案才能提高性能,而不是太慢地减慢我的应用程序。

由于


这里是精简的示例代码:

public sealed partial class App : Application
{
    .
    .
    .

    public static ETWLogger Logger;
    public App()
    {
        InitializeComponent();

        Logger = new ETWLogger();

        Suspending += OnSuspending;
        UnhandledException += OnUnhandledExceptionAsync;
    }

    private async void OnUnhandledExceptionAsync(object sender, UnhandledExceptionEventArgs args)
    {
        await Logger.SaveToFileAsync();
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        // Check to see if there are files in the Log folder. If so
        // then upload them and then delete all files in the Log folder.
    }

    .
    .
    .
}

public class ETWLogger
{
    private LoggingSession _session;
    private LoggingChannel _channel;
    private StorageFolder _logFolder;
    .
    .
    .

    public ETWLogger()
    {
        .
        .
        .
        _session = new LoggingSession("DefaultSession");
        _channel = new LoggingChannel("DefaultChannel");
        _session.AddLoggingChannel(_channel);

        _logFolder = StorageHelper.CreateSubFolder(ApplicationData.Current.LocalFolder, "LogFiles", CreationCollisionOption.OpenIfExists);
        .
        .
        .
    }

    public async Task SaveToFileAsync()
    {
        if (_session == null) return;

        var fileName = DateTime.Now.ToString("yyyyMMdd-HHmmssTzz", CultureInfo.InvariantCulture) + ".etl";
        await _session.SaveToFileAsync(_logUploadFolder, fileName);
    }

    .
    .
    .
}

1 个答案:

答案 0 :(得分:3)

我非常清楚这里发生了什么。您描述了Microsoft使用的常用技术,它可以防止文件损坏和数据丢失。它不是创建您要求的foo.etl文件,而是 first 创建具有不同名称的文件。喜欢foo.etl.tmp。只有在成功写入文件时,或者换句话说,异步方法实际完成时,它才会将文件从foo.etl.tmp重命名为foo.etl。

你现在有了一个很好的保证,你总是得到一个完整的写好"好"文件。没有腐败。如果您有一个具有相同名称的先前文件,那么它不会被损坏的半写文件替换。没有数据丢失。

  

当发生未处理的异常时,我记录异常,然后等待呼叫

"未处理的例外"是问题。只有当异常不足以阻止异步/等待管道继续工作时,才能完全写入您的日志文件。换句话说,你只能得到温和的"异常信息。坏的产生了半写的foo.etl.tmp文件,应用程序在完成之前就已经完成了。

如果您想了解“坏”"那么您无法在此使用await。那些。 SaveToFileAsync()调用必须同步完成。